簡體   English   中英

在Powershell中的ForEach-Object中引用目標對象

[英]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-ObjectWhere-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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM