PrinterSwap.psm1
function Start-PrinterServerSwap { <# .SYNOPSIS Run as Admin, then creates a task to install printers in $ENV:USERNAME's profile when they log on after a delay of 2 min. .DESCRIPTION Assists with installing Migrating local printers to printers of same name as new Print Server by installing all drivers to admin then creating a user task to migrate user printers on Log on to Printers of the same name on the new Print Server. Can either be run without switches to only install drivers, ran with switches to also install a user task and/or only install the user task. .EXAMPLE PS C:\> Start-PrinterServerSwap -OldPrintServer "ABCPrintServer01" -NewPrintServer "ABCPrintServer02" -TaskUserOrGroup "USRDOM\Domain Users" -CreateUserTask -Confirm:$false -Verbose Installs all shared printers from the new print server and created scheduled task to installs user's previous printers on logon after delay. .EXAMPLE PS C:\> Start-PrinterServerSwap -OldPrintServer "ABCPrintServer01" -NewPrintServer "ABCPrintServer02" -TaskUserOrGroup "USRDOM\Domain Users" -OnlyCreateUserTask -Confirm:$false -Verbose Only creates the logon task for users. .EXAMPLE PS C:\> Start-PrinterServerSwap -OldPrintServer "ABCPrintServer01" -NewPrintServer "ABCPrintServer02" -TaskUserOrGroup "USRDOM\Domain Users" -Confirm:$false -Verbose Only installs all shared printers from the new print server. .PARAMETER OldPrintServer Specify the hostname of the old server. Ex: "Print01" .PARAMETER NewPrintServer Specify the hostname of the new server. Ex: "Print02" .PARAMETER TaskUserOrGroup Specifies the username or usergroup(Preferred) to run the task. Ex: Domain\Username .PARAMETER CreateUserTask Switch to also create the user task. Without the switch, only printers from the new server are installed. .PARAMETER OnlyCreateUserTask Switch to only create the user task without installing printer drivers. .PARAMETER Reset Switch to remove local files created by script and any scheduled tasks for starting over. Remove-Item "C:\temp\PrintLogs\Add-PrinterTask.ps1" -Force Remove-Item "C:\temp\PrintLogs\$($printserver).DriversAdded.txt" -Force Remove-Item "$($home)\Saved Games\PrintersAddedCheck.txt" -Force Unregister-ScheduledTask -TaskName "Migrate Printers to new Server" -Confirm:$false .INPUTS System.String .OUTPUTS Output (if any) .NOTES Only installs networked printers. Can be run as GPO immediate task for computer or can be run directly by loading both functions and then running Start-PrinterServerSwap with the appropriate parameters. Servernames used as input to create a logon task that removes the local printers and installs printers of the same name that are found on the new print server. If the new print server has a different share name for a printer, it will not be installed and will need to be added manually by navigating to the Printer share path "\\<PRNTSVRHostName>\" or through control panel if they are shared in active directory. Logs to C:\temp\PrintLogs. #> [CmdletBinding( DefaultParameterSetName = 'Task not included', SupportsShouldProcess = $true, ConfirmImpact = 'High' )] param ( [Parameter( Position = '0', Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true )] [string] $OldPrintServer, # Parameter help description [Parameter( Position = '1', Mandatory = $true, ValueFromPipelineByPropertyName = $true )] [string] $NewPrintServer, # Parameter help description [Parameter( Position = '2', Mandatory = $true, ValueFromPipelineByPropertyName = $true )] [string] $TaskUserOrGroup, # Parameter help description [Parameter( Position = '3', ParameterSetName = 'Create User Task', Mandatory = $false, ValueFromPipelineByPropertyName = $true )] [switch] $CreateUserTask, # Parameter help description [Parameter( Position = '3', ParameterSetName = 'Only Create User Task', Mandatory = $false, ValueFromPipelineByPropertyName = $true )] [switch] $OnlyCreateUserTask, [Parameter( Position = '3', ParameterSetName = 'Reset', Mandatory = $false, ValueFromPipelineByPropertyName = $true )] [switch] $Reset ) Begin { # Check for admin and throw exception if not. $currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent()) if (!($currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))) { throw "Not Running as admin! Please rerun as administrator!" } # Create Log Path $DirPath = "C:\temp\PrintLogs" $DirPathCheck = Test-Path -Path $DirPath If (!($DirPathCheck)) { Try { #If not present then create the dir New-Item -ItemType Directory $DirPath -Force } Catch { Write-Output "Directory: $DirPath was not created." exit } } if ($reset) { Remove-Item "C:\temp\PrintLogs\Add-PrinterTask.ps1" -Force Remove-Item "C:\temp\PrintLogs\$($printserver).DriversAdded.txt" -Force Remove-Item "$($home)\Saved Games\PrintersAddedCheck.txt" -Force Unregister-ScheduledTask -TaskName "Migrate Printers to new Server" -Confirm:$false Write-Output "If this was deployed via an `"Immediate Task GPO`", please set the action to `"Remove`" to ensure the scheduled task is stopped." -ForegroundColor Green Start-Sleep 20 Stop-Transcript Exit } # Log commands and input Start-Transcript -OutputDirectory C:\temp\PrintLogs -IncludeInvocationHeader -NoClobber if(Test-Path "C:\temp\PrintLogs\Add-PrinterTask.ps1"){ Remove-Item "C:\temp\PrintLogs\Add-PrinterTask.ps1" -Confirm:$false -Force Unregister-ScheduledTask -TaskName "Migrate Printers to new Server" -Confirm:$false if (Test-Path -Path "C:\temp\PrintLogs\$($printserver).DriversAdded.txt") { Remove-Item "C:\temp\PrintLogs\$($printserver).DriversAdded.txt" } } else{ if (Test-Path -Path "C:\temp\PrintLogs\$($printserver).DriversAdded.txt") { exit Stop-Transcript } } Start-Service Spooler Set-Service -Name "Spooler" -StartupType Automatic Write-Host "OldPrintServer: $OldPrintServer" Write-Host "NewPrintServer: $NewPrintServer" Write-Host "Task User or Group Name in DOMAIN\USERNAME or DOMAIN\GROUP format: $TaskUserOrGroup" } # End Begin Process { # If $OnlyCreateUserTask switch if ($OnlyCreateUserTask) { # Create Script File for User Task. Start-CreatePrinterInstallTask -oldpserver $OldPrintServer -newpserver $NewPrintServer -tskusrorgrp $TaskUserOrGroup Stop-Transcript exit } # End Create User Task ##########END ONLYCREATEUSERTASK########### # Install all printers from New Print server locally. $printserver = $NewPrintServer $notinstalled = @{} $notinstalled.PrinterName = @() Get-Printer -ComputerName $printserver | Where-Object { $_.shared -eq $true } | ` foreach-object { Write-Output "Installing Printer: $($_.Name)" try { if ($PSCmdlet.ShouldProcess( ("Overwritting existing Printer {0}" -f $($_.Name)), ("Would you like to overwrite {0}?" -f $($_.Name)), "Create Printer Prompt")) { Add-Printer -ConnectionName "\\$($printserver)\$($_.Name)" -ErrorVariable ErrorAddPrinter } } Catch { $notinstalled.PrinterName += $_.Name Write-Output "Failed: Printer $($_.Name) failed to install" Write-Output "The Error was: `n" $ErrorAddPrinter } if ($?) { Write-Output "Success: Printer $($_.Name) was installed successfully!`n" } } if ($?) { "Drivers Added on $((Get-Date).ToString('MM-dd-yyyy-hh-mm-ss'))" | Out-File "C:\temp\PrintLogs\$($printserver).DriversAdded.txt" -NoClobber $done = (Get-date).AddMinutes(10) Write-Output "Waiting 10 Minutes! Will be done at: $done" if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, "Sleep for 10 min")) { Start-Sleep -Seconds 600 } } else { Throw "$($_.Exception.Message)" } Write-Output "Printers not installed: `n" $notinstalled.PrinterName | Out-File "C:\temp\PrintLogs\$($printserver).Notinstalled.txt" -NoClobber } # End Process End { # Switch to also create a task to find and install printers with the same name on the new print server. if ($CreateUserTask) { # Create Script File for User Task. try { if ($PSCmdlet.ShouldProcess($OldPrintServer, $NewPrintServer, $TaskUserOrGroup)) { Start-CreatePrinterInstallTask -oldpserver $OldPrintServer -newpserver $NewPrintServer -tskusrorgrp $TaskUserOrGroup } } catch { Throw "$($_.Exception.Message)" } } # End CreateUserTask else { Write-Output "Installed Printers on new Print Server. User printer task has not been created" } Stop-Transcript } # End } function Start-CreatePrinterInstallTask { [CmdletBinding()] param ( [Parameter()] [string] $OldPServer, [Parameter()] [string] $NewPServer, [Parameter()] [string] $tskUsrOrGrp ) $scripts = { Start-Transcript -OutputDirectory C:\temp\PrintLogs -IncludeInvocationHeader -NoClobber if (Test-Path -Path "$($home)\Saved Games\PrintersAddedCheck.txt" ) { exit } $OldPrintServer = "oldpserver" $NewPrintServer = "newpserver" $waittxt = "Please wait for this to complete! Click here and press enter if it takes more than 10 min!" $migratingtxt = "Migrating your printers from $OldPrintServer to $NewPrintServer for user: " Write-Host $migratingtxt -ForegroundColor Yellow Write-Host "User: $($env:USERNAME)" Write-Host $waittxt -ForegroundColor Green try { # Get Printers of connection type "Connection" $MappedPrinters = Get-Printer | Where-Object { $_.type -eq "Connection" } } catch { Write-Output "Could not connect to printer. The Error was: `n" Throw "$($_.Exception.Message)" } Write-Host "Successfully Connected to local printer!" -ForegroundColor Green $path = "C:\temp\PrintLogs\OriginalPrinters.$env:USERNAME.$((Get-Date).ToString('MM-dd-yyyy-hh-mm-ss')).csv" $xmlpath = "C:\temp\PrintLogs\OriginalPrinters.$env:USERNAME.$((Get-Date).ToString('MM-dd-yyyy-hh-mm-ss')).xml" # Log initial values of printers per user. $MappedPrinters | Export-CSV -Path $path -NoTypeInformation $MappedPrinters | Export-Clixml -Path $xmlpath Foreach ($Printer in $MappedPrinters) { $printername = $printer | Select-Object -ExpandProperty Name $printername If ($PrinterName -Like "*$OldPrintServer*") { Write-Host "Found Printer `"$PrinterName`" to be connected!" -ForegroundColor Green $PrinterNewName = $PrinterName -Replace "$OldPrintServer", "$NewPrintServer" Add-printer -ConnectionName $PrinterNewName -ErrorAction SilentlyContinue if ($?) { Remove-Printer -Name $printername Write-Host "Removed Printer `"$printername`" from your computer." ` -ForegroundColor Yellow -BackgroundColor Blue } } } # Create File for verification on future runs if ($?) { "Success" | Out-File "$($home)\Saved Games\PrintersAddedCheck.txt" Stop-Transcript } } # Resume Script Context # Output Scripts to File $scripts | Out-File -FilePath "C:\temp\PrintLogs\Add-PrinterTask.ps1" -Encoding utf8 # Replace values in file with values from Parameters. ((Get-Content -path "C:\temp\PrintLogs\Add-PrinterTask.ps1" -Raw) -replace 'oldpserver', $($OldPrintServer)) | ` Set-Content -Path "C:\temp\PrintLogs\Add-PrinterTask.ps1" ((Get-Content -path "C:\temp\PrintLogs\Add-PrinterTask.ps1" -Raw) -replace 'newpserver', $($NewPrintServer)) | ` Set-Content -Path "C:\temp\PrintLogs\Add-PrinterTask.ps1" # Create User Task $jobName = "Migrate Printers to new Server" $script = '-NoLogo -ExecutionPolicy Bypass -File C:\temp\PrintLogs\Add-PrinterTask.ps1' $action = New-ScheduledTaskAction -Execute "$pshome\powershell.exe" -Argument $script $taskPrincipal = New-ScheduledTaskPrincipal -GroupId $tskUsrOrGrp -RunLevel Highest $timeSpan = New-TimeSpan -Minutes 2 $trigger = New-ScheduledTaskTrigger -AtLogOn -RandomDelay $timeSpan $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -RunOnlyIfNetworkAvailable -DontStopOnIdleEnd Register-ScheduledTask -TaskName $jobName -Action $action -Principal $taskPrincipal -Settings $settings -Trigger $trigger } |