PowerShellでのレポート

テキスト出力、報告、メール送信の問題が考慮されます。 コードスニペットを何度も使用したり、不足しているスニペットを追加したり、より長いレポートを収集したりできるように、レポートの作成方法に関するヒントが提供されています。

PowerShellを使用して情報を収集するか、それを効果的に使用する方法を学習したい人にとって、間違いなく必要です。



報告の秘密33



この章には

  1. HTMLフラグメントを使用する
  2. スタイリッシュなHTMLレポートを作成する
  3. メールレポート




この章では、レポートを作成するためのPowerShellテクニックについて説明します。 文字列を操作する必要がある場合、PowerShellは機能しません。このためにオブジェクトを使用してみてください。 レポートの作成時にオブジェクトを使用するほど、処理を改善できます。



33.1何をする必要がないか。

この章は、貧弱な報告手法の例であると考えるものから始めます。 私たちは常にこのスタイルを満たしています。 ほとんどのITプロフェッショナルはそれについて考えず、VBScriptなどの他の言語のコードを永続化します。

次のコードは、あなたが適用しないことを願うスタイルで書かれており、あまり知られていないシステム管理者のためにコードで見ることができます。



リスト33.1適切に設計されていないインベントリスクリプト

param ($computername) Write-Host '------- COMPUTER INFORMATION -------' Write-Host "Computer Name: $computername" $os = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $computername Write-Host " OS Version: $($os.version)" Write-Host " OS Build: $($os.buildnumber)" Write-Host " Service Pack: $($os.servicepackmajorversion)" $cs = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $computername Write-Host " RAM: $($cs.totalphysicalmemory)" Write-Host " Manufacturer: $($cs.manufacturer)" Write-Host " Model: $($cd.model)" Write-Host " Processors: $($cs.numberofprocessors)" $bios = Get-WmiObject -Class Win32_BIOS -ComputerName $computername Write-Host "BIOS Serial: $($bios.serialnumber)" Write-Host '' Write-Host '------- DISK INFORMATION -------' Get-WmiObject -Class Win32_LogicalDisk -Comp $computername –Filt 'drivetype=3' | Select-Object @{n='Drive';e={$_.DeviceID}}, @{n='Size(GB)';e={$_.Size / 1GB -as [int]}}, @{n='FreeSpace(GB)';e={$_.freespace / 1GB -as [int]}} | Format-Table –AutoSize
      
      





リスト33.1のコードは、これに似た出力を生成します。

画像

図33.1行ベースの出力。



どうやらこのスクリプトが機能するように、ドンジョーンズ(著者の1人)は、スクリプトからの出力を明確な行で見て、神と子犬(おそらく元のドンの呪いには、彼がスクリプトを見るたびに発言する怒りの神と子犬がいる)このような純粋なテキストを出力します)。 まず、このスクリプトは画面にのみ表示できます。 出力はWrite-Hostを介して行われます。 ほとんどの場合、 Write-Hostを使用すると、間違ってしまいます。 この情報をファイルまたはHTMLに出力できたらいいと思いますか? すべてのWrite-HostWrite-Outputに変更することでこれを実現できますが、これは依然として間違った方法です。



レポートを生成するより効率的な方法があり、これがこの章を書いた理由です。 まず、情報が生成される各ブロックまたは関数に対して、必要なすべての情報を含む1つのオブジェクトを作成することをお勧めします。 コードをブロックに分割するほど、これらのブロックを再利用できます。 悪い例では、最初のセクション「コンピューター情報」は、作成する関数によって実行される必要があります。 この種のすべてのレポートで使用できます。 「ディスク情報」セクションでは、データは単一のオブジェクトによって示されます。異なるソースからの情報を結合する必要はありませんが、すべてのWriteコマンドレットは削除する必要があります。 (翻訳者のメモ。これを行う方法については、セクション33.2.1ソース情報の取得の例を参照してください)



各ルールの例外

各ルールには例外があります。 リチャードシドウェイは、他の人のシステムの監査に多くの時間を費やしています。 これにより、これがスクリプトの標準セットになります。 スクリプトは出力を生成するように設計されており、出力は直接Word文書に送信されるか、ファイルが生成されて文書に挿入されます。 したがって、初期データを非常に迅速に取得して表示できるため、分析と議論が遅れることはありません。



