Windows PowerShell の応用


 [Home]  [Index] 投稿 2015/04/28


 

 

 

ここでは分野ごとにいくつかのサンプルを紹介します。

 コンピュータの管理

システム

★ OS と PowerShell のバージョン情報

#
#  Windows と PowerShell のバージョンを取得する。
#
$ver = [System.Environment]::OSVersion.Version
$global:osver = @{ "Major"=$ver.Major; "Minor"=$ver.Minor; "Build"=$ver.Build; "Revision"=$ver.Revision}

if ($args.length -eq 0) {
  $str = [String]$osver["Major"] + "." + [String]$osver["Minor"]
}
else {
  $str = [String]$osver["Major"] + "." + [String]$osver["Minor"] + "." + [String]$osver["Build"] + "." + [String]$osver["Revision"]
}

$str = "Windows Version " + $str
$str

$psver = $(get-host).version
"PowerShell Version " + [string]$psver.major + "." + [string]$psver.minor

実行例

PS C:\> .\version.ps1
Windows Version 6.3
PowerShell Version 4.0

[Top]


★ コンピュータの各種情報

#
#  WMI Win32_ComputerSystem
#
$wmio = get-wmiobject Win32_ComputerSystem

$wmio.Caption
$wmio.Description
$wmio.Domain
$wmio.Manufacturer
$wmio.Model
$wmio.Name
$wmio.PrimaryOwnerName
$wmio.Status
$wmio.Workgroup

実行例

PS C:\> .\wmi_computer.ps1
DELL
AT/AT COMPATIBLE
Workgroup
Dell Inc.
Inspiron 3847
DELL
xxxxxxxx@hotmail.com
OK
Workgroup

[Top]


★ スペシャルフォルダの場所を表示する

