[英]Powershell - How to pass variable into scriptblock
我試圖理解並弄清楚如何將變量傳遞到腳本塊中。 在我下面的示例腳本中,當一個新文件被拖放到受監視的文件夾中時,它會執行 $action 腳本塊。 但是 $test1 變量只是顯示為空白。 我可以讓它工作的唯一方法是讓它成為一個全局變量,但我真的不想這樣做。
我已經對此進行了一些研究,但我比開始時更加困惑。 誰能幫助我或指出正確的方向來理解這一點?
$PathToMonitor = "\\path\to\folder"
$FileSystemWatcher = New-Object System.IO.FileSystemWatcher
$FileSystemWatcher.Path = $PathToMonitor
$FileSystemWatcher.Filter = "*.*"
$FileSystemWatcher.IncludeSubdirectories = $false
$FileSystemWatcher.EnableRaisingEvents = $true
$test1 = "Test variable"
$Action = {
Write-Host "$test1"
}
$handlers = . {
Register-ObjectEvent -InputObject $FileSystemWatcher -EventName Created -Action $Action -SourceIdentifier FSCreateConsumer
}
try {
do {
Wait-Event -Timeout 5
} while ($true)
}
finally {
Unregister-Event -SourceIdentifier FSCreateConsumer
$handlers | Remove-Job
$FileSystemWatcher.EnableRaisingEvents = $false
$FileSystemWatcher.Dispose()
}
您可以通過與ScriptBlocks
類似的方式將變量傳遞給function
。
param(...)
塊:$scriptBlock = {
param($i)
"hello $i"
}
& $scriptBlock -i world! # => hello world! // no access to $i
. $scriptBlock -i world! # => hello world! // $i ('world!') exists in this scope
$args
自動變量:$scriptBlock = {
'{0} {1}!' -f $args[0], $args[1]
}
& $scriptBlock hello world # => hello world! // using $args automatic variable
事件操作塊在后台線程上運行,並且在分派時無法解析$test1
。
一種解決方法是顯式讀取和寫入全局范圍的變量(例如Write-Host $global:test1
),但更好的解決方案是確保$Action
塊“記住” $test1
的值以備后用 - 某事我們可以通過閉包來完成。
為此,我們需要稍微重新組織代碼,因此首先將$test1
字符串文字替換為同步哈希表:
$test1 = [hashtable]::Synchronized(@{
Value = "Test variable"
})
這將允許我們做兩件事:
$test1
中存儲的 object 的身份的情況下修改字符串值,現在我們只需要從$Action
塊創建閉包:
$Action = {
Write-Host $test1.Value
}.GetNewClosure()
這會將$test1
的值(我們剛剛在上一行創建的同步哈希表的引用)綁定到$Action
塊,因此它將“記住” $test1
解析為哈希表而不是嘗試(並失敗)在運行時解決它。
隱藏在Register-ObjectEvent的文檔中,在-Action
參數描述的下方是這個小花絮:
Action 參數的值可以包括 $Event、$EventSubscriber、$Sender、$EventArgs 和 $Args 自動變量。 這些變量向 Action 腳本塊提供有關事件的信息。 有關詳細信息,請參閱 about_Automatic_Variables。
這意味着 PowerShell 會自動創建一些變量,您可以在事件處理程序腳本塊中使用這些變量,並在觸發事件時填充它們 - 例如:
$Action = {
write-host ($Sender | format-list * | out-string)
write-host ($EventArgs | format-list * | out-string)
}
當您在監視文件夾中創建文件時,您會看到一些 output 如下所示:
NotifyFilter : FileName, DirectoryName, LastWrite
Filters : {*}
EnableRaisingEvents : True
Filter : *
IncludeSubdirectories : False
InternalBufferSize : 8192
Path : c:\temp\scratch
Site :
SynchronizingObject :
Container :
ChangeType : Created
FullPath : c:\temp\scratch\New Text Document (3).txt
Name : New Text Document (3).txt
如果這些包含您所追求的信息,那么您實際上不需要自己將任何參數傳遞給腳本塊:-)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.