簡體   English   中英

嘗試將高級 function 作為 Powershell 中的 function 參數傳遞

[英]Trying to pass an advanced function as a function argument in Powershell

我有一個帶有計算機名稱的 CSV 文件。 我導入它們並希望使用每個值來做某事。

$computerNames = import-csv -Path "C:\Users\fakePath\Desktop\Programming\Powershell\remoteAddPrinters\computers.csv" -header "Computers"

function Iterate-CSV {
    param (
        # Parameter help description
        [Parameter(Mandatory=$true)]
        [array]
        $csvFilePath,

        [scriptblock]$functionCall #?
    )
    foreach ($computer in ($csvFilePath).Computers) { # Computer is the argument used in other functions.

        Write-Host $functionCall.Invoke($computer)
    }
}

這需要一個 csv 文件作為參數然后循環遍歷它。 試圖讓這個 function 作為參數傳遞

function Add-NetworkPrinter {
    [CmdletBinding()]
    param (
        # Parameter help description
        [Parameter(Mandatory=$true, Position=0)]
        [String]
        $computerName
    )
    
    begin {
        $addPrinterCue = "\\printServer\printCue"
    }
    
    process { # This is a non-terminating error and cannot be handled by try/catch
        Write-Output "$addPrinterCue && $computerName"
        # invoke-command -ComputerName $computerName -scriptBlock {
        #     # cmd.exe /c rundll32 printui.dll,PrintUIEntry /gd /n$addPrinterCue
        #     cmd.exe /c rundll32 printui.dll,PrintUIEntry /ga /n$addPrinterCue /q
        #     Restart-Service -Name Spooler -Force
        #                                     #Creates error to handle
        # } -Credential $domainCredentials  #-ErrorVariable errmsg 2>$null
    }
    
    end {
        Write-Output "Successfully added printer to $computerName"
    }
}

這樣我就不必編寫另一個 foreach 循環來使用 CSV 中的值同步執行其他任務,我可以只使函數接受一個參數,即迭代變量

您需要傳遞一個調用您的scriptblock的腳本塊。

$func = [scriptblock]{ 
    param ($arg)
    Add-NetworkPrinter $arg 
}

Iterate-CSV -csvFilePath ... -functionCall $func

要引用已注冊 function 的底層腳本塊定義,請使用function:驅動器前綴將其作為變量傳遞:

Iterate-Csv ... -scriptBlock ${function:Add-NetworkPrinter}

正如@Andrey 指出的那樣,我沒有創建名為 Add-NetworkPrinter 的高級 Function,而是創建了一個腳本塊,同時保持我的高級 function 迭代 CSV 文件的值。

$computerNames = import-csv -Path "C:\fakePath\computers.csv" -header "Computers"

function Iterate-CSV {
    param (
        # Parameter help description
        [Parameter(Mandatory=$true)]
        [array]
        $csvFilePath,
        [scriptblock]$functionCall
    )
    foreach ($computer in ($csvFilePath).Computers) { 
        Write-Host $functionCall.Invoke($computer)
    }
}

$addNetworkPrinter = [scriptblock]{ 
    param ($computer)
    $addPrinterCue = "\\printServer\printCue"
    Write-Output "$addPrinterCue && $computer"
    # invoke-command -ComputerName $computerName -scriptBlock {
    #     # cmd.exe /c rundll32 printui.dll,PrintUIEntry /gd /n$addPrinterCue
    #     cmd.exe /c rundll32 printui.dll,PrintUIEntry /ga /n$addPrinterCue /q
    #     Restart-Service -Name Spooler -Force
    #                                     #Creates error to handle
    # } -Credential $domainCredentials  #-ErrorVariable errmsg 2>$null
}

$restarComputers = [scriptblock]{
    param (
        [Parameter(Mandatory=$true, Position=0)]
        [string]
        $computer
    )
    Write-Output "Restarting computer $computer"
    # Restart-Computer -ComputerName $computer -Credential $domainCredentials -Force
}

然后,我通過提供 csv 的路徑作為 param1 和對 param2 使用相同值的腳本塊來調用 Iterate-CSV function。 感謝您提供 ScriptBlock 信息!

Iterate-CSV -csvFilePath $computerNames -functionCall $addNetworkPrinter
Iterate-CSV -csvFilePath $computerNames -functionCall $restarComputers

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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