Reputation: 331
I have a CSV file with computer names. I import them and want to use each value to do something with.
$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)
}
}
This takes a csv file as a param then loops over it. trying to get this function passed as a parameter
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"
}
}
That way i dont have to write another foreach loop to do other tasks syncronously using values within the CSV, i can just make functions taking one argument, the iteration variable
Upvotes: 0
Views: 171
Reputation: 331
Instead of creating an Advanced Function named Add-NetworkPrinter, I just created a scriptblock, as @Andrey pointed out while keeping my advanced function that iterates through values of the CSV file.
$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
}
Then I just call my Iterate-CSV function by providing the path to csv as param1 and scriptblocks that use the same values for param2. Thanks for the ScriptBlock Info!
Iterate-CSV -csvFilePath $computerNames -functionCall $addNetworkPrinter
Iterate-CSV -csvFilePath $computerNames -functionCall $restarComputers
Upvotes: 0
Reputation: 174815
To reference the underlying scriptblock definition of a registered function, use the function:
drive prefix to pass it as a variable:
Iterate-Csv ... -scriptBlock ${function:Add-NetworkPrinter}
Upvotes: 1
Reputation: 4356
You'll need to pass a scriptblock
that calls your function.
$func = [scriptblock]{
param ($arg)
Add-NetworkPrinter $arg
}
Iterate-CSV -csvFilePath ... -functionCall $func
Upvotes: 1