#
#  スペシャルフォルダ一覧
#
$keys = [Enum]::GetNames("System.Environment+SpecialFolder") | Sort-Object
foreach ($key in $keys) 
{
  write-host $key `t  $([System.Environment]::GetFolderPath($key))
}

実行例

PS C:\> .\specialfolders.ps1
AdminTools       C:\Users\user\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Administrative Tools
ApplicationData          C:\Users\user\AppData\Roaming
CDBurning        C:\Users\user\AppData\Local\Microsoft\Windows\Burn\Burn
CommonAdminTools         C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Administrative Tools
CommonApplicationData    C:\ProgramData
(以下略)

[Top]


ハードウェア

★ マシンとメモリの情報

#
#  WMI Win32_OperatingSystem
#    関連情報 http://www.wmifun.net/library/win32_operatingsystem.html
$wmio = get-wmiobject Win32_OperatingSystem
$wmio.Caption
$wmio.Description
"空き物理メモリ " + [string]$wmio.FreePhysicalMemory
"空き仮想メモリ " + [string]$wmio.FreeVirtualMemory
"全物理メモリ " + [string]$wmio.TotalVisibleMemorySize
"全仮想メモリ " + [string]$wmio.TotalVirtualMemorySize
PS C:\> .\wmi_os
Microsoft Windows 8.1
Inspiron 3847
空き物理メモリ 6047460
空き仮想メモリ 12714672
全物理メモリ 8338372
全仮想メモリ 16726980

[Top]


★ ディスク情報

#
#  WMI Win32_DiskDrive
#
$wmio = get-wmiobject Win32_DiskDrive

$n = $wmio.Caption.length
"ドライブ数 " + $n
for ($i = 0; $i -lt $n; $i++) {
  $mb = [Math]::Round($wmio.Size[$i] / (1024 * 1024 * 1024))
  $si = $i + 1
  [string]$si + " " + $wmio.Caption[$i] + " " + [string]$mb + "GB"
}
PS C:\> .\wmi_disk
ドライブ数 3
1 SDHC Card 15GB
2 WDC WD10EZEX-75M2NA0 932GB
3 Hitachi HDT721010SLA360 932GB

[Top]


イベントログ

★ 警告一覧の表示

PS C:\> get-eventlog -newest 50 -logname system | where EntryType -eq "Warning"

Index Time          EntryType   Source                 InstanceID Message
----- ----          ---------   ------                 ---------- -------
 9572 4 30 08:20    Warning     Microsoft-Windows...         1014 名前 matomedb.com の名前解決は、構成されたどの ...
 9544 4 30 05:55    Warning     Microsoft-Windows...          219 デバイス ROOT\WPD\0000 のドライバー \Driver\Wud...

[Top]


ユーザ

ユーザの情報を表示

# ユーザのフォルダ
$env:userprofile
# ユーザの名前
$env:username

[Top]



プロセス

★ ワイルドカードを指定してプロセス一覧を表示

#
#  名前のワイルドカードを指定してプロセス一覧を表示する。
#
if ($args.length -eq 0)
{
  "パラメータを指定してください。pattern"
  exit
}

$pattern = $args[0]
get-process | where name -like $pattern

実行例

PS C:\> .\show_process A*

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    362      21    10092        628   116     0.23   4916 AAM Updates Notifier
     76       8     1232        248    76     0.00   4416 ActivateDesktop
     96       7     1540       1480    57     0.00   2228 AdminService
     34       4      500        644    12     0.00   2196 AERTSr64
    190      13     2388       3040    82     0.09   4944 ApplicationManager
     81       7     1044       1172    44     0.02   1944 armsvc
    413      14    13432      17656    81 1,323.25   6764 audiodg

[Top]


★ CPU に負荷を掛けているプロセスを降順で10個表示

#
#  CPU に負荷を掛けているプロセスを降順で10個表示する。
#   -u を付けると他のユーザのプロセスも表示。

#
# 管理者か判別する。
#   (Writtern by) http://powershell.com/cs/media/p/200.aspx
#
function isAdmin { 
  $identity = [System.Security.Principal.WindowsIdentity]::GetCurrent() 
  $principal = new-object System.Security.Principal.WindowsPrincipal($identity) 
  $admin = [System.Security.Principal.WindowsBuiltInRole]::Administrator 
  $principal.IsInRole($admin) 
} 

$cmd = "Get-Process"
if (($args.length -gt 0) -and ($args[0] -eq "-u")) {
  if (isAdmin -eq $true) {
    $cmd = $cmd + " -IncludeUserName"
  }
  else {
    "管理者権限が必要です。"
    exit
  }
}

$i = 0
invoke-expression $cmd | sort-object -property CPU -descending | foreach-object {
  $i++
  if ($i -gt 10) {
    break
  }
  $_
}

実行例

PS C:\> .\sort_process.ps1

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    989     171   607316     556324  1296 1,731.23   1636 firefox
   1211       0    43180       1104    47 1,658.05      4 System
    424      15    13616      17764    83 1,342.17   6764 audiodg
    554      56   133104      86500   347   743.58   3016 MsMpEng
    782      37   105672      92972   168   258.28   1064 svchost
    203      21    53824      48128   252   204.95    960 dwm
    569      41    48008      62564   332   176.14   5420 plugin-container
   2731     364   103948     112508  1239   133.27   2016 explorer
    643      54    34656      42064   392    35.30   3216 SearchIndexer
   1993      66    30908      35372   178    28.55    360 svchost
p -u (他のユーザのプロセスも表示) オプションを付けた時
PS C:\> .\sort_process.ps1 -u

Handles      WS(K) VM(M)   CPU(s)     Id UserName          ProcessName
-------      ----- -----   ------     -- --------          -----------
    987     558220  1300 1,762.13   1636 DELL\makandata... firefox
   1209       1104    47 1,660.55      4                   System
    417      17668    82 1,356.42   6764                   audiodg
    552      87560   348   750.13   3016                   MsMpEng
    782      92992   168   258.59   1064 NT AUTHORITY\S... svchost
    207      48288   252   208.42    960 Window Manager... dwm
    581      61936   332   180.69   5420 DELL\makandata... plugin-container
   2732     113740  1241   134.47   2016 DELL\makandata... explorer
    621      42012   391    35.75   3216 NT AUTHORITY\S... SearchIndexer
   1999      35336   177    28.59    360 NT AUTHORITY\S... svchost

[Top]


★ Java アプリの起動

#
#  Java アプリを実行する。
#    args[0] メインクラスの名前 または jarファイル
#    args[1] 引数のリスト
#    args[2] 実行ディレクトリ
#  ※ CLASSPATH は事前に設定すること。
#

if ($args.length -eq 0) {
@"
   Java アプリを実行する。
     args[0] メインクラスの名前 または jarファイル
     args[1] 引数のリスト
     args[2] 実行ディレクトリ
    ※ CLASSPATH は事前に設定すること。
"@
 exit
}

$main = "Main"
if ($args.length -gt 0) {
  $main = $args[0]
}


$workdir = "."
if ($args.length -gt 1) {
  $workdir = $args[1]
}

$arglist = ""
if ($args.length -gt 2) {
  $arglist = $args[2]
}


if ($main -match "\.jar$") {
  echo "java -jar $main $arglist @$workdir"
  start-process java -argumentlist "-jar $main $arglist" -workingdirectory $workdir -nonewwindow
}
else {
  echo "java $main $arglist @$workdir"
  start-process java -argumentlist "$main $arglist" -workingdirectory $workdir -nonewwindow
}

実行例

PS C:\workspace\misc\PowerShell\process> .\java_start ButtonTest.jar C:\workspace\Java\AWT\Button
java -jar ButtonTest.jar  @C:\workspace\Java\AWT\Button

[Top]


サービス

★ サービス一覧

#
# 動作しているサービス一覧を得る。
#
get-service | foreach-object {
  if ( $_.status -eq "Running") {
    $_.name + "`t" + $_.displayname
  }
}

