2017-09-12 3 views
0

現在、私のログ機能は情報を単一の列に吐き出し、読みにくいです。各(DisplayName、PoolName、PoolSnapshot、DesktopSVIVmSnapshot)とそれぞれの情報が正しく配置されている別々の列に分割する方法はありますか?PowerShellログ機能の可読性

function log ([string]$entry) { 
    Write-Output $entry | Out-File -Append "C:\logs\SNAPSHOT.csv" 
} 

Add-PSSnapin Quest.ActiveRoles.ADManagement 

$date = Get-Date -Format "MM-dd-yyyy" 
$time = Get-Date -Format "hh:mm:sstt" 

# begin log 
log $(Get-Date) 
log "The below Desktops are not using the correct Snapshot." 

if (@($DesktopExceptions).Count -lt 1) { 
    Write-Output "All desktops in $pool are currently using the correct snapshots." | 
     Out-File -Append "C:\logs\SNAPSHOT.csv" 
} else { 
    Write-Output $DesktopExceptions | 
     Select-Object DisplayName,PoolName,PoolSnapshot,DesktopSVIVmSnapshot | 
     sort DisplayName | 
     Out-File -Append "C:\logs\SNAPSHOT.csv" 
} 

log $(Get-Date) 
 
09/11/2017 12:16:17 

DisplayName PoolName  PoolSnapshot       DesktopSVIVmSnapshot 
----------- --------  ------------       -------------------- 
xxxc-13v  xxxc-xxx  /8-11-2017/09-07-2017     /8-11-2017 
xxxc-15v  xxxc-xxx  /8-11-2017/09-07-2017     /8-11-2017 
xxxc-1v  xxxc-xxx  /8-11-2017/09-07-2017     /8-11-2017 
xxxc-20v  xxxc-xxx  /8-11-2017/09-07-2017     /8-11-2017 

注:私はポストに長いをしないために期待してのログの一部を削除しました。

答えて

0

オブジェクトを作成していて、デフォルトのPowerShellフォーマッタの動作を行っているようです。

あなたのログは、メッセージをファイルに書き込むこと(書式なし)のみを担当することをお勧めします。ここでは、試すかもしれないものの例です:

function Write-LogMessage { 
    [CmdletBinding()] 
    param (
     [Parameter(Mandatory = $true, HelpMessage = "The text-content to write to the log file.", 
      ValueFromPipeline = $true)] 
     [string]$Text 
    ) 

    Process { 
     Write-Host -ForegroundColor Green $Text 
    } 
} 
Set-Alias log Write-LogMessage 

注:この例では、PowerShellコンソールに直接書き込みをしていますが、実際にはOut-Fileまたはリダイレクト演算子のいずれかを使用して(ファイルに出力を指示する必要があります - Get-Help about_Operators参照)。

それを使用するには、あなたがこのような何か書くでしょう:あなたの具体的な例について

"This is a message that would be written" | Write-LogMessage 

を、あなたはそれをメッセージをインラインでフォーマットして、パイプができます

Write-Output $DesktopExceptions | Select-Object DisplayName,PoolName,PoolSnapshot,DesktopSVIVmSnapshot | sort DisplayName | ForEach-Object { "{0}: Host = {1}, Pool = {2}, Pool SN = {3}, SVIV Snapshot = {4}" -f (Get-Date), $_.DisplayName, $_.PoolName, $_.PoolSnapshot, $_.DesktopSVIVmSnapshot } | log 

。なお、ログステートメントは必要ありません。Out-Fileコマンドレットにパイプする前に書式を追加するだけで、後で処理することができます。

編集: OPは元の投稿で列の書式設定(表形式出力)を求められました。これを実現するには、ConvertTo-CsvまたはExport-Csvコマンドレットのいずれかを使用できます(通常、出力の最初の行が型定義でないように、これらのコマンドには-NoTypeInformationスイッチパラメータを使用します)。この例は次のとおりです。

$DesktopExceptions | Select-Object DisplayName,PoolName,PoolSnapshot,DesktopSVIVmSnapshot | sort DisplayName | Export-Csv C:\Temp\Datum.csv -NoTypeInformation 

としては、そうでない場合は、ファイルのリダイレクト、リダイレクト演算子を使用して(指示されない限り、PowerShellは自動的に出力ストリームにすべての出力を書き込むためWrite-Outputは、必要とされていない使用して、別の答えで指摘し、またはOut-Nullコマンドレット)。

