We use the Deployed Printers feature in the Print Management console to deploy printers to users. As part of the printer migration that I have been working on, I needed to modify all of these GPOs so that all of the policies directed all of the users to the new print server.
There are over 200 policies in existence. That would be a lot of manual work, that would be prone to errors.
Also, I needed to be able to change over print servers in around an hour. Editing 200 policies in an hour would be impossible.
This is what the result of this conundrum is. The script below goes out to find all of the deployed printers in all GPOs in the domain. It then looks for the name of the old print server, and replaces it with the name of the new print server.
The script fully supports the -WhatIf switch, and also an output of all of the printers that were found and what changes were made is output at the end of the process. I suggest that the output is piped to a variable, which can then be formatted as a table or exported into something more readable. I just provide the raw data here, you can do with it as you wish.
You will need the ActiveDirectory module loaded in your Powershell session, and you will also need to be running this script as a user that has sufficient permissions to modify GPO in your domain.
As always, test on a lab before running this on your production servers!
# ---------------------------------------------------------------------------------------------------------- # PURPOSE: Modify all GPO's which have Pushed Printer Connections to a new print server name. # # VERSION DATE USER DETAILS # 1 22/08/2014 Craig Tolley First version # # # ---------------------------------------------------------------------------------------------------------- #Define the print server names. Should include the leading \\ to ensure it only matches at the start. Function Modify-PushedPrinterConnections { [cmdletbinding(SupportsShouldProcess=$True)] Param ( #The name of the Old Print Server. This string will be searched for in order to be replaced. [Parameter(Mandatory=$true)] [string]$OldPrintServerName, #The name of the New Print Server. This will replace the Old Print Server value. [Parameter(Mandatory=$true)] [string]$NewPrintServerName ) #Collection detailing all of the work $GPOPrinterDetails = @() #Get all of the GPO objects in the domain. $GPOs = Get-GPO -All Write-Host "GPOs Retrieved: $($GPOs.Count)" ForEach ($GPO in $GPOs) { $PrintObjects = Get-ADObject -SearchBase "CN={$($GPO.Id)},CN=Policies,CN=System,DC=medlan,DC=cam,DC=ac,DC=uk" -Filter {objectClass -eq "msPrint-ConnectionPolicy"} -SearchScope Subtree ForEach ($PCO in $PrintObjects) { #Get the properties of the Print Connection Object that we actually need. $PrintConnection = Get-ADObject $PCO.DistinguishedName -Properties printerName, serverName, uNCName #Log details of the policy that we have found $GPOPrinterDetail = @{ GPOId = $GPO.Id GPOName = $GPO.DisplayName PrintConnectionID = $PrintConnection.ObjectGUID PrinterName = $PrintConnection.printerName OriginalPrintServer = $PrintConnection.serverName OriginalUNCName = $PrintConnection.uNCName NewPrintServer = $null NewUNCName = $null ChangeStatus = "NotEvaluated" } #Find out if we need to make a change or not. If ($PrintConnection.serverName.ToLower() -eq $OldPrintServerName.ToLower()) { #Change the local instance $PrintConnection.serverName = $NewPrintServerName $PrintConnection.uNCName = $PrintConnection.uNCName.Replace($OldPrintServerName,$NewPrintServerName) #Update our reporting collection $GPOPrinterDetail.NewPrintServer = $PrintConnection.serverName $GPOPrinterDetail.NewUNCName = $PrintConnection.uNCName $GPOPrinterDetail.ChangeStatus = "ChangePending" #Write the changes and catch any errors Try {Set-ADObject -Instance $PrintConnection -Verbose $GPOPrinterDetail.ChangeStatus = "ChangeSuccess"} Catch {$GPOPrinterDetail.ChangeStatus = "ChangeFailed"} } Else { $GPOPrinterDetail.ChangeStatus = "NoChange" } #Update the table $GPOPrinterDetails += New-Object PSObject -Property $GPOPrinterDetail } } #Finally write out the changes Write-Output $GPOPrinterDetails }
2 thoughts on “Modifying GPO Printer Deployment using PowerShell”