2013年11月29日金曜日

◆取得したオブジェクトにオートナンバーキー列を付与する

http://social.technet.microsoft.com/Forums/ja-JP/ccf8e6fc-0220-4a0c-9fa5-16a1a680973a?forum=powershellja

こんな方法でもできそう。

001
002

$script:n = 0
ps | sort id | ft @{n="number";e={($script:n++)}},id,name -auto

スクリプト変数を使うとSelectやFormat出力の時に直接カウントアップできる。

また、カウントアップだけだと出力されないので括弧で囲むと良いようだ。
($script:n++)

これは
$script:n++;$script:nと同じ結果になる。

2013年11月27日水曜日

◆タスクスケジューラのジョブを纏めてエクスポートする

サーバーにしかけてあるジョブが増えてきたのでバックアップしておこうかと思ったのだが、GUIでは1つずつしかエクスポートできなさそう。

3.0が使えればコマンドレットが用意されているようだが、3.0を追加できないサーバーなので他の方法を探してみた。

「schtasks」か「Win32_ScheduledJob」あたりを使うのかなっと思って探しているとCOMを使ったそのものずはりのサンプルがあったので基本的にそのまま使わせていただいた。
Powershell, and exporting Windows Scheduled Tasks – TheGeekery

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015

$outPath = "f:\desktop\wk"
$outFileName = "{0}.xml"

$sch = New-Object -ComObject("Schedule.Service")
$sch.Connect("localhost")
$tasks = $sch.GetFolder("\").GetTasks(0
)
 

$outfile_temp = Join-Path $outPath $outFileName
 
$tasks | %{
$xml = $_.Xml
$task_name = $_.Name
$outfile = $outfile_temp -f 
$task_name
$xml
 | Out-File $outfile
}

image

2013年11月19日火曜日

◆ISEを別のユーザーとして実行する

Launching PowerShell as Different User - Power Tips - PowerShell.com – PowerShell Scripts, Tips, Forums, and Resources

 

PowerShellは「Shift」を押しながら右クリックすると「別のユーザーとして実行」メニューが表示されるので、それを選べばよい。
image

しかし、ISEは同じ方法では別ユーザーとして起動できない。

そんなときは、別のユーザーとして起動したPoserShellのコマンドラインで「ISE」と打ち込めばPowerShellを起動したユーザーでISEも起動される。

2013年10月25日金曜日

◆C#からPowerShellを使う

昔どこかで見かけたことはあるが、あまり使い道は無いのかと思っていた。

ふと思い立って、一応使い方を確認しておくことにした。

まずは、DLL(System.Management.Automation.dll)が必要なようなので参照を追加する。私のWindows8環境では以下の場所にあった。

"C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\3.0\System.Management.Automation.dll"

Get-Processを使うにはこんな感じでOKだった。

namespace PowerShellTest

{

    class Program

    {

        static void Main(string[] args)

        {

            PowerShell ps = PowerShell.Create();

            ps.AddCommand("Get-Process");

            var results = ps.Invoke();

            results.ToList().ForEach(

                p => Console.WriteLine(p.Properties["ProcessName"].Value));

           

        }

    }

}

image

Get-ProcessからPSObjectが返ってきてしまうので、プロパティが文字列参照になってしまうあたりが今1つな感じ・・・。

2013年10月23日水曜日

PowerShell ISE 新しいタブと新しいページの違い

いままで全く気付いていなかったのだが、ISEでは複数の「タブ」を扱える。

ここで、「タブ」というのは以下

image

をクリックして追加される以下では無い。

image

「ファイル」メニューの以下を選択すると
image

以下のように追加される。

image

今まで「タブ」だと思っていたのは「ページ」とでも呼ぶのだろうか・・・。

どうやらこの「タブ」が1つのセッションとして扱われているらしい。

なので、「タブ」間では変数等が共有されない。

 

これまで、最終確認とかでISE自体を開きなおしていたのだが、実は新しいタブを追加すればよいだけだったのね・・・。(お恥ずかしい)

「Ctrl + N」 新しいページを開く
「Ctrl + T」 新しいタブを開く

2013年10月2日水曜日

◆about系のヘルプはまだ?

最近ちょっとPowerShellから離れていたので良く判らないが、about系のヘルプはまだ日本語化されていないのだろうか。

Update-Helpでも入ってこないっポイ?

Onlineでも参照できない?

image

自分的には英語でもそんなに苦ではないのだが、人に教えるときに「ほら、こうやってヘルプを見ると簡単でしょ?」と言えないのがちょっと・・・。
特にコマンドレットのヘルプなら英語でも良いけど、about系は説明がメインだから余計厳しい。

クライアントではそれほど3.0のメリットも感じないので、7で2.0を使うのが幸せなのだろうか。

8はちょっと失敗感ただよっているしなぁ・・・。

◆昇格した管理者権限で実行されているか確認する

スクリプトが「昇格した管理者権限」を要求するような場合、最初にチェックしたほうが親切かもしれない。

以下にそのサンプルがあったのでメモしておく。
Testing Administrator Privileges - Power Tips - PowerShell.com – PowerShell Scripts, Tips, Forums, and Resources

image

非常に短いコーディングでチェックできるので便利そう。

若干トリッキーなので仕掛けを解析しておくと、
まずネイティブなコマンドの「whoami /groups」を使って現在のユーザーが所属するグループを表示すると以下のような感じで返ってくる。
image

ここで、「昇格した管理者権限」に属する場合は以下のグループが存在するようだ。

image

これは、対話ログオンすると「INTERACTIVE」グループに動的に所属するのと同じパターンかな。

あとは「match」演算子を使って「昇格した管理者権限」の「SID」が含まれるか判定している。

配列に「match」演算子を使うとマッチした要素だけが抽出される。

PS>"ma","mb","mc" -match "b"
mb

あとはマッチしなければ何も返ってこない(null)しマッチすればマッチした文字列が返ってくるのを、「bool」にキャストしている。

2013年9月26日木曜日

◆Invoke-WebRequestサンプル2

PowerShell: ◆Invoke-WebRequestサンプル

 

Invoke-WebRequestで取ってきた後、ParsedHtmlプロパティを使うと自分でHTML解析せずに色々と使えそう。

私自身Web系のプログラミングはやらないので詳しくは判らないが、さしあたってタグとその順番を指定して切り出すには以下のような感じ。

001
002
003
004
005
006
007
008
009

$URL = "http://weather.yahoo.co.jp/weather/jp/3/3310.html"
$OutputFile = "$env:temp\weather.html"

$data = Invoke-WebRequest -Uri $URL
 
@(
$data.ParsedHtml.getElementsByTagName("h2"))[0].OuterHTML ,
@($data.ParsedHtml.getElementsByTagName("table"))[0].OuterHTML |
Set-Content -Path $OutputFile

& $OutputFile

<切り出し前>

image

<切り出し後>

image

2013年8月22日木曜日

◆Resolve-Path

昔からあるし使い方も難しくない。
相対パスを絶対パスにしてくれたり、ワイルドカードを展開してくれたりする。

image

 

Officeのインストールパスを取得するサンプルが載っていたのでメモしておく。
バージョンが違ったり、64ビットだったりしても問題なく取得できる。
(あくまでもデフォルトパスにインストールした場合だと思うが)

image

2013年7月26日金曜日

◆スクリーンセーバーの情報を取得する

Finding Screen Saver Information - Power Tips - PowerShell.com – PowerShell Scripts, Tips, Forums, and Resources

001
002
003
004
005
006
007

gwmi win32_desktop | ?{$_.name -eq "NT AUTHORITY\SYSTEM"}

gwmi win32_desktop -filter "name='NT AUTHORITY\\SYSTEM'"

gwmi win32_desktop -Filter "name='$env:userdomain\\$env:username'"

[wmi]"win32_desktop='NT AUTHORITY\SYSTEM'"

基本的にはどの行も同じ結果が表示される。
image

「¥」の扱いにちょっと注意が必要。
WMIの世界ではエスケープが必要で、PowerShellの世界ではエスケープが不要って事かな。

2013年7月10日水曜日

◆Usingラベルのサンプル

別セッションに変数を渡すサンプル。(V3からの機能だそうです)

001
002
003
004
005

$class = 'Win32_LogicalDisk'
$ComputerName = 'hogePC.sample.co.jp'

Invoke-Command -ScriptBlock
 { 
 
Get-WmiObject -Class $using:class } -ComputerName $ComputerName

バックグラウンドジョブを使うときなんかに重宝するかも。

 

参考までにV2でやるにはこんな感じでパラメータ渡ししてあげるらしいです。

001
002
003
004
005
006

$class = 'Win32_LogicalDisk'
$ComputerName = 'vista3.ad.ics.co.jp'
Invoke-Command -ScriptBlock
 { 
 
param($class
) 
 
Get-WmiObject -Class $class
 
} 
-ComputerName $ComputerName -ArgumentList $class

 

参考
Using "Using:" On Remote PowerShell Sessions - Power Tips - PowerShell.com – PowerShell Scripts, Tips, Forums, and Resources

2013年7月4日木曜日

◆Invoke-WebRequestサンプル

以前もちょっと取り上げたV3で追加になったコマンド。