1

CSVファイルには、列名を含むヘッダー行と列値を含むデータ行が必要です。

の出力を最初に - 1つの日付/時刻文字列に続けて別の単一文字列出力を続け、$DesktopExceptions | Select-Object ...呼び出しから複数列出力を続けて書くと、有効なCSVファイルが作成されません。

あなたはまだそのようなファイルを作成したい場合は

log (Get-Date) # With a single command, you don't need $(...) - (...) will do. 
log "The below Desktops are not using the correct Snapshot." 

If ($DesktopExceptions) # a non-empty array/non-$null object 
{ 
    log ($DesktopExceptions | 
    Select-Object DisplayName,PoolName,PoolSnapshot,DesktopSVIVmSnapshot | 
    Sort-Object DisplayName | 
     ConvertTo-Csv -NoTypeInformation) 
} 
Else 
{ 
    log "All desktops in $pool are currently using the correct snapshots." 
} 

log (Get-Date) 
  • タイプ[string]としてあなたlog()関数のパラメータを定義することにより、あなたは効果的にあなたがそれに渡すどんなオブジェクトの文字列化を強制しています。この文字列化は、可変参照またはコマンドを"..."(文字列展開/補間)内に埋め込んだときと同じですが、ではなくであり、コンソールに印刷するときと同じものです。対照的に、は、CSVは、例えば、あるとして、しかし、人間消費のためではなく、マシンの構文解析のためのフォーマットで、コンソール、(に印刷するときに、あなたが得る同じ出力で結果をし

  • Out-File、 )。

  • CSV形式の出力を取得するには、Export-Csv - ファイルに直接書き込むか、ConvertTo-Csvを使用して文字列表現を取得する必要があります。

  • はまた、明示的にWrite-Outputを使用する理由は、一般的にありませんのでご注意 - 明示的に(ファイルまたは$nullに)リダイレクト変数/に割り当てられていない任意のコマンド/式の出力は、PowerShellのの[成功]出力に送ら暗黙的ですストリーム;たとえばWrite-Output Get-DateはちょうどGet-Dateと同じです。

0

私の答えは、一部解決策と部品のアドバイスとしてお読みください。

PowerShellの「問題」は、コードの出力だけをキャプチャしないことです。他のスクリプト、モジュール、実行可能ファイルからの出力をキャプチャします。言い換えれば、ロギングを試みるどんな試みも、例えばNLOGのC#には、固有の問題があります。

私はビルドしている複雑な継続的な配送パイプラインのために、この件について自分自身を調べました。私は、構造化ログが100%可能ではないことを理解し、PowerShellの転写(Start-Transcript)の目的を受け入れました。しかし、私はWrite-Logのような関数を作成しないようにしたいと考えていました。可能であれば、Write-DebugWrite-Verboseの機能を使用するすべてのコードの出力を強化しました。

私はXWrite PowerShellモジュールを作成しました。このモジュールは、自分自身でもうまく動作します。呼び出し元の名前(コマンドレットまたはスクリプト)とタイムスタンプによって生成されたトレースメッセージを拡張するため、このメソッドを使用します。呼び出し元の名前は、トラブルシューティングと、私が暗黙的にベンチマークするために使用するタイムスタンプで多く役立ちます。テスト-MyXWrite.ps1:ここ

DEBUG例のカップルですこんにちは

DEBUG:スクリプト:テスト-MyXWrite.ps1:20170804:10:57:27.845:こんにちは

しかし、いくつかの制限があります。バイナリのコードトレース出力は強化されません。また、cmlletが完全な名前空間を使用してWrite-*を明示的に参照する場合は、動作しません。行ごとにキャプチャするためには、すべてのトレースと出力には、.netタイプのPowerShell実装フックが必要です。これを行った人がいますが、私はPowerShellプロセスの動作を積極的に影響させたくありません。そして、この瞬間、私はそれが転写の役割であると信じています。あなたのアイデアのような場合は、いくつかの点でXWrite

からモジュールをインストール

、私はサービスをテレメトリためにリダイレクトしてモジュールを拡張したいと思いますが、私はまだ私はそれをやってみたいことを決めていませんでした、私は上記の例外と他の実行可能ファイルをキャプチャしないためです。スクリプトが実行されている間、私は目に見える進歩を提供するだけです。

関連する問題