これらのシナリオで違反するルールは次のとおりです

  1. 出力は、テキストとオブジェクトの混合です。
  2. 出力はすぐにフォーマットされます


スクリプトの適用方法とレポートの表示方法がわかっているため、これは意図的な決定です。 この物語の教訓は、オブジェクトを導き出し、理由がある場合はパラダイムを超えて準備ができていることです。



33.2 HTMLスニペットとファイルの使用

この方法の秘Theは、ConvertTo-HTMLを2つの異なる方法で使用できることです。 最初の方法は完全なHTMLページを作成することであり、2番目の方法はHTMLフラグメントを作成することです。 このフラグメントは、コマンドレットに転送されたデータを含む単なるHTMLテーブルです。レポートの各セクションをフラグメントとして作成し、フラグメントを完全なHTMLページに収集します。



33.2.1初期情報の取得

データをオブジェクトに収集することから始めます。レポートの各セクションに1つのオブジェクトがあります。 この場合、2つのオブジェクトがあります-コンピューターに関する情報とディスクに関する情報です。 柔和で明快にするために、エラー処理やその他の微妙な点はスキップすることに同意します。 実際の条件では、それらを追加します。 Get-WMIObject自体は、ディスク情報を含むオブジェクトを生成します。 したがって、コンピューターに関する情報を含むオブジェクトを発行する関数を作成する必要があります。



 function Get-CSInfo { param($computername) $os = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $computername $cs = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $computername $bios = Get-WmiObject -Class Win32_BIOS -ComputerName $computername #property names with spaces need to be enclosed in quotes $props = @{ComputerName = $computername 'OS Version' = $os.version 'OS Build' = $os.buildnumber 'Service Pack' = $os.sevicepackmajorversion RAM = $cs.totalphysicalmemory Processors = $cs.numberofprocessors 'BIOS Serial' = $bios.serialnumber} $obj = New-Object -TypeName PSObject -Property $props Write-Output $obj }
      
      





この関数は、3つの異なるWMIクラスから情報を取得します。 関数の出力をパイプラインに渡したいため、3つのオブジェクトから組み立てられたハッシュテーブルを使用してオブジェクトを作成します。 通常、スペースを含まないプロパティ名を指定しますが、最終レポートでは名前を使用するため、この規則から逸脱しています。



33.2.2 HTMLレポートのフラグメントの作成。



書かれた関数を使用して、HTMLでレポートを取得できます。



 $frag1 = Get-CSInfo –computername SERVER2 | ConvertTo-Html -As LIST -Fragment –PreContent '<h2>Computer Info</h2>' | Out-String
      
      





私たちは長い間このトリックに移ったので、分解する必要があります。

1.出力をHTMLフラグメントの形式で$ frag1という名前の変数に保存します。後で、出力を目的の出力場所に挿入するか、全体を保存できます。

2. Get-CSInfoが起動し 、データを受信するコンピューターの名前を受信します。コンピューター名をハードに書き込み、将来的には変数に置き換えます。

3.結果の出力はConvertTo-HTMLに送信さます 。このコマンドは、出力でHTMLフラグメントを水平ではなく垂直リストの形式で生成します。 このリストは、 使用できない出力情報技術に関する古いレポートの外観をシミュレートします

4. –PreContentパラメーターを使用して、レポートプレートの前に碑文を追加します。 タグを追加して、太字のタイトルを取得しました。

5.起こったことすべて-これはトリックです-はOut-Stringに渡されます。 ConvertTo-HTMLがパイプラインに多くのものを配置することがわかります 。 行、行のコレクション、他のあらゆる種類のオブジェクトがパイプラインに書き込まれていることがわかります。 これらはすべて、最終的なHTMLページにすべてを配置しようとすると、最後に問題につながります。代わりに、Out-Stringをファイルして、古き良き文字列を取得しました。



さらに進んで、2番目のフラグメントを作成できます。 簡単だから 関数を記述する必要はありません。HTML生成はまったく同じに見えます。 唯一の違いは、リストではなくテーブルのこのセクションからデータを収集することです。



 $frag2 = Get-WmiObject -Class Win32_LogicalDisk -Filter 'DriveType=3' -ComputerName SERVER2 | Select-Object @{name='Drive';expression={$_.DeviceID}}, @{name='Size(GB)';expression={$_.Size / 1GB -as [int]}}, @{name='FreeSpace(GB)';expression={ $_.freespace / 1GB -as [int]}} | ConvertTo-Html -Fragment -PreContent '<h2>Disk Info</h2>' | Out-String
      
      





両方のフラグメントがあり、最終レポートの作成を開始できます。



33.2.3最終的なHTMLファイルの組み立て

ビルドには、2つのフラグメントとスタイルシートの追加が含まれます。 CSSスタイルシートと言語の使用は、この本の範囲外です。 スタイルシートを使用すると、HTMLページの書式を制御して、見栄えを良くすることができます。 優れたチュートリアルと追加のCSS素材へのリンクが必要な場合は、http://www.w3schools.com/css/をご覧ください。



 $head = @' <style> body { background-color:#dddddd; font-family:Tahoma; font-size:12pt; } td, th { border:1px solid black; border-collapse:collapse; } th { color:white; background-color:black; } table, tr, td, th { padding: 2px; margin: 0px } table { margin-left:50px; } </style> '@ ConvertTo-HTML -head $head -PostContent $frag1, $frag2 -PreContent "<h1>Hardware Inventory for SERVER2</h1>"
      
      





$ headスタイルシートが作成され、文字列型変数に目的のスタイルが記述されます。 次に、この変数が–headパラメーターに渡され、フラグメントが–PostContentパラメーターにコンマ付きでリストされます。 レポートのタイトルが–PreContentパラメーターに追加されます。 スクリプト全体をC:\ Good.ps1として保存し、次のように実行します。

./good> Report.htm

これにより、図33.2のように、出力がReport.htmファイルにリダイレクトされ、 きれいになります。



画像

図33.2いくつかのフラグメントからのレポート



これは芸術作品ではないかもしれませんが、この章を始めたスクリーン上のレポートよりも見栄えの良いレポートです。 リスト33.2は、コンピューター名(デフォルトではlocalhost)を設定できるカーテン付きスクリプトを示しています。 ヘッダーは[CmdletBinding()]で、 –verboseを使用できますWrite-Verboseがスクリプトの本文に挿入されているため、各ステップの実行内容を確認できます。



リスト33.2 HTMLインベントリスクリプト

 <# .DESCRIPTION Retrieves inventory information and produces HTML .EXAMPLE ./Good > Report.htm .PARAMETER The name of a computer to query. The default is the local computer. #> [CmdletBinding()] param([string]$computername=$env:computername) # function to get computer system info function Get-CSInfo { param($computername) $os = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $computername $cs = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $computername $bios = Get-WmiObject -Class Win32_BIOS -ComputerName $computername $props = @{'ComputerName'=$computername 'OS Version'=$os.version 'OS Build'=$os.buildnumber 'Service Pack'=$os.servicepackmajorversion 'RAM'=$cs.totalphysicalmemory 'Processors'=$cs.numberofprocessors 'BIOS Serial'=$bios.serialnumber} $obj = New-Object -TypeName PSObject -Property $props Write-Output $obj } Write-Verbose 'Producing computer system info fragment' $frag1 = Get-CSInfo -computername $computername | ConvertTo-Html -As LIST -Fragment -PreContent '<h2>Computer Info</h2>' | Out-String Write-Verbose 'Producing disk info fragment' $frag2 = Get-WmiObject -Class Win32_LogicalDisk -Filter 'DriveType=3' -ComputerName $computername | Select-Object @{name='Drive';expression={$_.DeviceID}}, @{name='Size(GB)';expression={$_.Size / 1GB -as [int]}}, @{name='FreeSpace(GB)';expression={$_.freespace / 1GB -as [int]}} | ConvertTo-Html -Fragment -PreContent '<h2>Disk Info</h2>' | Out-String Write-Verbose 'Defining CSS' $head = @' <style> body { background-color:#dddddd; font-family:Tahoma; font-size:12pt; } td, th { border:1px solid black; border-collapse:collapse; } th { color:white; background-color:black; } table, tr, td, th { padding: 2px; margin: 0px } table { margin-left:50px; } </style> '@ Write-Verbose 'Producing final HTML' Write-Verbose 'Pipe this output to a file to save it' ConvertTo-HTML -head $head -PostContent $frag1,$frag2 -PreContent "<h1>Hardware Inventory for $ComputerName</h1>"
      
      







スクリプトの使用

 PS C:\> $computer = SERVER01 PS C:\> C:\Scripts\good.ps1 -computername $computer | >> Out-File "$computer.html" >> PS C:\> Invoke-Item "$computer.html"
      
      





このスクリプトは、将来使用できるHTMLファイルを生成し、レポートを表示します。 Get-CSInfo関数は再利用できることに注意してください。 テキストではなくオブジェクトが表示されるため、同じ情報を表示する必要があるさまざまな場所で使用できます。

レポートにさらに情報を追加する必要がある場合、新しいセクションを追加するには次が必要です。



はい、このレポートはテキストです。 テキストは私たちが読むものであるため、最終的に、各レポートはテキストになります。 このメソッドの本質は、最後の瞬間まですべてがオブジェクトのままであるということです。 PowerShell形式を使用できます。 このスクリプトの作業要素はコピーして他の場所で使用できますが、章の冒頭のソーステキストを使用して行うことはできません。



33.3メールの送信

HTMLレポートよりも優れているものは何でしょうか? 電子メールで自動的に届くレポート!



PowerShellパーツには、既にSend-MailMessageコマンドレットが含まれています。 スクリプトを少し修正しましょう。

 Write-Verbose 'Producing final HTML' Write-Verbose 'Pipe this output to a file to save it' ConvertTo-HTML -head $head -PostContent $frag1,$frag2 -PreContent "<h1>Hardware Inventory for $ComputerName</h1>" | Out-File report.htm Write-Verbose "Sending e-mail" $params = @{'To'='whomitmayconcern@company.com' 'From'='admin@company.com' 'Subject'='That report you wanted' 'Body'='Please see the attachment.' 'Attachments'='report.htm' 'SMTPServer'='mail.company.com'} Send-MailMessage @params
      
      





出力をファイルにリダイレクトすることにより、パイプラインの終わりを変更しました。 次に、 Send-MailMessageを添付ファイルとして使用しました。 メッセージの本文としてHTMLを送信できます。 このためにディスク上にファイルを作成する必要はありません。パイプラインから直接出力を取得できます。 別の例を次に示します。

 Write-Verbose 'Producing final HTML' $body = ConvertTo-HTML -head $head -PostContent $frag1,$frag2 -PreContent "<h1>Hardware Inventory for $ComputerName</h1>" | Out-String Write-Verbose "Sending e-mail" $params = @{'To'='whomitmayconcern@company.com' 'From'='admin@company.com' 'Subject'='That report you wanted' 'Body'=$Body 'BodyAsHTML'=$True 'SMTPServer'='mail.company.com'} Send-MailMessage @params
      
      





ここでは、 Send-MailMessageパラメーターをハッシュテーブルに作成し、 $ Param変数に保存しました。 これにより、 スプラット手法を使用して、すべてのパラメーターを一度にチームに提供できます。 パラメーターとして入力したり、ハッシュテーブルで指定したりしても違いはありませんが、とにかく動作しますが、それを読む方が良いでしょう。



33.4まとめ

管理者にとってレポートは確かに大きなニーズです。PowerShellがこのタスクに適していることを示したかったのです。 秘Theは、情報の抽出がフォーマットや出力の作成から分離されるような方法でレポートを作成することです。 実際、PowerShellは、わずかな作業で優れた書式設定機能と出力機能を提供できます。



Z.Y. 翻訳者から

使用する必要があるロシア語のテキストを正しく表示するには

 $encoding = [System.Text.Encoding]::UTF8 Send-MailMessage @params -Encoding $encoding
      
      






All Articles