実際に使う機会があったのでサンプルとして記載しておく。

かつてノーツで作られていた議事録をSharePointに移行したリストがあったのだが、移行ツールに不具合があるのか稀に添付文書のリンク切れが発生している。
そこで、リンク切れをチェックしてリストアップするスクリプトを書いた。

リスト形式(一覧)では添付の有無しか判らず、そのパスは明細を読む必要がある。
そこで、リストを一旦CSVに落として添付があるものについて「Invoke-WebRequest」で読み込んでみる。
そこから「href」に「Attachment」(すなわち添付)の文字があるものを抽出して存在チェックする。
とりあえず存在チェック自体も「Invoke-WebRequest」で読んでみてエラーになるかどうかで判断している。(これについては他にもっと良い方法が有るのかも・・・)

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015

$url = "http://server/sites/hoge/MEETING/Lists/List/DispForm.aspx?ID={0}"
$csv = Import-Csv "F:\Desktop\打ち合わせ報告書.csv" -Encoding default
$csv | %
{
 
if($_.添付 -eq 1
){
   
$_.整理番号 | Tee-Object -Variable number
    $urlString = $url -f $_.
ID
   
$web = Invoke-WebRequest -uri $urlString -UseDefaultCredentials
 
   
$web.links | ?{$_.href -like "*attachment*"} | %
{
     
$_.href |  %
{
       
Invoke-WebRequest -uri $_ -UseDefaultCredentials | Out-Null
        if($? -eq $false){$number >> "F:\Desktop\整理番号.txt"}
      }
    }
  }
}
<!-

2013年6月25日火曜日

◆CSVファイルのハッシュテーブル化

昔、ほぼ同じことを以下でやっているが忘れていたのでメモ。
PowerShell: ◆カスタマイズした条件を使ってグルーピングする(Group-Object)

 

以下のようなCSVファイルを読み込んで、ハッシュテーブル化すると各項目をダイレクトに参照出来て便利だよってお話。
image

001
002
003
004
005

$content = Import-Csv "F:\Desktop\Servers.csv"
$hash = $content |
 
 
Group-Object -AsHashTable -AsString -Property Name
$hash["sv4"].OS
$hash.sv3.SP

image

2013年6月24日月曜日

◆別の資格情報で管理者として実行する2

タスクスケジューラに登録されたタスクの一覧を表示するスクリプトがあったので試してみた。

それ自体は特に問題はない。

複数サーバーのタスクをクライアントから覗けるとベターかと思うのだが、昇格した管理者権限が要求される。

以前PowerShell: ◆別の資格情報で管理者として実行するでちょっとやったのだが、もう一度ちゃんと調べてみたところPowerShellをネストして呼び出すというのが主流のようだ。(別の資格情報でPowerShellを起動し、その中でまたPowerShellを起動し昇格してコマンド実行)

コマンドを単独で実行するサンプルはあったのだが、スクリプトブロックを実行するサンプルが見当たらなかったため試行錯誤で作ってみた。

文字列の扱いが面倒で、都度エラーに対処しながら書いたのでスマートな書き方では無いかもしれない。(前回同様パスワードは予め保存しているものを使っている)

$password = ConvertTo-SecureString (gc f:\myPass)

$cred =

  New-Object System.Management.Automation.PsCredential "ad\adm",$password

 

 

