| TIPS |
| コマンド |
| コマンド |
説明 |
| Write-Output |
コンソール(またはPowerShell ISE)に出力 |
| Set-Location |
ディレクトリのパスを指定し、ディレクトリを移動する |
| New-Item |
ファイル、フォルダの新規作成[Alias]ni |
| Remove-Item |
削除(del,rm,rmdirに似た機能)、レジストリ削除 |
| Get-Content |
ファイル内容(テキスト)を表示(type,catに似た機能) |
| Invoke-Item |
色々実行(フォルダを開く、関連づけて開く、実行ファイル実行...) |
| Select-String |
ファイルから文字列を検索する(findstr,grepに似た機能) |
| Get-ChildItem |
ディレクトリ情報を取得 |
| Test-Path |
パスのすべての要素が存在するかどうかを確認 |
| Get-Counter |
システムのパフォーマンスを計測 |
| Get-EventLog |
Windows のイベントログを取得 |
| Write-EventLog |
Windows のイベントをログに記録 |
| New-EventLog |
新しいイベントソースを作成 |
| ConvertTo-Json |
オブジェクトを JSON 形式の文字列に変換 |
| ConvertTo-Xml |
オブジェクトの XML ベースの表現を作成 |
| Compress-Archive |
ZIP圧縮 |
| Expand-Archive |
ZIP解凍 |
| New-Object |
Microsoft .NET Framework または COM オブジェクトのインスタンスを作成 VBScriptで言えばCreateObject |
| Get-NetAdapter |
コンピュータのネットアダプタを取得する |
| New-NetIPAddress |
ネットアダプタに静的IPアドレスを設定する |
| Get-NetTCPConnection |
TCPポートのコネクションを確認する |
| Test-NetConnection |
ネットワークの疎通を確認する |
| Get-NetIPConfiiguration |
ネットワークアダプタのIP設定を取得する |
| New-NetRoute |
ネットワークの経路を設定する |
| Get-DNSClientCashe |
リゾルバキャッシュを取得する |
| Get-NetNeighbor |
ネットワークアダプタのARPテーブルを取得 |
| Get-NetConnectionProfile |
ネットワーク状態を取得する |
| Get-NetAdpterAdvancedProperty |
ネットワークアダプターの詳細設定を取得する |
| Start-Process |
|
| CheckPoint-VM |
[Hyper-V]チェックポイントを作成する |
|
|
|
| スクリプト実行設定 |
# ローカルで作成されたスクリプトは無条件で実行できるが、ネットワークから入手したスクリプトは署名が無ければ実行できない
Set-ExecutionPolicy RemoteSigned
# batで起動する例
powershell -NoProfile -ExecutionPolicy Bypass hogehoge.ps1
# batで起動する例2
powershell -ExecutionPolicy RemoteSigned コマンド
|
| スクリプトの文字コードと改行 |
[文字コード] *BOM付きUTF-8がベターかも
SJIS、BOM付きUTF-8、UTF-16
[改行コード]
CR/LF(¥r¥n) *LFだけだと誤動作する
|
| エスケープシーケンス |
エスケープシーケンス
バッククォート(`)を使用する
タブ `t
改行 `r `n
ダブルクォーテーション `"
|
| 引数 |
# ./hogehoge.ps1 -filename xxxx -count xxx を定義(countはデフォルト=100)
param (
[string]$filename,
[int]$count = 100
)
|
| 自動変数 |
| 自動変数 |
説明 |
| $true |
true |
| $false |
false |
| $null |
NULL |
| $$ |
最後に実行したステートメント |
| $? |
最後に実行したステートメントの結果(コマンドレットの結果) |
| $LASTEXITCODE |
最後に実行した外部コマンドの結果(コマンドレットの結果ではない) |
| $PSScriptRoot |
スクリプト自身のパスを表す |
| $IsWindows |
環境がWindowsか |
| IsLinux |
環境がLinuxか |
| IsMacOS |
環境がMacOSか |
|
|
|
| 出力(Write-Output) |
### 単にコンソールに出力するならWrite-Hostでよい。
# コンソール(またはPowerShell ISE)に出力
Write-Output "Hello World in PowerShell!" | Out-Host
# デフォルトに出力
Write-Output "Hello World in PowerShell!" | Out-Default
# 最後に出力された先かデフォルトに出力
Write-Output "Hello World in PowerShell!"
Out-File, Out-GridView,Out-Null,Out-Printer,Out-String
|
| Excel |
$excel = New-Object -ComObject Excel.Application
$book = $excel.Workbooks.Open("C:\hogehoge.xlsx")
# シートの取得
$sheet = $book.Worksheets.Item("Sheet1")
# セル値の取得
$cell_value = $sheet.Cells.Item(1, 2).Value()
$cell_value = $sheet.Range("B2").Value()
# セル数式の取得
$cell_formula_value = $sheet.Cells.Item(1, 2).Formula()
$cell_formula_value = $sheet.Range("B2").Formula()
# 使用している行数
$sheet.UsedRange.Rows.Count
# 使用している列数
$sheet.UsedRange.Columns.Count
# セルに値を設定
$sheet.Cells.Item(1, 2).Value() = $cell_value
# シートループ
foreach ( $sheet2 in $excel.Worksheets ) {
$sheetname = $sheet2.Name
}
# テキストボックス(オートシェイプ)からテキストを取得
for ($idx=1; $idx -le $sheet.Shapes.Count; $idx++){
# Shapes("名称")でも取得できるはず
$text = $sheet.Shapes($idx).TextFrame().Characters().Text
}
# テキストボックスを追加
$sheet.Shapes.AddTextbox(1(msoTextOrientationHorizontal), left, top, width, height).TextFrame().Characters().Text = "テキストボックスに表示"
# 上書きセーブ
[void]$book.Save()
# Bookをとじる
[void]$book.Close($false)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($book)
# Excelの終了
[void]$excel.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
|
| ZIP圧縮 |
# 圧縮
Compress-Archive -Path 圧縮する対象 -DestinationPath ZIPファイル
|
| パス結合とフルパス |
# パス結合 セパレータは自動判別で付与される
$allPath = Join-Path "C:¥" "hogehoge" "filename.ext"
"C:¥hogehoge¥filename.ext"
# フルパス
$path = ".¥filename.ext"
$fullPath = Convert-Path $path
|
| 親フォルダを取得する |
Split-Path -Path $path
|
| ファイル名取得(.NET版) |
$path = "root/path/file.ext"
$filename = [System.IO.Path]::GetFileName($path)
|
| POST |
#
Invoke-RestMethod -Method Post -Uri http://localhost:8080/aaaa -Headers @{'xxx' = 'xxx'} -Body '{"xxx":"xxx"}'
#
$createUrl = "$baseUrl/Server/api-001"
$body = @{
item = "TEST-001"
name = "Test from PowerShell"
} | ConvertTo-Json
$response = Invoke-RestMethod -Uri $createUrl -Method Post -Headers $headers -Body $body
|
| インポート |
# スクリプト自身と同じフォルダのenv.ps1を読み込む
. "$PSScriptRoot\env.ps1"
|
| JSONから読み込む |
# JSONから設定を読み込む
# ファイル内容 { "hostname": "pc-hogehoge" }
# JSONのキー名に-(ハイフン)は使用しない(コマンドレットとして誤認識するから)
$config = ConvertFrom-Json -InputObject (Get-Content $ConfigFilePath -Raw)
$hostName = $config.hostname
|
| テキストファイル読み書き |
$str = "hogehoge"
# 書き込み
Set-Content test.txt $str
# 追記
Add-Content test.txt "追記"
# 読み込み
$read_str = Get-Content test.txt
# 文字コード指定で出力
Set-Content test.txt $str -encoding UTF8 # UTF-8で書き込み
|
| 基本文法 |
# コメント
# if
if ($a -eq 5) {
} elseif($a -gt 5) {
} else {
}
# for
for ($i = 0 ; $i -le 10 ; $i++) {
}
# foreach
$a = @("A", "B", "C")
foreach ($item in $a) {
}
|
| Hyper-Vコマンド |
# HYPER-V のコマンドの一覧を返す
Get-Command -Module hyper-v | Out-GridView
# 仮想マシンの一覧を返す
Get-VM
# 動作中の仮想マシンの一覧
Get-VM | where {$_.State -eq 'Running'}
# 停止の仮想マシンの一覧
Get-VM | where {$_.State -eq 'Off'}
# 起動
Start-VM -Name (仮想マシン名)
# 動作中の仮想マシンを停止する
Get-VM | where {$_.State -eq 'Running'} | Stop-VM
# チェックポイントを作成する
Get-VM -Name (仮想マシン名) | Checkpoint-VM -SnapshotName (チェックポイント名)
|
| 指定フォルダからファイルリスト取得 |
# "C:¥hogehoge"フォルダからファイルの一覧を取得する
$folderFileList = Get-ChildItem -Path "C:¥hogehoge" -File
# 取得したファイルの数だけループする
foreach($item in $folderFileList) {
# ファイル名を表示する
Write-Host $item.Name # .FullName ならフルパス
}
# "C:¥hogehoge¥"フォルダの"*.txt"の一覧を取得する(Includeを指定する場合でRecurseを指定しない場合はPath指定に*が必要らしい)
$folderFileList = Get-ChildItem -Path "C:¥hogehoge¥*" -Include "*.txt"
# "C:¥hogehoge¥"フォルダとサブフォルダの"*.txt"の一覧を取得する
$folderFileList = Get-ChildItem -Path "C:¥hogehoge¥" -Recurse -Include "*.txt"
|
| 環境変数とデスクトップフォルダ |
# 環境変数の一覧
Get-ChildItem -Path env:
# デスクトップフォルダを取得1 環境変数から組み立て
$desctopPath = $Env:HOMEDRIVE + $Env:HOMEPATH + "¥Desktop"
# デスクトップフォルダを取得2 System.Environmentから取得
$desctopPath = [System.Environment]::GetFolderPath("Desktop")
# スクリプト自身のパス
$MyInvocation.MyCommand.Path
|
| いろいろ |
# 年月日(yyyyMMddHHmmss形式)を取得
$yyyyMMddhhmmss = Get-Date -Format "yyyyMMddHHmmss"
# 式の途中で呼び出す
$filename = "ファイル_" + (Get-Date -Format "yyyyMMdd") + ".txt"
|
| 連想配列 |
# 作成
$hash = @{ "A"="AA"; "B"="BB" }
# 要素の取得
$hash["A"]
$hash.A
# ハッシュのループ
# for($entry in $hash.Keys){}
for($entry in $hash.GetEnumerator()){
$entry.Key
$entry.Value
}
|
| Environmentクラス |
# System.Environmentクラスの利用
# メンバーの一覧を表示(staticメンバー)
[System.Environment] | Get-Member -Static
# OSバージョンを表示する
[System.Environment]::OSVersion
|
| Mathクラス |
# System.Mathクラスの利用
# メンバーの一覧を表示(staticメソッド)
[System.Math] | Get-Member -Static -MemberType Methods
# ルート3を計算する
[System.Math]::Sqrt(9)
|
| WebClient |
$webClient = New-Object System.Net.WebClient
$webClient.DownloadString("http://URL/") > url.html
|
| メール送信 |
# メール送信 非推奨なので注意
Send-MailMessage
|
| 終了 |
# スクリプト終了
exit
|
| starz的テンプレート |
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# starz的テンプレート
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# デスクトップ
#$desctopPath = [System.Environment]::GetFolderPath("Desktop")
#-------------------
# 処理ルーチン
#-------------------
Function Execute(){
Param(
[string]$pExcelFile
)
$excel = New-Object -ComObject Excel.Application
$book = $excel.Workbooks.Open("C:\hogehoge.xlsx")
# シートループ
foreach ($sheet in $excel.Worksheets) {
$sheetname = $sheet.Name
Write-Host $sheetname
}
# Bookをとじる
[void]$book.Close($false)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($book)
# Excelの終了
[void]$excel.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
} #Execute
#-------------------
# 起動ルーチン
#-------------------
Function Main {
Param(
[parameter(mandatory=$true)]$param1
)
if ((Test-Path $param1) -eq $False){
Write-Host "ファイルがありません"
exit
}
# 処理起動
Execute $param1
} #Main
# 起動
Main $Args
|
| WinSCPを使ってLinuxサーバのファイルを取得する |
param (
# 引数1: 接続先URI(ユーザー名・パスワードを含む)
# 例: sftp://user:password@192.168.1.100/
[string]$Uri,
# 引数2: Linux上の取得対象ファイル(フルパス)
# 例: /home/test/test.csv
[string]$RemoteFile,
# 引数3: Windows側の保存先(フルパス)
# 例: C:\work\download\test.csv
[string]$LocalFile
)
# WinSCPのコマンドライン版
$WinScp = "C:\Program Files (x86)\WinSCP\WinSCP.com"
# WinSCPでファイルを取得
& $WinScp /command `
"open $Uri" `
"get `"$RemoteFile`" `"$LocalFile`"" `
"exit"
# WinSCPの終了コードをBATへ返す
exit $LASTEXITCODE
|
| DBからデータを取得してExcelに貼る(ClosedXMLを使用) |
param(
[Parameter(Mandatory = $true)]
[string]$Rdbms,
[Parameter(Mandatory = $true)]
[string]$SqlFile,
[Parameter(Mandatory = $true)]
[string]$OutputFile
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
# ============================================================
# 設定 & 設定ファイルの存在チェック
# ============================================================
$BaseDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$configFile = Join-Path $BaseDir "config\$Rdbms.conf"
$closedXmlDll = Join-Path $BaseDir "lib\ClosedXML.dll"
if (-not (Test-Path $configFile)) {
throw "接続設定ファイルが存在しません: $configFile"
}
if (-not (Test-Path $SqlFile)) {
throw "SQLファイルが存在しません: $SqlFile"
}
if (-not (Test-Path $closedXmlDll)) {
throw "ClosedXML.dllが存在しません: $closedXmlDll"
}
# ============================================================
# ClosedXML読み込み
# ============================================================
Add-Type -Path $closedXmlDll
# ============================================================
# 設定ファイル読み込み
#
# 形式:
# Server=localhost
# Database=TESTDB
# UserId=testuser
# Password=testpassword
# ============================================================
$config = @{}
foreach ($line in Get-Content $configFile -Encoding UTF8) {
$line = $line.Trim()
# 空行・コメント行は無視
if ([string]::IsNullOrWhiteSpace($line)) {
continue
}
if ($line.StartsWith("#")) {
continue
}
$parts = $line.Split("=", 2)
if ($parts.Count -ne 2) {
continue
}
$key = $parts[0].Trim()
$value = $parts[1].Trim()
$config[$key] = $value
}
# ============================================================
# 接続文字列作成
# ============================================================
$requiredKeys = @(
"Server",
"Database"
)
foreach ($key in $requiredKeys) {
if (-not $config.ContainsKey($key)) {
throw "設定ファイルに '$key' がありません: $configFile"
}
}
$connectionStringBuilder =
New-Object System.Data.SqlClient.SqlConnectionStringBuilder
$connectionStringBuilder["Data Source"] = $config["Server"]
$connectionStringBuilder["Initial Catalog"] = $config["Database"]
if ($config.ContainsKey("UserId") -and
$config.ContainsKey("Password")) {
$connectionStringBuilder["User ID"] = $config["UserId"]
$connectionStringBuilder["Password"] = $config["Password"]
}
else {
# UserId / PasswordがなければWindows認証
$connectionStringBuilder["Integrated Security"] = $true
}
$connectionString = $connectionStringBuilder.ConnectionString
# ============================================================
# SQLファイル読み込み
# ============================================================
$sqlText = Get-Content $SqlFile -Raw -Encoding UTF8
# ============================================================
# SQLを分割
#
# -- [シート名]
# SELECT ...
#
# -- [シート名]
# SELECT ...
# ============================================================
$pattern = '(?ms)^\s*--\s*\[(.+?)\]\s*\r?\n(.*?)(?=^\s*--\s*\[.+?\]\s*$|\z)'
$matches = [regex]::Matches($sqlText, $pattern)
if ($matches.Count -eq 0) {
throw "SQLファイルに '-- [シート名]' 形式のSQLがありません。"
}
# ============================================================
# Excel作成
# ============================================================
$workbook = New-Object ClosedXML.Excel.XLWorkbook
try {
foreach ($match in $matches) {
$sheetName = $match.Groups[1].Value.Trim()
$sql = $match.Groups[2].Value.Trim()
if ([string]::IsNullOrWhiteSpace($sheetName)) {
continue
}
if ([string]::IsNullOrWhiteSpace($sql)) {
continue
}
Write-Host "SQL実行: [$sheetName]"
# ------------------------------------------------------
# シート名の長さ・使用禁止文字チェック
# ------------------------------------------------------
if ($sheetName.Length -gt 31) {
throw "シート名が31文字を超えています: $sheetName"
}
if ($sheetName -match '[\\\/\?\*\[\]\:]') {
throw "シート名に使用できない文字があります: $sheetName"
}
# ------------------------------------------------------
# SQL実行
# ------------------------------------------------------
$connection = New-Object System.Data.SqlClient.SqlConnection
$connection.ConnectionString = $connectionString
try {
$connection.Open()
$command = $connection.CreateCommand()
$command.CommandText = $sql
$command.CommandTimeout = 0
$adapter =
New-Object System.Data.SqlClient.SqlDataAdapter($command)
$table = New-Object System.Data.DataTable
[void]$adapter.Fill($table)
}
finally {
if ($connection.State -ne
[System.Data.ConnectionState]::Closed) {
$connection.Close()
}
$connection.Dispose()
}
Write-Host " 件数: $($table.Rows.Count)"
# ------------------------------------------------------
# シート作成
# ------------------------------------------------------
$sheet = $workbook.Worksheets.Add($sheetName)
$columnCount = $table.Columns.Count
# ------------------------------------------------------
# ヘッダ
# ------------------------------------------------------
for ($col = 0; $col -lt $columnCount; $col++) {
$cell = $sheet.Cell(1, $col + 1)
$cell.SetValue(
[string]$table.Columns[$col].ColumnName
)
$cell.Style.Font.Bold = $true
$cell.Style.Fill.BackgroundColor =
[ClosedXML.Excel.XLColor]::LightBlue
$cell.Style.Alignment.Horizontal =
[ClosedXML.Excel.XLAlignmentHorizontalValues]::Center
}
# ------------------------------------------------------
# データ
# DBの型をExcelへ持ち込まず、すべて文字列として設定する
# ------------------------------------------------------
for ($row = 0; $row -lt $table.Rows.Count; $row++) {
for ($col = 0; $col -lt $columnCount; $col++) {
$value = $table.Rows[$row][$col]
if ($value -eq [DBNull]::Value) {
$text = ""
} else {
$text = [string]$value
}
$cell = $sheet.Cell(
$row + 2,
$col + 1
)
# 文字列として設定
$cell.SetValue($text)
# Excel側も文字列として扱わせる
$cell.Style.NumberFormat.Format = "@"
}
}
# ------------------------------------------------------
# 罫線
# ------------------------------------------------------
$lastRow = [Math]::Max(
1,
$table.Rows.Count + 1
)
if ($columnCount -gt 0) {
$range = $sheet.Range(
1,
1,
$lastRow,
$columnCount
)
$range.Style.Border.OutsideBorder =
[ClosedXML.Excel.XLBorderStyleValues]::Thin
$range.Style.Border.InsideBorder =
[ClosedXML.Excel.XLBorderStyleValues]::Thin
}
# ------------------------------------------------------
# 列幅自動調整
# ------------------------------------------------------
if ($columnCount -gt 0) {
$sheet.Columns().AdjustToContents()
# 極端に幅が広くなることを防止
foreach ($column in $sheet.Columns()) {
if ($column.Width -gt 50) {
$column.Width = 50
}
}
}
# ------------------------------------------------------
# 1行目固定
# ------------------------------------------------------
$sheet.SheetView.FreezeRows(1)
}
# ========================================================
# Excel保存
# ========================================================
$outputFullPath = [System.IO.Path]::GetFullPath($OutputFile)
Write-Host ""
Write-Host "Excel出力: $outputFullPath"
$workbook.SaveAs($outputFullPath)
}
finally {
$workbook.Dispose()
}
Write-Host ""
Write-Host "完了しました。"
|