我有帶有日志記錄功能的基本 PowerShell 腳本和一些要運行的命令。我正在尋找一種登錄日志檔案命令的解決方案。
現在我只知道這一點,但是復制 粘貼所有已記錄的命令非常煩人:
$LogPath = "C:\Logs"
$FileName = (Get-Item $PSCommandPath).Basename
$LogFile = $LogPath "\" $FileName ".log"
Function WriteLog
{
Param ([string]$LogString)
$Stamp = (Get-Date).toString("yyyy-MM-dd HH:mm:ss")
$LogMessage = "$Stamp $LogString"
Add-content $LogFile -value $LogMessage
}
WriteLog "***********************"
WriteLog ""
WriteLog "Command1"
Command1
WriteLog "Command2"
Command2
WriteLog "Command3"
Command3
WriteLog "Command4"
Command4
WriteLog "Command5"
Command5
WriteLog ""
WriteLog "***********************"
uj5u.com熱心網友回復:
我建議如下:
修改您的函式以替代接受代表要執行的命令的腳本塊( )。
{ ... }如果給出了一個腳本塊,則使用它的字串表示作為日志訊息,然后執行它。
# Create the logging function in a *dynamic module* (see below).
# Place this at the top of your script.
$null = New-Module {
# Define the log-file path.
$LogPath = 'C:\Logs'
$FileName = (Get-Item $PSCommandPath).Basename
$LogFile = $LogPath '\' $FileName '.log'
# Create / truncate the file.
New-Item -Force -ErrorAction Stop $LogFile
function Add-LogMessage {
[CmdletBinding(DefaultParameterSetName = 'String')]
param(
[Parameter(Position = 0, Mandatory, ParameterSetName = 'ScriptBlock')]
[scriptblock] $ScriptBlock
,
[Parameter(Position = 0, ParameterSetName = 'String')]
[string] $String
)
# If a script block was given, use its string representation
# as the log string.
if ($ScriptBlock) {
# Make the string representation single-line by replacing newlines
# (and line-leading whitespace) with "; "
$String = $ScriptBlock.ToString().Trim() -replace '\r?\n *', '; '
}
# Create a timestamped message and append it to the log file.
$stamp = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
$logMessage = "$stamp $String"
Add-Content -LiteralPath $LogFile -Value $logMessage
# If a script block was given, execute it now.
if ($ScriptBlock) {
# Because this function is defined in a (dynamic) module,
# its invocation doesn't create a child scope of the *caller's* scope,
# and invoking the given script block, which is bound to the caller's scope,
# with . (dot-sourcing) runs it *directly in the caller's scope*.
. $ScriptBlock
}
}
}
筆記:
- 函式名稱遵循 PowerShell 的動詞-名詞約定, using
Add,這是一個認可的動詞;然而,為簡潔起見,在情境中也執行執行(這Invoke將是批準的動詞)的方面并未反映在名稱中。
您的腳本將如下所示:
Add-LogMessage "***********************"
Add-LogMessage ""
Add-LogMessage { Command1 }
Add-LogMessage { Command2 }
# ...
Add-LogMessage "***********************"
筆記:
通過將函式放置在通過創建的(動態、瞬態)模塊
New-Module中,它的呼叫不會創建呼叫者作用域的子作用域。{ ... }當一個由呼叫者作用域中的字面量 () 創建的腳本塊被傳遞時,它可以被dot-sourcing 運算子.呼叫,它直接在呼叫者的作用域中執行它,這意味著腳本塊的代碼可以自由修改腳本的變數,就像將代碼直接放在腳本中一樣。如果您希望該函式還記錄給定腳本塊的輸出(同時仍將其列印到顯示幕),您可以使用
Tee-Object如下(為簡單起見,我假設相同的目標日志檔案,根據需要進行調整):. $ScriptBlock | Tee-Object -Append -FilePath $LogFile警告:從 PowerShell 7.2.x 開始,
Tee-Object使用固定字符編碼,即Windows PowerShell中的 UTF-16LE(“Unicode”)和PowerShell (Core) 7 中的 BOM-less UTF-8 。GitHub 問題 #11104建議添加一個-Encoding引數(只有未來的PowerShell(核心)版本才會受益)。因此,如果您使用的是Windows PowerShell,并且您的目標是相同的日志檔案來捕獲輸出,請務必修改
Add-Content呼叫,-Encoding Unicode如下所示:Add-Content -Encoding Unicode -LiteralPath $LogFile -Value $logMessage或者,如果您想避免使用 UTF-16LE(“Unicode”)檔案的大小(使用全 ASCII 字符,它們是 ANSI 和 UTF-8 檔案大小的兩倍),您可以使用其中討論的解決方法之一這個答案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/530777.html
標籤:电源外壳功能日志记录