実行例

PS C:\workspace\Misc\PowerShell\os> .\running_services.ps1
AdobeActiveFileMonitor13.0      Adobe Active File Monitor V13
AdobeARMservice Adobe Acrobat Update Service
AERTFilters     Andrea RT Filters Service
AppHostSvc      Application Host Helper Service
(以下略)

[Top]


★ svchost.exe から起動されているサービス一覧

# svchost.exe から起動されているサービス一覧
tasklist /SVC | foreach-object { if ($_ -match "svchost.exe") { $_ } }
svchost.exe                    816 BrokerInfrastructure, DcomLaunch, LSM,
svchost.exe                    860 RpcEptMapper, RpcSs
svchost.exe                   1016 Audiosrv, Dhcp, EventLog,
(以下略)

※ svchost.exe は DLL から起動されるサービスのホストになるプロセスである。

[Top]


★ サービスのリスタート

#
#  サービスを再起動する(管理者権限が必要)。
#

#
# 管理者か判別する。
#   (Writtern by) http://powershell.com/cs/media/p/200.aspx
#
function isAdmin { 
  $identity = [System.Security.Principal.WindowsIdentity]::GetCurrent() 
  $principal = new-object System.Security.Principal.WindowsPrincipal($identity) 
  $admin = [System.Security.Principal.WindowsBuiltInRole]::Administrator 
  -not $principal.IsInRole($admin) 
}

if (isAdmin -eq $false) {
  "管理者権限がありません。"
  exit
}

$list = new-object "System.Collections.Generic.List[String]"
get-service | foreach-object {
  if ( $_.status -eq "Running") {
    $list.Add($_.displayname)
  }
}

for ($i = 0; $i -lt $list.count; $i++) {
  $n = [string]($i + 1)
  [string]$n + " " + $list[$i]
}

"リスタートするサービスの番号を入力してください。( Ctrl+C で中止 )"
$n = [int]$(read-host) - 1
$list[$n] + "を再起動します。中止するときは Ctrl+C を入力してください。"
read-host
restart-service -displayname $list[$n]
"再起動しました。"
1 Adobe Active File Monitor V13
2 Adobe Acrobat Update Service
3 Andrea RT Filters Service
(中略)
96 Windows Search
97 Windows Driver Foundation - User-mode Driver Framework
リスタートするサービスの番号を入力してください。( Ctrl+C で中止 )
1
Adobe Active File Monitor V13を再起動します。中止するときは Ctrl+C を入力してください。

再起動しました。

[Top]


プログラム

★ スタートメニューの内容

#
#  Start Menu の内容
#
$start = "StartMenu"
if ($args.length -gt 0) {
  # 何かコマンドライン引数があれば、共通メニューを表示する。
  $start = "Common" + $start
}

$place = [System.Environment]::GetFolderPath($start)
get-childitem $place -recurse | foreach-object {
  if ($_.name -match "\.lnk$") {
    $($_.directory.name + "/" + $_.name).replace(".lnk", "")
  }
}

実行例

PS C:\> .\startmenu.ps1
Programs/Documents
Programs/Internet Explorer
Programs/Pictures
Programs/powershell_ise
(以下略)

[Top]


地域

現在の言語を取得するには get-culture を使用する。

PS C:\< get-culture

LCID             Name             DisplayName
----             ----             -----------
1041             ja-JP            日本語 (日本)

[Top]


 ファイルシステム

ファイル一覧の取得

ファイル一覧の取得は get-childitem コマンドレットを使用する。

#
#  ファイル一覧を取得する。(リダイレクトしてファイル保存可能)
#

# p がファイルなら true, ディレクトリなら false を返す。
function isFile($p) {
  test-path $p -pathtype leaf
}

if ($args.length -eq 0) {
  "パラメータを指定してください。folder"
  exit
}

get-childitem $args[0] | foreach-object {
  $path = $_.fullname
  if (isFile($path)) {
    $path
  }
}

[Top]


オブジェクトの存在確認

tes-path コマンドレットを使うとファイルなどの存在を確認できる。

if ($args.Length -gt 0) {
  if (test-path $args[0]) {
    "存在"
  }
  else {
    "存在しない。"
  }
}
else {
  "エラー"
}

[Top]


ファイルとディレクトリの判別

指定したパスがファイルか判別するには test-path コマンドレットで -pathtype leaf を使用する。

if ($args.Length -gt 0) {
  if (test-path $args[0] -pathtype leaf) {
    "存在"
  }
  else {
    "存在しない。"
  }
}
else {
  "エラー"
}

[Top]


ディレクトリの作成

ディレクトリの作成は new-item コマンドレットで行うが、mkdir を使ったほうが簡単である。

PS C:\workspace> new-item -type directory -name dir1

    ディレクトリ: C:\workspace


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        2015/05/01     17:23            dir1

[Top]


ファイルの作成