$cmd = {

    $computers = 'hoge-sv','v064'  #対象サーバー

    $service = New-Object -ComObject Schedule.Service

    $computers | %{

    $service.Connect($_)

    $folder = $service.GetFolder('\')

    $tasks = $folder.GetTasks(1)

    Write-Host 'ComputerName = ' $_ -ForegroundColor Yellow

    $tasks | ft Name, Enabled, LastRunTime, LastTaskResult, NextRunTime -auto

  }

}

 

$sc =

  "-command &{Start-Process PowerShell -ArgumentList {-noexit -command $cmd} -Verb runas }"

Start-Process -Credential $cred  -FilePath PowerShell.exe -ArgumentList $sc 

image

2013年6月3日月曜日

◆所属するドメインユーザーグループを表示する

>([wmi]"Win32_userAccount.Domain='ad',Name='hogeUser'").GetRelated('Win32_Group')

image

ローカルマシン上のグループにも属している場合は、ローカルグループも表示される。

2013年5月21日火曜日

◆PowerGUIのメニュー(ツールバー)が消えた時の回復方法

何のはずみか、PowerGUIのメニューとツールバーが消えてしまった。

image

普通ならばどこかのコンテキストメニュで回復できそうなものだが、何も見当たらない・・・。

なんともはや・・・。

原因はさておき、以下にあるファイルにレイアウトが設定されるようなので、これを削除すると良さそうだ。

C:\Users\ユーザー名\AppData\Roaming\Quest Software\PowerGUI\BarManagerLayoutFile.xml

image

ふぅ~。

2013年5月1日水曜日

◆SharePoint2010にPowerShell3.0を入れてはいけない

SharePoint2010の入ったサーバーにPowerShell3.0を入れた。

するとこれまで動いていたスクリプトが動かなくなってしまった。
「SharePoint は、バージョン 4.0.30319.296 の Microsoft .Net Runtime ではサポートされません」
image

まさか下位互換が無いなんてことは無いよねっと思い調べていると、そのまさかである。

Windows Server 2012 では SharePoint Server 2010 がサポートされない
image

つくづくSharePointという製品はいけてない。
3つも4つも前のバージョンならいざしらず、一つ前のバージョンが入らないって。

しかも、今回はWindowsServer2012に入れたわけでは無く、2008R2にSharePoint3.0を入れただけ。

ダメならダメでSharePointのインストーラでチェックしなきゃ。

SharePoint、信じがたい程使いづらいGUI、超低品質、バージョン間の互換性は皆無。

何十年もの間、いろんな製品を見たが、これは酷すぎ。(SharePontとコラボしているProjectServerも酷いが)

SharePoint2013などは互換性が無いわけだから名前を変えるべきでは無いのかなぁ・・・。

◆Update-Help

いつの間にか、Ver3用の日本語ヘルプが提供されているようだ。

オンラインで参照すると2012年8月更新となっているけど?。
image

英語でもそんなに困ることは無いがやはり日本語の方が助かる。

単純にUpdate-Helpと打つと更新してくれるようだ。

 

ついでに3.0のダウンロード先をリンクしておく。

Download WMF 3.0 from Official Microsoft Download Center

2013年4月9日火曜日

◆SharePointのサイトテーマを設定する

ここのところSharePoint2013をセットアップしていたのだが、結局その使用を断念することになった。

SharePoint2013ではデフォルトの認証方式が「クレームベース」に変更されている。(クレームベース自体はこれまでもあったのだが、デフォルトでは無かったのであまり使われていなかったのではなかろうか)

で、「クレームベース」とやら、具体的に何が違うのかは良く判らないのだが、とにかく色々と非互換がありそう。

さしあたって「InfoPath」がさっぱり動かない。
軒並みコーディング変更まで必要になりそうな気配。

ならばと、「クレームベース」を止めてこれまでのデフォルト(Classicだったかな)に戻すと、「WebApps」が動かなくなると脅される。

ん~、相変わらずSharePointはカオスだ。

結局ざっと眺めた感じでは2013に魅力的な機能は見当たらないので(イントラネット向けではないのかも)、苦労して2013にするメリットは無いと判断した。

そもそも「InfoPath」自体、印刷がさっぱりであまり使い物にならないので、いずれ撤退して、SharePoint2020あたりでの移行を目指すか(笑)

 

愚痴はさておき、SharePointサイトのテーマを設定する。

GUIでは「サイトの操作」「サイトの設定」「外観」「サイトのテーマ」から設定することができる。
image

これを見ると、親サイトのテーマを変えるとサブサイトのテーマも一気に変更してくれる。

っと思うのが普通だが、サブサイトのテーマは一向に変わってくれない。
サブサイト側の設定は確かに継承設定に変更されるのだが、
image

テーマ自体が反映されない。

なんともはや・・・。

仕方がないので、スクリプトで一律変更することにした。

あまり自信はないがこんな感じだろうか。

001
002
003
004
005
006
007
008
009
010
011
012
013

Add-PSSnapin Microsoft.SharePoint.PowerShell
$root = "http://svname/sites/root1"
$themeFile = "_catalogs/theme/Vantage.thmx"

#テーマ更新
$rootSite = Get-SPSite 
$root
$web
 = Get-SPWeb "$root/sub1"
$theme =
 
 
[Microsoft.SharePoint.Utilities.ThmxTheme]::Open($rootSite,$themeFile)
$theme.ApplyTo($web,$false)
$web.Update()
$web.Dispose()
$rootSite.Dispose()

ここでは「Vantage」というテーマを指定している。
image

対応する名前は以下のスクリプトで取得可能。

>[Microsoft.SharePoint.Utilities.ThmxTheme]::GetManagedThemes($rootsite) | select name

image

 

あーっ!!判った。
image

これを設定するタイミングでテーマも変更してあげないといけないようだ。
なので今のテーマを一律子供に反映したいときは、一旦別のテーマにしてから戻してあげると良さそう。

SharePoint恐るべし。