Modifying GPO Printer Deployment using PowerShell

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

}

4 people found this post useful.


2 thoughts on “Modifying GPO Printer Deployment using PowerShell

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.