ファイルの作成は write-host や write-output (echo) とリダイレクト演算子 (>, >>) を使って行うことができる。

PS C:\> echo "oops" > test.txt
PS C:\> cat test.txt
oops
PS C:\> echo oops2 >> text.txt
PS C:\> echo oops3 >> text.txt
PS C:\> cat text.txt
oops
oops2
oops3

[Top]


オブジェクトの削除

ディレクトリおよびファイルの削除は remove-item コマンドレットで行うことができる。

PS C:\workspace> remove-item dir1
PS C:\workspace> ls
PS C:\workspace>

ファイルやサブディレクトリを含むディレクトリを削除するときは -recurse オプションを使用する。

[Top]


オブジェクトの移動

オブジェクトに移動または名前の変更は move-item コマンドレットを使う。ファイルだけでなくディレクトリに対しても同様に使用できる。

PS C:\workspace> move-item test.txt test2.txt
PS C:\workspace> ls

    ディレクトリ: C:\workspace

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        2015/05/01     17:41         14 test2.txt

[Top]


パス名

パス名の要素を取り出すには split-path コマンドレットを使用する。

# Split-Path コマンドレット

# PowerShell フォルダ
split-path $profile  # -parentと同じ
split-path $profile -leaf
split-path $profile -qualifier
split-path $profile -isabsolute
split-path ".\" -isabsolute

# レジストリの場合
$key = "HKCU:\Software\Microsoft\Windows"
split-path $key
split-path $key -leaf
split-path $key -qualifier
split-path $key -isabsolute

実行例

PS C:\> .\splitpath.ps1
C:\Users\user\Documents\WindowsPowerShell
Microsoft.PowerShell_profile.ps1
C:
True
False
HKCU:\Software\Microsoft
Windows
HKCU:
True

パス名の一部を連結するには join-path コマンドレットを使用する。

PS C:\> join-path c:\windows system32
c:\windows\system32

[Top]


絶対パス

相対パスを絶対パスに変換するには convert-path を使用する。

PS C:\workspace\PowerShell> convert-path .
C:\workspace\misc\PowerShell

[Top]


ショートカット

ショートカットは WSH の WScript.Shell オブジェクトを使用して操作する。

# フォルダ内のショートカットを検索し、ショートカットの内容を変更する。
clear-host

# ショートカットを検索する対象フォルダ
$folder = "C:\data\Pictures"
write-host "対象フォルダ:"  $folder
# 置換対象(検索)文字列
$search = "D:\"
# 置換する文字列
$replace = "C:\data\"

# ショートカット一覧を得る。
"ショートカットを検索中。しばらくお待ちください ..."
$shortcuts = get-childitem -path $folder -recurse -include *.lnk

$count = $shortcuts.length
if ($count -eq 0) {
  "ショートカットが見つかりませんでした。", "終了します。"
  exit 9
}

$shell = new-object -comobject WScript.Shell

write-host $count "件のショートカットが見つかりました。"
$shortcuts | foreach-object {
  echo $_.fullname
  $wsc = $shell.CreateShortcut($_.fullname)
  if ($wsc.TargetPath.IndexOf("D:\Pictures") -eq 0) {
    echo $wsc.TargetPath
    $wsc.TargetPath = $wsc.TargetPath.Replace($search, $replace)
    $wsc.Save()
  }
}

[Top]


 

 テキストファイル

ファイルの読み書き

ファイルを読み込むのには get-content コマンドレットを使用する。

# ファイルの読み込み
if ($args[0].length -eq 0) {
  "ファイルを指定してください。"
  exit
}

$s = get-content $args[0]
$s

実行例

PS C:\> .\read sample.txt
sample.txt
row 1
row 2
row 3

1行ずつファイルを読み込んで処理するには、StreamReader などを使用する。

#
#  大きなファイルを1行づつ処理する場合
#
if ($args.length -eq 0) {
  "ファイルを指定してください。"
  exit
}

$filename = convert-path $args[0]
$stream = new-object System.IO.StreamReader($filename)
while ($stream.EndOfStream -ne $true) {
  $s = $stream.ReadLine()
  $s
}
$stream.Close()

実行例

PS C:\> .\readline.ps1 sample.txt
sample.txt
row 1
row 2
row 3

ファイルに文字列を書くにはリダイレクトを使用する。

# ファイルの書き込み
if ($args.length -eq 0) {
  "ファイルを指定してください。"
  exit
}

if ($(test-path $args[0]) -eq $true) {
  remove-item $args[0]
}

for ($i = 0; $i -lt 5; $i++) {
  echo $i >> $args[0]
}
"done."

[Top]


ファイルの比較

ファイルの比較には compare-object コマンドレットを使用する。

#
#  ファイルの比較
#
if ($args.length -lt 2) {
  "比較するファイルを指定してください。"
  exit
}

$result = compare-object -referenceobject $(get-content $args[0]) -differenceobject $(get-content $args[1])

