PowerShellで作成したフォルダに直ぐに移動(ただのメモ)

| 2010年12月1日水曜日
フォルダを作成するとき、直ぐにそのフォルダに移動して作業をしたいことが多いと思う。

でも、フォルダが多い場所で作成すると、目的のフォルダに移動するのはなかなか時間がかかる。
特に日本語のフォルダに移動するときは、Tabを連打したり、フォルダ名の一部を入力、またはペースとして補完するなど、わりと面倒くさい。

そんな時、作成したフォルダに直ぐに移動するには、PowerShellでは以下のようにすればよい。

> mkdir "適当なフォルダ名" | cd $_

mkdirをすると、DirectoryInfoオブジェクトが返ってくるのでそれをパイプして移動する。

※単純だけど、なんとなく忘れてしまいそうなTipsなのでメモ

Pingの結果をPowerShellっぽく取得してみる

| 2010年11月30日火曜日
PowerShellからPing打つことはもちろんできるが、バッチファイルの中で利用すると結果が一々コンソールに出力されてちょっと邪魔な時がある。

バッチファイルの中で知りたいのは、そのIPのマシンが生きているかどうかなので、結果は「True」か「False」で十分だ。

そこで、Pingの結果をラップしてPowerShellで扱いやすいようにしてみる。

■使い方
> Get-PingResult www.google.com #成功時
Value Reply
----- -----
True {www.l.google.com [66.249.89.104]に ping を送...

> $a = Get-PingResult www.google.com #変数に入れてみる
> $a.Reply
www.l.google.com [66.249.89.104]に ping を送信しています 32 バイトのデータ:
66.249.89.104 からの応答: バイト数 =32 時間 =19ms TTL=57
66.249.89.104 からの応答: バイト数 =32 時間 =21ms TTL=57
66.249.89.104 からの応答: バイト数 =32 時間 =19ms TTL=57
66.249.89.104 からの応答: バイト数 =32 時間 =20ms TTL=57
66.249.89.104 の ping 統計:
パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
最小 = 19ms、最大 = 21ms、平均 = 19ms

> Get-PingResult www.google.coma #失敗時
Value Reply
----- -----
False ping 要求ではホスト www.google.coma が見つかり...

  1. function Get-PingResult([String]$IP) {
  2.  $reply = C:\Windows\System32\PING.EXE $IP
  3.  #余分な空白行を削除する
  4.  $reply = $reply | % { if ($_ -ne "") { $_ }}
  5.  #上手くいったかどうかは結果の行数で判断する
  6.  $success = 9
  7.  $result = New-Object psobject
  8.  if ($reply.Length -eq $success) {
  9.   $result | Add-Member -MemberType NoteProperty -Name "Value" -Value $true
  10.  } else {
  11.   $result | Add-Member -MemberType NoteProperty -Name "Value" -Value $false
  12.  }
  13.  $result | Add-Member -MemberType NoteProperty -Name "Reply" -Value $reply
  14.  return $result
  15. }

PowerShellで文字列をバイトで区切って切り出す

|
メールの本文を生成する場合などに、きれいにフォーマットするためスペースなどで埋めたり、文字数でカットして成形したい時がある。
ただ、PowerShellだと、半角の「ABCD」というのと、全角の「ABCD」はおなじ4文字としてカウントされる。
そこでVBのLeftBのようにバイト数で切り取ってみる。

■使い方
> Get-SubStringBytes "ABCD" 2 2 #半角文字を2バイト目から2バイト切り取る
CD
> Get-SubStringBytes "ABCD" 2 2 #全角文字を・・・(略)
  1. function Get-SubStringBytes([String]$Text, [int]$StartIndex = 0, [int]$Length = 0) {
  2. $enc = [System.Text.Encoding]::Default
  3. $bytes = $enc.GetBytes($Text)
  4. return $enc.GetString($bytes, $StartIndex, $Length)
  5. }

PowerShellでユーザー一覧に利用可能か無効を付けて出力する

|
Windowsのサーバー管理をしていると、突然に利用しているユーザーの一覧を提出するように求められることがある。

そんな時、慌ててGUIの管理ツールからユーザー一覧をCSV形式やなんかでエクスポートすると、削除せずに無効にしているユーザーまで出力されてしまい、そのユーザーが現在利用可能かどうかなどの状態情報は出力されないので後で指摘されることがある。

そこで、現在利用可能か無効かの情報も一緒にユーザー一覧に付けて出力してみる。

> Get-WmiObject Win32_UserAccount | Select-Object -Property Status, Name, FullName, Description

Status    Name      FullName  Description
------    ----       --------   -----------
Degraded   Administrator         コンピュータ/ドメイン...
Degraded  Guest               コンピュータ/ドメイン...
OK      ユーザー名

利用可能なユーザーは「Status」が「OK」になっている。

PowerShellでディスクトップのキャプチャを撮る

| 2010年10月19日火曜日
わざわざキャプチャを撮るのにPowerShellを使っても仕方がないから、あまり使う機会はないかもしれない。
普通にPrintScreenキー押してMSBitmapに張り付ければいいからね。

ただ、サーバー管理なんかをしている人だと、サーバー側で現在のサーバー自身のディスクトップをキャプチャして、定期的にメールしてくるってのは、わりといいのではないかと思って作成してみた。

下のコードはコマンドを打つと、カレントフォルダに「out.jpg」ファイルができる感じです。

--- PrintScreen-Desktop.ps1 ---
  1. param([string]$outImage = "out.jpg")
  2. $b = New-Object System.Drawing.Bitmap([System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Width, [System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Height)
  3. $g = [System.Drawing.Graphics]::FromImage($b)
  4. $g.CopyFromScreen((New-Object System.Drawing.Point(0, 0)),(New-Object System.Drawing.Point(0, 0)), $b.Size)
  5. $g.Dispose()
  6. $b.Save((Join-Path $PWD $outImage))

PowerShellで「du」コマンド その3

| 2010年10月7日木曜日
【その2】の「du」だと、フルパスが長すぎるとうまく取得できない場合があるのでWSHの力を借りる。

やっていることは、カレントフォルダ内のフォルダを対象に、右クリックのプロパティで取得できるサイズをとっているだけ。

GetFolderのSizeを取っているだけなのであっさりと書けるのがよい。

速度も【その2】の時より早い。
簡単に計測したのでは、【13倍】の速さだった。

$fs = New-Object -ComObject Scripting.FileSystemObject
ls | % {
if ($_.PSIsContainer) {
$name = $_.name
$size = ($fs.GetFolder($_)).size / 1MB
Write-Host $name " : " $size.ToString("0.00") "MB"
}
}

PowerShellで「ユーザーは次回ログオン時にパスワードの変更が必要」を有効化するには

| 2010年6月18日金曜日
サーバー管理をしていてリストにあるユーザー全員の「ユーザーは次回ログオン時にパスワードの変更が必要」を有効化しないといけなくなったので調べてみた。

手順としては、まずユーザー情報を取ってくる。
そのあと、有効化フラグである「1」を指定して反映させる。

PS> $username = ユーザーID
PS> $query "WinNT://./" + $username + ",user"
PS> $user = [ADSI]($query)
PS> $user.PasswordExpired = 1
PS> $user.SetInfo()

自分が実際にやった時には、CSVに書かれたユーザーIDをImport-CSVして一気に処理させたけどね;-)

PowerShellでダミーファイルを作る

|
別にPowerShellでなくても普通にCMDでダミーファイルを作る時も同じだけど、

PS> fsutil.exe file createnew 1MBのダミーファイル 1048576
ファイル C:\Windows\system32\1MBのダミーファイル が作成されました

っとすると、1MBのファイルを作る事が出来る。

それをPowerShellでやると何が嬉しいかと言うと、引数に「1048576」じゃなくて「1MB」と指定しても作れるところだ。

PowerShellでは、

PS> fsutil.exe file createnew 1MBのダミーファイル (1MB)
ファイル C:\Windows\system32\1MBのダミーファイル が作成されました

っとすれば、作ることができる。これで、「100MB」でも「1GB」でも簡単に作れそうだ。

ただ、「1MB」を括弧で囲んで「 (1MB) 」としないと、下のようにヘルプが表示されてしまう。
「1MB」が展開されずに「1MB」と文字列で渡されてしまうからだろう。

PS> fsutil.exe file createnew 1MBのダミーファイル 1MB
使用法 : fsutil file createnew <ファイル名> <長さ>
例 : fsutil file createnew C:\testfile.txt 1000

※ちなみに、Vistaだと管理者権限でPowerShellを起動しないと作れない。

PowerShellでLinuxの「du」コマンド その2

| 2010年6月8日火曜日
 フォルダ容量を取得するくらいなら、PowerShellのコマンドレットだけでできるような気がしてたけど、実際にできたのでメモ。
っというか、前にブログを書いた時点で気付けたと思うんだけどね。まだまだだな俺。

binフォルダ以下の容量を取得ところ、「Sum」が合計
> Get-ChildItem -Path .\bin -Force -Recurse | Measure-Object -Property Length -Sum

Count : 13391
Average :
Sum : 1243746959
Maximum :
Minimum :
Property : Length

これだと、わかりにくいので、MBにする。
> Get-ChildItem -Path .\bin -Force -Recurse | Measure-Object -Property Length -Sum | ForEach-Object { $_.Sum / 1MB }
1186.12953090668

MBでもわかりにくかったのでGBで、
> Get-ChildItem -Path .\bin -Force -Recurse | Measure-Object -Property Length -Sum | ForEach-Object { $_.Sum / 1GB }
1.15832962002605

PowerShellでMACアドレスからメーカーを調べる

| 2010年6月1日火曜日
PowerShellでMACアドレスからメーカー(ベンダー)を調べてみる。

まずは、MACアドレスを取得する。
MACアドレスの取り方はいろいろあるけど、ここでは、「nbtstat」コマンドを利用することにした。
まぁ一行であっさり書きたかっただけだけど。

--- Get-MACAddress.ps1 ---
  1. param([string]$ip)
  2. nbtstat -A $ip | ForEach-Object { if ( $_ -match "MAC") { $_ -replace " ","" -replace "MACアドレス=","" } }

次に、取得したMACアドレスからメーカーを調べる。
メーカーを調べるサイトは、ここを利用させてもらう。

--- Find-MacAddressFromVendorName.ps1 ---
  1. param([string]$macaddress)
  2. [void]([Reflection.Assembly]::LoadWithPartialName("System.Web"))
  3. $macaddress = [Web.HttpUtility]::UrlEncode($macaddress)
  4. $webReq = [Net.HttpWebRequest]::Create("http://www.coffer.com/mac_find/?string=$macaddress")
  5. $webReq.Method = "GET"
  6. $webReq.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)"
  7. $webRes = $webReq.GetResponse()
  8. $sr = New-Object IO.StreamReader($webRes.GetResponseStream(), $webRes.ContentEncoding)
  9. $content = $sr.ReadToEnd()
  10. $sr.Close()
  11. $webRes.Close()
  12. $content = $content.Split("`n")
  13. $result = $content | ForEach-Object {
  14. if ($_ -match "table2" -and $_ -match "td") {
  15. $_ -replace "<.*?>","" -replace "`t","" }
  16. }
  17. $obj = New-Object PSObject
  18. $obj | Add-Member NoteProperty MacAddress $macaddress
  19. $obj | Add-Member NoteProperty Vendor $result[1]
  20. $obj
利用方法は、パスを通したところにスプリクトを保存しておいて、

> Find-MacAddressFromVendorName ( Get-MACAddress 192.168.0.1)

MacAddress            Vendor
----------                ------
XX-XX-XX-XX-XX-XX       XXX

っといった感じ。

PowerShellでリモートPCのHDD容量を取得する

| 2010年5月28日金曜日
 サーバーのHDD容量を、PowerShellで監視したかったので、書いてみた。
 PowerShellを使うと、わりとなんでも簡単にできるのから嬉しいが、だんだん手放せなってきているのがちょっと怖い。
  1. $computer_name = "foo.bar.co.jp" #IPアドレスでもOK
  2. $user_name = "administrator"
  3. $password = ConvertTo-SecureString -String "hogehoge" -AsPlainText -Force
  4. $credential = New-Object System.Management.Automation.PSCredential($user_name, $password)
  5. Get-WmiObject -Class win32_logicaldisk -ComputerName $computer_name -Credential $credential

PowerShellでリモートのイベントログを取得する(その2)

| 2010年5月25日火曜日
PowerShellでは以下のコマンドでリモートのイベントログを取得する事ができる。

> Get-EventLog -ComputerName コンピュータ名 -LogName ログ名

例えば、

> Get-EventLog -ComputerName foo.xx.co.jp -LogName application

とすると、「foo.xx.co.jp」のアプリケーションログを取得する事ができる。

でも、コンピュータ名@ドメイン名を入力するということは、DNSで名前解決できるマシンじゃないと駄目ということだ。
俺の環境では使えないか…

っと思っていたら、引数がコンピュータ名などとなっているのにもかかわらず、IPアドレスでもリモートのイベントログを取得できることが分かった。

> Get-EventLog -ComputerName 192.168.0.1 -LogName Application

だだし、指定したIPによっては以下のようなエラーとなるかもしれない。

> Get-EventLog -ComputerName 192.168.0.1 -LogName Application
Get-EventLog : 許可されていない操作を実行しようとしました。
発生場所 行:1 文字:13
+ Get-EventLog <<<< -ComputerName 192.168.0.1 -LogName Application
+ CategoryInfo : NotSpecified; (:) [Get-EventLog], UnauthorizedAccessException
+ FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands. Get
EventLogCommand

そんな時は、単にそのマシンに対して権限がないだけの話なので、以下のように「net use」コマンドを利用して、管理者権限でそのIPのマシンに接続してしまえばOKだ。

> net use \\192.168.0.1 パスワード /user:administrator

あと、Get-Processも引数に -ComputerName をとるので、リモートで何台も管理している人は覚えておくと便利だと思う。

PowerShellでLinuxの「du」コマンド

| 2010年5月22日土曜日
作ろうと思ったら、もう作っている人がいたので、メモ。