当スクリプトの目的
作業エビデンス取得の効率化などで、キャプチャを一定間隔で取っておきたいということがあると思います。そのためにWinShotなどの画面キャプチャソフトがありますが、現場によっては勝手にexeを使うと怒られることがあります。そういう現場でも、Windows PowerShellは入っているので、それを使えば似たことができます。今回は、そのニッチなニーズのためのスクリプトです。結局、仕事では使わなかったので公開します。
シンプルなやり方
プリントスクリーンのキーを送って、画像保存するというだけなら、以下のようなスクリプトで大丈夫でしょう。キーを送ってから1秒待っています。これをps1ファイルとして保存して、右クリックでパワーシェルとして実行すれば同フォルダにキャプチャ画像ができていきます。
Add-Type -AssemblyName System.Windows.Forms
[Console]::WindowWidth = 50
while ($true) {
Write-Host "Capturing screenshot at $((Get-Date).ToString('yyyy-MM-dd HH:mm:ss'))..."
[System.Windows.Forms.SendKeys]::SendWait("{PRTSC}")
Start-Sleep -Seconds 1
$image = [System.Windows.Forms.Clipboard]::GetImage()
$filename = "screenshot_$((Get-Date).ToString('yyyyMMdd_HHmmss')).png"
$image.Save($filename, [System.Drawing.Imaging.ImageFormat]::Png)
Write-Host "Screenshot saved as $filename"
Start-Sleep -Seconds 4
}
ただ、マルチディスプレイを使っている環境では、全てのスクリーンが取得されてしまうため、少し不十分です。
マルチディスプレイ対応版
以下は、ディスプレイ番号を指定して、そのディスプレイ分のみ取得するスクリプトです。最近の高解像度ディスプレイでは座標指定がズレてしまうことがありますので、その対応を含んでいます。ScaleFactorを変数にして、1.5などに書き換えれば正しい領域が取得できます。
Add-Type -AssemblyName System.Windows.Forms
[Console]::WindowWidth = 100
#### Please specify 3 parameters.
$waitSecond = 4 #Specify the wait time.
$screenNo = 0 #If multiple displays are connected, specify the number.
$scaleFactor = 1 #Set the scale factor for a high DPI display.
Write-Host "Capture interval is $waitSecond seconds (+ image processing time)."
$screens = [System.Windows.Forms.Screen]::AllScreens
$chosenScreen = $screens[$screenNo]
Write-Host "Screen $screenNo is chosen."
$screenLines = $chosenScreen -split " "
$screenLines = $screenLines -join "`n"
Write-Host $screenLines
if ($scaleFactor -gt 1) {
Write-Host "High-resolution display: Using scaled bounds."
$bounds = $chosenScreen.Bounds
$bounds.Width = [int]($bounds.Width * $scaleFactor)
$bounds.Height = [int]($bounds.Height * $scaleFactor)
$bounds.X = [int]($bounds.X * $scaleFactor)
$bounds.Y = [int]($bounds.Y * $scaleFactor)
} else {
Write-Host "Regular display detected: Using regular bounds."
$bounds = $chosenScreen.Bounds
}
Write-Host "Bounds*Scalse=$bounds"
while ($true) {
Write-Host "Capturing screenshot at $((Get-Date).ToString('yyyy-MM-dd HH:mm:ss'))..."
$bitmap = New-Object System.Drawing.Bitmap $bounds.Width, $bounds.Height
$graphics = [System.Drawing.Graphics]::FromImage($bitmap)
$graphics.CopyFromScreen($bounds.Location, [System.Drawing.Point]::Empty, $bounds.Size)
$filename = "screenshot_$((Get-Date).ToString('yyyyMMdd_HHmmss')).png"
$bitmap.Save($filename, [System.Drawing.Imaging.ImageFormat]::Png)
Write-Host "Screenshot saved as $filename"
Start-Sleep -Seconds $waitSecond
}
これで、閉ざされた世界(スタンドアローンテスト環境)でもあなたが生きた証(テストエビデンス)を遺すことができます。まあ、実際には他の縛りで使えませんでした。
GitHubにも置いておきました。
https://github.com/KentAnak/ScreenCaptureScript