[英]Referencing targeted object in ForEach-Object in Powershell
我對Powershell相當陌生。 我試圖通過引用作為備份一部分創建的每個GPO備份的“ gpresult.xml”文件中的名稱來重寫GPO備份文件夾的名稱,以使用其友好名稱而不是其GUID。 但是,我不明白如何引用正在讀入ForEach-Object循環中的特定對象(在這種情況下為文件夾名稱),以便讀入此文件夾下的文件。
function Backup_GPO {
$stamp = Get-Date -UFormat "%m%d"
New-Item -ItemType "directory" -Name $stamp -Path \\dc-16\share\GPO_Backups -Force | out-null # create new folder to specify day backup is made
Backup-GPO -All -Path ("\\dc-16\share\GPO_Backups\" + "$stamp\" )
Get-ChildItem -Path \\dc-16\share\GPO_Backups\$stamp | ForEach-Object {
# I want to reference the current folder here
[xml]$file = Get-Content -Path (folder that is being referenced in for loop)\gpresult.xml
$name = $file.GPO.Name
}
我來自Python,如果我想引用當前正在迭代的對象,則可以非常簡單地執行此操作-
for object in list:
print(object)
如何在Powershell的ForEach-Object命令中引用當前正在使用的對象?
我來自Python,如果我想引用當前正在迭代的對象,則可以非常簡單地執行此操作-
for object in list: print(object)
在PowerShell中直接等效的是foreach
語句 (循環) :
$list = 1..3 # create a 3-element array with elements 1, 2, 3
foreach ($object in $list) {
$object # expression output is *implicitly* output
}
請注意, 您不能在PowerShell 管道中直接使用foreach
語句 。
在管道中,您必須使用ForEach-Object
cmdlet來代替 ,后者(通過混淆) 也可以稱為foreach
,它通過別名被使用 -只有解析模式才能區分語句和cmdlet的別名。
您正在管道中使用ForEach-Object
cmdlet ,其中應用了不同的規則 。
傳遞給管道處理cmdlet(例如ForEach-Object
和Where-Object
)的腳本塊( { ... }
) 沒有使用foreach
語句提供的顯式迭代變量。
取而代之的是,按照慣例,這樣的腳本塊看到當前的管道輸入對象的自動變量 $_
-或者更冗長,因為$PSItem
。
盡管foreach
語句和ForEach-Object
cmdlet在特定的抽象級別上運行相同,但是存在根本的區別 :
foreach
語句 完全對內存中 foreach
收集的集合進行操作。
ForEach-Object
cmdlet 對流輸入進行逐個對象操作 ,因為每個對象都是通過管道接收的。
這種差異等於以下權衡 :
使用foreach
語句以獲得更好的性能,但要消耗內存 。
使用ForEach-Object
cmdlet 持續使用內存 ,也可能為了提高性能而犧牲單個管道的語法 效果 -但是,對於非常大的輸入集,這可能是唯一的選擇(假設您不同時收集內存中非常大的數據集, 輸出 )。
在ForEach-Object
腳本塊內,將要迭代的當前項目復制到$_
:
Get-ChildItem -Filter gpresult.xml |ForEach-Object {
# `$_` is a FileInfo object, `$_.FullName` holds the absolute file system path
[xml]$file = Get-Content -LiteralPath $_.FullName
}
如果要指定自定義名稱,則可以指定-PipelineVariable
名稱:
Get-ChildItem -Filter gpresult.xml -PipelineVariable fileinfo |ForEach-Object {
# `$fileinfo` is now a FileInfo object, `$fileinfo.FullName` holds the absolute file system path
[xml]$file = Get-Content -LiteralPath $fileinfo.FullName
}
或使用foreach
循環語句,就像python for object in list
中的for object in list
一樣:
foreach($object in Get-ChildItem -Filter gpresult.xml)
{
[xml]$file = Get-Content -LiteralPath $object.FullName
}
其他方式...
$dlist = Get-ChildItem -Path "\\dc-16\share\GPO_Backups\$stamp"
foreach ($dir in $dlist) {
# I want to reference the current folder here
[xml]$file = Get-Content -Path (Join-Path -Path $_.FullName -ChildPath 'gpresult.xml')
$name = $file.GPO.Name
}
這是我的解決方案。 令人討厭的是$ _沒有完整的路徑。 $ gpath比$ _。fullname更容易使用,因為在下一行使用get-content將兩個字符串連接在一起。 嘗試backup-gpo時,我得到一個gpreport.xml文件。 顯然,您不能將。\\ gpo_backups \\之類的相對路徑與backup-gpo一起使用。
mkdir c:\users\js\gpo_backups\
get-gpo -all | where displayname -like '*mygpo*' |
backup-gpo -path c:\users\js\gpo_backups\
Get-ChildItem -Path .\GPO_Backups\ | ForEach-Object {
$gpath = $_.fullname
[xml]$file = Get-Content -Path "$gpath\gpreport.xml"
$file.GPO.Name
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.