3

i am looking for a way to take a script that I have created. And simply run it against the individual printers all at once. I do not care about returning any information other than success or failure if that is possible.

so far this is what I have come up with:

$scriptBlock = {
                    param($PRINTSERVER,$PRINTER) 
                    . \\rictx-script-p2\Scripts\Module\OS\Print Server\Set-Permissions\Apply-PrinterPermissions3.ps1
                    Apply-PrinterPermissions -PrintServers $PRINTSERVER -PrinterName_Single $PRINTER
                }


$PSERVER = "MTHOH-PRINT-P06"
$MyPrinter = "WILPA0P30"
#Async
Start-Job -ScriptBlock $scriptBlock -ArgumentList @($PSERVER,$MyPrinter)

The Script works great in parallel. But I am trying to speed up a 12 to 13 hour run on over 900 different printers in the environment. By applying the script async. The script is already configured to work on a print server as a whole and on a printer individually. To ensure there is a consistant permissions assigned to them all according to corporate policy. On average the script takes about 1 to 1.5 minutes per printer to apply the printer ACL Changes.

My Thoughts was to have a script block load the printer permissions script, call the printers individually per job with the print server. And run about 50 to 100 jobs at once. This would require sending 2 paramaters to the script block for the function to be called.

What would be the best way to do this? Currently the script does nothing when I start the job. but works if I call the apply-printerpermissions3 script directly.

Other things I have tried:

$scriptBlock = {
                    param($P) 
                    . \\rictx-script-p2\Scripts\Module\OS\Print Server\Set-Permissions\Apply-PrinterPermissions3.ps1
                    Apply-PrinterPermissions -PrintServers $P[0] -PrinterName_Single $P[1]
                }


$PSERVER = "MTHOH-PRINT-P06"
$MyPrinter = "WILPA0P30"
#Async
Start-Job -ScriptBlock $scriptBlock -ArgumentList @($PSERVER,$MyPrinter)

#Syncroneous
& $scriptBlock -PRINTSERVER $PServer -PRINTER $MyPrinter

The Sycroneous process works but the async does not.

Sorry I am not sure how to add my comment with code blocks as a reply: I have tried this:

$s = New-PSSession -ComputerName mthoh-print-p06
    $scriptBlock = { param($PRINTSERVER,$PRINTER)
                    Write-Host "$PRINTSERVER"
                    Write-Host "------------"
                    Write-Host "$Printer" 
                    . \\rictx-script-p2\Scripts\Module\OS\Print Server\Set-Permissions\Apply-PrinterPermissions3.ps1
                    Apply-PrinterPermissions -PrintServers $PRINTSERVER -PrinterName_Single $PRINTER }

$ArgumentList = "PSERVER", "Wilpa0p30"

Invoke-Command -Session $s -ScriptBlock $scriptBlock -AsJob -ArgumentList $ArgumentList



$s = New-PSSession -ComputerName mthoh-print-p06
$scriptBlock = { param($P)
                    Write-Host "$PRINTSERVER"
                    Write-Host "------------"
                    Write-Host "$Printer" 
                    . \\rictx-script-p2\Scripts\Module\OS\Print Server\Set-Permissions\Apply-PrinterPermissions3.ps1
                    Apply-PrinterPermissions -PrintServers $P[0] -PrinterName_Single $P[1] 
                }

$ArgumentList = "PSERVER", "Wilpa0p30"

Invoke-Command -Session $s -ScriptBlock $scriptBlock -AsJob -ArgumentList $ArgumentList

My Problem is this completes but does not appear to do anything. The script works if I call it locally just not working with Invoke-command.

I am not worried about the process of passing each printer name. I can eaisly do:

foreach ( $Printer in ((Get-Printer -Computername $Server).Name) )
{do something to pass each command to my Printer ACL Script...}

My Printer ACL Script is configured to do a printer individually and process a server as a whole.


I think I have found something that works. Thanks for your help:

$parameters = @{
    ComputerName = "mthoh-print-p06"
    ScriptBlock = { param($PRINTSERVER,$PRINTER)
                    
                    Write-host "$($env:COMPUTERNAME)  ---  $($env:USERNAME)"
                    Write-Host "$PRINTSERVER"
                    Write-Host "------------"
                    Write-Host "$Printer" 

                    $item = "\\rictx-script-p2\Scripts\Module\OS\Print Server\Set-Permissions\Apply-PrinterPermissions3.ps1"
                    ([System.IO.File]::Exists($Item))
                   
                    . "\\rictx-script-p2\Scripts\Module\OS\Print Server\Set-Permissions\Apply-PrinterPermissions3.ps1"
                    Apply-PrinterPermissions -PrintServers $PRINTSERVER -PrinterName_Single $PRINTER }
    ArgumentList = "mthoh-print-p06", "Wilpa0p30"
}
Invoke-Command @parameters -EnableNetworkAccess -AsJob
$j = Get-Job
$j | Format-List -Property *
$results = $j | Receive-Job
get-job | Where {$_state -ne "Running"} | Remove-Job
6
  • 1
    Why are you running a local job when you can run remote jobs on all servers in parallel with Invoke-Command ? Commented Jan 7, 2022 at 5:15
  • I am not opposed to it. But I would like single sign on authenticaiton so I do not have to pass credientials. Also I attempted to do this and it also failed for me: $parameters = @{ ComputerName = "Server01" ScriptBlock = { param($PRINTSERVER,$PRINTER) . \\rictx-script-p2\Scripts\Module\OS\Print Server\Set-Permissions\Apply-PrinterPermissions3.ps1 Apply-PrinterPermissions -PrintServers $PRINTSERVER -PrinterName_Single $PRINTER } ArgumentList = "PSERVER", "MyPrinter" } Invoke-Command @parameters -AsJob Commented Jan 7, 2022 at 6:15
  • I would like the ability to run async locally. But I am not against running the script remotely. Commented Jan 7, 2022 at 6:30
  • 1
    I'm assuming you don't have 900 ps1 files with their own $PServer='';$MyPrinter=''; & $ScriptBlock...; the solution to your problem is going to rely on how you're managing the list of devices. Commented Jan 7, 2022 at 19:08
  • no I will be doing a querry into a array then foreach loop passing all the printers individually as a parameter to the Printer ACL Script. Commented Jan 7, 2022 at 23:25

2 Answers 2

1

As stated in above comment. I'd try to run the scriptblock via Invoke-Command with the -AsJob parameter. Which will return a job, that you can await. Combined with PSRemoting you can fire multiple Invoke-Commands that'll return a job to a remote execution. See the PowerShell docu for an example. If you need to pass local parameters to the remote job, in a readonly manner, see this example.

Sign up to request clarification or add additional context in comments.

3 Comments

what both of these docu examples are missing is how to customize the run per server since each server has a different list of printers...
I like the option being offered but running into a road block. My Problem is this completes but does not appear to do anything. The script works if I call it locally just not working with Invoke-command.
finally figured out that enablednetwork parameter needed to be added to the script.
1

Since you're not trying to cherry-pick the printers, it makes the task of standardizing the code across all the servers much simpler

$s = new-pssession -computername @(
   'MTHOH-PRINT-P05',
   'MTHOH-PRINT-P06'
)

$Init = get-content '\\rictx-script-p2\Scripts\Module\OS\Print Server\Set-Permissions\Apply-PrinterPermissions3.ps1' -raw
$RemoteJobs = invoke-command -session $s -scriptblock {
   $Init = [ScriptBlock]::Create($Using:Init)
   $MyName = $env:COMPUTERNAME
   
   $ServerJobs = foreach($MyPrinter in (get-printer -computername $MyName).name){
      start-job -InitializationScript $Init -ScriptBlock {
         param($PRINTSERVER,$PRINTER)
         Apply-PrinterPermissions -PrintServers $PRINTSERVER -PrinterName_Single $PRINTER
      } -ArgumentList $MyName,$MyPrinter
   }
   receive-job -job $ServerJobs -wait
   remove-job  -job $ServerJobs
} -AsJob

$null    = wait-job    -job $RemoteJobs
$results = receive-job -job $RemoteJobs
remove-job -job $RemoteJobs

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.