if ($result -eq $null) {
  "一致しました。"
}
else {
  "内容が異なります。"
}

[Top]


CSV

ConvertTo-Csv

CovertTo-Html コマンドレットは .NET Framework のオブジェクトを CSV に変換する。デフォルトでは標準出力に出力されるので、ファイルに保存するときはリダイレクトを利用する。

PS C:\> get-date | convertto-csv
#TYPE System.DateTime
"DisplayHint","DateTime","Date","Day","DayOfWeek","DayOfYear","Hour","Kind","Millisecond","Minute","Month","Second","Ticks","TimeOfDay","Year"
"DateTime","2015年5月8日 14:27:19","2015/05/08 0:00:00","8","Friday","128","14","Local","23","27","5","19","635666920390238704","14:27:19.0238704","2015"

[Top]


ConvertFrom-Csv

ConvertFrom-Csv は CovertTo-Html コマンドレットで作成した CSV を元のオブジェクトに変換する。

PS C:\> $cmd = get-command *-csv | convertto-csv
PS C:\> $cmd | convertfrom-csv

HelpUri             : http://go.microsoft.com/fwlink/?LinkID=135201
DLL                 : C:\Windows\Microsoft.Net\assembly\GAC_MSIL\Microsoft.PowerShell.Commands.Utility\v4.0_3.0.0.0__31
                      bf3856ad364e35\Microsoft.PowerShell.Commands.Utility.dll
Verb                : ConvertFrom
Noun                : Csv
HelpFile            : Microsoft.PowerShell.Commands.Utility.dll-Help.xml
PSSnapIn            :
ImplementingType    : Microsoft.PowerShell.Commands.ConvertFromCsvCommand
Definition          :
                      ConvertFrom-Csv [-InputObject] <psobject[]> [[-Delimiter] <char>] [-Header <string[]>] [<CommonParameters>]
(以下略)

[Top]


Export-Csv

Export-Csv はパイプラインからの入力を CSV ファイルに保存できる。

PS C:\> get-command *-csv | select name | export-csv export.csv
PS C:\> cat export.csv
#TYPE Selected.System.Management.Automation.CmdletInfo
"Name"
"ConvertFrom-Csv"
"ConvertTo-Csv"
"Export-Csv"
"Import-Csv"

[Top]


Import-Csv

Import-Csv コマンドレットは Export-Csv で作成した CSV ファイルをオブジェクトに変換できる。

PS C:\> $a = import-csv export.csv
PS C:\> $a

Name
----
ConvertFrom-Csv
ConvertTo-Csv
Export-Csv
Import-Csv

[Top]


HTML

CovertTo-Html コマンドレットは .NET Framework のオブジェクトを HTML に変換する。デフォルトでは標準出力に出力されるので、ファイルに保存するときはリダイレクトを利用する。

PS C:\> get-date | convertto-html -title get-date
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>get-date</title>
</head><body>
<table>
<colgroup><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/></colgroup>
<tr><th>DisplayHint</th><th>DateTime</th><th>Date</th><th>Day</th><th>DayOfWeek</th><th>DayOfYear</th><th>Hour</th><th>
Kind</th><th>Millisecond</th><th>Minute</th><th>Month</th><th>Second</th><th>Ticks</th><th>TimeOfDay</th><th>Year</th><
/tr>
<tr><td>DateTime</td><td>2015年5月8日 14:12:06</td><td>2015/05/08 0:00:00</td><td>8</td><td>Friday</td><td>128</td><td>
14</td><td>Local</td><td>314</td><td>12</td><td>5</td><td>6</td><td>635666911263146314</td><td>14:12:06.3146314</td><td
>2015</td></tr>
</table>
</body></html>

[Top]


XML

ConvertTo-Xml コマンドレットは .NET Framework オブジェクトから XML ベースの表現を作成する。

ConvertFrom-Xml コマンドレットは ConvertTo-Xml コマンドレットの出力を元のオブジェクトに戻す。

Export-CliXml

Export-CliXml は .NET Framework オブジェクトから XML ファイルを生成する。

PS C:\> get-date | export-clixml cli.xml
PS C:\> cat cli.xml
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
  <Obj RefId="0">
    <DT>2015-05-08T15:32:45.864678+09:00</DT>
    <MS>
      <Obj N="DisplayHint" RefId="1">
        <TN RefId="0">
          <T>Microsoft.PowerShell.Commands.DisplayHintType</T>
          <T>System.Enum</T>
          <T>System.ValueType</T>
          <T>System.Object</T>
        </TN>
        <ToString>DateTime</ToString>
        <I32>2</I32>
      </Obj>
    </MS>
  </Obj>
</Objs>

[Top]


Import-CliXml

Import-CliXml コマンドレットは Export-CliXml コマンドレットで作成した XML からオブジェクトを作成する。

PS C:\> $a = import-clixml cli.xml
PS C:\> $a

2015年5月8日 15:32:45

[Top]


JSON

ConvertTo-Json

オブジェクトを JSON 形式の文字列に変換する。

PS C:\> get-date | convertto-json
{
    "value":  "\/Date(1431067435575)\/",
    "DisplayHint":  2,
    "DateTime":  "2015年5月8日 15:43:55"
}

[Top]


 

 コレクション

PowerShell に組み込まれているコレクションは配列と連想配列だけであるが、.NET Framework の System.Collections 名前空間の各種クラスが利用できる。

下のソースは各種コレクションクラスをインスタンス化する関数を含むモジュールである。

<#
   List
#>

function New-List {
  new-object System.Collections.Generic.List[System.Object]
}

function New-StringList {
  new-object System.Collections.Generic.List[System.String]
}

function New-ArrayList {
  new-object System.Collections.ArrayList
}

function New-BitArray {
  new-object System.Collections.BitArray
}

function New-Hashtable {
  new-object System.Collections.Hashtable
}

function New-Hashtable {
  new-object System.Collections.Hashtable
}

function New-Queue {
  new-object System.Collections.Queue
}

function New-SortedList {
  new-object System.Collections.SortedList
}

function New-SortedSet {
  new-object System.Collections.Generic.SortedSet[System.String]
}

function New-Stack {
  new-object System.Collections.Stack
}

Export-ModuleMember -Function *

テストプログラム

# test List
import-module Commons\list

$list = New-List
$list.Add("abc")
$list.Add("xxabc")
$list.Add("Zabc")

echo $list.Count
foreach ($x in $list) {
  $x
}

$a = "tulip","lily","rose","violet"
$list.AddRange($a)
echo $list.Count
foreach ($x in $list) {
  $x
}

$list[2]

実行例

PS C:\> .\test_list
3
abc
xxabc
Zabc
7
abc
xxabc
Zabc
tulip
lily
rose
violet
Zabc

[Top]

 

 オフィス

Microsoft Excel のブックをアクセスするためのモジュールの例を下に示す。

<#
   Excel object
#>

# Excel ブックから Excel Book を取得する。
#  $filename はフルパス
function GetBook($filename) {
  [reflection.assembly]::LoadWithPartialName("Microsoft.VisualBasic") > $null
  $filename = convert-path $filename
  $book= [Microsoft.VisualBasic.Interaction]::GetObject($filename)
  return $book
}

#  新しい Excel Book を取得する。
#  $filename は省略可能、指定するときはフルパス。
function CreateBook($filename) {
  $global:excel = new-object -comobject Excel.Application
  if ($filename -ne $null) {
    $book = $global:excel.Workbooks.open($filename)
  }
  else {
    $book = $global:excel.Workbooks.Add()
  }
  return $book
}

#  新しいワークシートを追加する。
function AddWorksheet($book) {
  $sheet = $book.Worksheets.Add()
  return $sheet
}

# ワークシートを得る。
function SelectWorksheet($book, $n) {
  return $book.worksheets.item($n)
}

# セルの値を得る。
function GetCell($sheet, $row, $col) {
  return $sheet.cells.item($row, $col)
}

# セルに値をセットする。
function SetCell($sheet, $row, $col, $value) {
  $sheet.cells.item($row, $col) = $value
}

# Excel ブックを保存する。
#   $filename はフルパスであること。
function Save($book, $filename) {
  $book.SaveAs($filename)
}

# Excel を終了させる。
function Quit {
  $global:excel.quit()
}

# すべての関数をエクスポートする。
Export-ModuleMember -Function *

テストプログラム (1)

# test excel.psm1
import-module Commons\excel

$filename = "c:\temp\book1.xlsx"

try {
  $book = createBook
  $sheet1 = selectWorksheet $book 1
  setcell $sheet1 1 1 "XXXX"
  setcell $sheet1 1 2 "XXXY"
  $sheet4 = addWorksheet $book
  setcell $sheet4 1 1 "CCC"
  save $book $filename
  "Saved $filename"
}
finally {
  quit
}

テストプログラム (2)

# test excel.psm1 part2
import-module Commons\excel

$filename = "c:\temp\book1.xlsx"
if ($(test-path $filename) -eq $false) {
  "$filename が見つかりません。"
  exit
}

$book = getBook $filename
$sheet1 = selectWorksheet $book 1
$v = $(getcell $sheet1 1 1)
$v.text
"Done."

テストプログラム (3)

# test excel.psm1 part2
import-module Commons\excel

$filename = "c:\temp\book1.xlsx"

$book = createBook $filename
$sheet1 = selectWorksheet $book 1
$v = $(getcell $sheet1 1 1)
$v.text
"Done."

[Top]

 

 データベース

ADO.NET の機能を利用するとデータベースを使用できます。(注意) コネクタが32ビットバージョンだと64bit PowerShell では動作しないことがあります。

SQL Server

# SQL Server
set-variable -name ConnString -value "Data Source=(localdb)\ProjectsV12;Initial Catalog=AppData;Integrated Security=True;" -o   ption constant
$db = new-object System.Data.SqlClient.SqlConnection($ConnString)
$db.Open > $null
$command = new-object System.Data.SqlClient.SqlCommand
$command.Connection = $db
$command.CommandText = "select * from colors"
$adapter = new-object System.Data.SqlClient.SqlDataAdapter
$adapter.SelectCommand = $command
$dataSet = new-object System.Data.DataSet
$adapter.Fill($dataSet)
$table = $dataSet.Tables[0]
foreach ($row in $table.Rows) {
  write-host $row[0], $row[1]
}
$db.Close > $null

SQL Server Compact Edition

SQL Server Compact Edition のコネクタは System.Data.dll に含まれないので別途ロードしておく必要があります。

# SQL Server Compact Edition
$dll = "C:\Program Files (x86)\Microsoft SQL Server Compact Edition\v4.0\Desktop\System.Data.SqlServerCe.dll"
[System.Reflection.Assembly]::LoadFile($dll) > $null
$connString = "Data Source=$home\Documents\compact.mdf.sdf"
$connString
$ce = new-object System.Data.SQLServerCe.SqlCeConnection($connString)
$cmd = new-object System.Data.SQLServerCe.SqlCeCommand("select * from colors", $ce)
$adapter = new-object System.Data.SQLServerCe.SqlCeDataAdapter($cmd)
$dataSet = new-object System.Data.DataSet
$adapter.Fill($dataSet) > $null
foreach ($row in $dataSet.Tables[0].Rows) {
  write-host $row[0], $row[1], $row[2]
}
$ce.Close()

MS-Access

# MS-Access
#   32bit 版 PowerShell で実行すること。
$connString = "Provider=Microsoft.Jet.OleDb.4.0; Data Source=$home\Documents\sample.mdb"
$connString
$mdb = new-object System.Data.OleDb.OleDbConnection($connString)
$cmd = new-object System.Data.OleDb.OleDbCommand("select * from test1", $mdb)
$adapter = new-object System.Data.OleDb.OleDbDataAdapter($cmd)
$dataSet = new-object System.Data.DataSet
$adapter.Fill($dataSet) > $null
foreach ($row in $dataSet.Tables[0].Rows) {
  write-host $row[0], $row[1], $row[2]
}
$mdb.Close()

SQLite3

SQLite3 の場合は、コネクタが標準でないため事前にロードしておく必要がある。64 bit 版 PowerShell の場合はコネクタも必ず 64bit 版を使用する。

# SQLite3
[System.Reflection.Assembly]::LoadFile("$pwd\System.Data.SQLite.dll")

try {
  $connString = "Data Source=C:\workspace\Misc\PowerShell\database\test.db"
  $sqlite = new-object System.Data.SQLite.SQLiteConnection($connString)
  $sqlite.Open()
  $command = new-object System.Data.SQLite.SQLiteCommand
  $command.CommandText = "select * from test"
  $command.Connection = $sqlite
  $reader = $command.ExecuteReader()
  while ($reader.Read() -eq $true) {
    $name = $reader.GetString(1)
    $code = $reader.GetString(2)
    write-host $name, $code
  }
  $sqlite3.Close
  "Done."
}
catch {
  "例外を検出。"
}

[Top]

 

 ネットワーク

Test-Connection

Test-Connection は ping の代わりに使用できます。

PS C:\> test-connection localhost

Source        Destination     IPV4Address      IPV6Address                              Bytes    Time(ms)
------        -----------     -----------      -----------                              -----    --------
DELL          localhost       127.0.0.1        ::1                                      32       0
DELL          localhost       127.0.0.1        ::1                                      32       0
DELL          localhost       127.0.0.1        ::1                                      32       0
DELL          localhost       127.0.0.1        ::1                                      32       0

Resolve-DnsName

Resolve-DnsName は nslookup の代わりに使用できます。

PS C:\> resolve-dnsname ubuntu14

Name                                           Type   TTL   Section    IPAddress
----                                           ----   ---   -------    ---------
ubuntu14                                       A      86400 Answer     192.168.1.115


PS C:\> resolve-dnsname www.yahoo.co.jp

Name                           Type   TTL   Section    NameHost
----                           ----   ---   -------    --------
www.yahoo.co.jp                CNAME  9     Answer     www.g.yahoo.co.jp

Name       : www.g.yahoo.co.jp
QueryType  : A
TTL        : 9
Section    : Answer
IP4Address : 182.22.63.230

Get-NetIPAddress

Get-NetIPAddress は IP アドレスを取得できます。

PS C:\> Get-NetIPAddress –AddressFamily IPv4 | Select-Object IPAddress

IPAddress
---------
192.168.159.1
169.254.81.167
192.168.37.1
169.254.89.168
169.254.150.205
127.0.0.1
192.168.1.101

Get-NetIPConfiguration

Get-NetIPConfiguration は ネットIP の構成を取得できます。

PS C:\> Get-NetIPConfiguration

InterfaceAlias       : イーサネット
InterfaceIndex       : 4
InterfaceDescription : Realtek PCIe GBE Family Controller
NetProfile.Name      : ネットワーク  2
IPv4Address          : 192.168.1.101
IPv4DefaultGateway   : 192.168.1.1
DNSServer            : 192.168.1.1
(以下略)

Get-NetTCPConnection

Get-NetTCPConnection は netstat の代わりに使用できます。

PS C:\> Get-NetTCPConnection

LocalAddress                        LocalPort RemoteAddress                       RemotePort State       AppliedSetting
------------                        --------- -------------                       ---------- -----       --------------
::1                                 49216     ::                                  0          Listen
::                                  49157     ::                                  0          Listen
::                                  49156     ::                                  0          Listen
::                                  49155     ::                                  0          Listen
::                                  49154     ::                                  0          Listen
(以下略)

Get-NetTCPSetting / Set-NetTCPSetting

Get-NetTCPSetting は TCP の設定を取得できます。Set-NetTCPSetting で変更もできます。

PS C:\> Get-NetTCPSetting

SettingName                   : Automatic
MinRto(ms)                    :
InitialCongestionWindow(MSS)  :
CongestionProvider            :
CwndRestart                   :
DelayedAckTimeout(ms)         :
DelayedAckFrequency           :
(以下略)

[Top]

 

 圧縮ファイル

PowerShell 5.0 から ZIP ファイルの圧縮・解凍がサポートされるそうです。

[Top]

 

 日付と時刻

現在の日付と時刻は Get-Date コマンドレットで取得できます。

PS C:\> get-date

2015年5月13日 13:49:35
PS C:\> get-date -format "yyyy/MM/dd"
2015/05/13

日時を指定した日時オブジェクトを取得することもできる。

PS C:\> $d3 = get-date -date "2014/03/11"
PS C:\> $d3

2014年3月11日 0:00:00

特定の部分だけ取り出すには次のようにする。

PS C:\> $d3.month
3
PS C:\> $d3.year
2014

曜日も取得できる。C:\> $d3.dayofweek

何日前とか何日後とかは get-timespan を使う。

PS C:\> $ts = new-timespan -day 5
PS C:\> $d3 + $ts

2014年3月16日 0:00:00

[Top]

 

 SQL Server

SQL Server を操作するための専用コマンドレット Invoke-Sqlcmd が用意されています。このコマンドレットは名前の通り sqlcmd コマンドを使用するので SSMS などがインストールされている必要があります。

直接コマンドレットの引数に SQL 文を指定するには -Query オプションを使用します。

#  -Query の使用
Invoke-Sqlcmd -ServerInstance localhost -Database User -Query "SELECT * FROM dbo.OMCCARD" | ForEach-Object {
   $($_.Id, $_.Date, $_.Shop, $_.Amount) -join ","
}

SQL ファイルを指定してクエリーを行うには -InputFile オプションを使用します。

#  -Query の使用
Invoke-Sqlcmd -ServerInstance localhost -Database User -InputFile .\query1.sql | ForEach-Object {
  $($_.Id, $_.Date, $_.Shop, $_.Amount) -join ","
}

[Top]

 

 CSV

PowerShell にはカンマ区切りテキストの処理を簡単にするためのコマンドレットが用意されています。Import-CSV コマンドレットは CSV ファイルをインポートします。CSV ファイルの文字コードはデフォルトでは UTF-8 になります。

# CSV ファイルを読む。
Import-CSV -Path $args[0] | Where-Object { $_.Date -gt "20160801" } | ForEach-Object {
  $($_.Id, $_.Shop, $_.Date, $_.Amount) -join "|"
}

Export-CSV というコマンドレットもあります。デフォルトでは ASCII コードで出力されるので、日本語が含まれていると文字化けします。-Encoding オプションを使うとUTF8やSJISに変更できます。SJISは"Default"を指定するとするとよさそうです。区切り文字はデフォルトではカンマですが、-Delimiter で変更できます。

データテーブルのデータをCSVにするとヘッダー行が付きます。また、フィールドは " で囲まれます。出力ファイルに .NET オブジェクトの型名を含めない場合、-notype パラメータを含めます。

# CSV ファイルを書く。
if (Test-Path -Path .\data.csv) {
   Remove-Item -Path .\data.csv   # Export-CSV の -Force オプションを使ってもよい。
}
Invoke-Sqlcmd -ServerInstance localhost -Database User -Query "SELECT Id, Date, Shop,Amount FROM dbo.OMCCARD" | Export-Csv -Path .\data.csv -Delimiter `t -NoType -Encoding Default