How to speed up login times using Group Policy Preferences and Powershell

If you’re anything like me, Group Policy preferences revolutionised the way I achieved things.  They seemed to answer a lot of our prayers as Admins and simplified a lot of tasks that otherwise would have been painful and \ or convoluted to implement.

One of the changes I made at my workplace was to deploy our printers using the new Group Policy User Preference item: Printers

1 - GPP Printers

Once I had created a new ‘Shared Printer’ I then used the Targeting feature to ensure that it would only apply if the computer was in a certain Organisational Unit (OU):

2 - Targeting

I could then add multiple printers to the same Group Policy; I had one Group Policy object which I deployed to my ‘Users’ and through the clever use of ‘targeting’, the logged in computer was sure to only receive the printer deployment that it should.

The whole process was genius and our single GPO contained over 80 printer deployments \ deletions.

You gotta love GPP’s!

I did,  until today.  Actually the story began last week when I was logging into a computer and thought that the process was incredibly slow.  I nailed the delay down to the printers being installed. (As they are installed on a user basis not computer; they are installed on every login.)

I decided to experiment with an alternative method of installing the printers and naturally I turned to Powershell to do this.  After getting some basic timings, I knew this was the way to go.

I wanted to achieve this with as little work as possible (don’t we all?) and so over the weekend I started to devise a cunning plan….

Cue Monday morning….

I wrote a Powershell script that reads the XML of the GPO containing the GPP for the Printers and installs \ deletes the printers based on whatever’s already there.

To clarify, I unlinked the existing GPO that deploys printers so it is in effect, just a ‘placeholder’ sitting there holding the printer info…which printer, who gets it, is it default etc and then read that info into a variable in my PS script – the variable is then parsed and printers deployed via the same script based on this information.

This has the added benefit of procedures remaining the same.  If someone already knows how to add a new printer deployment to the GPO, they continue exactly as they have always done.  Nothing has changed. (Except the GPO is no longer linked anywhere.)

I created a new GPO that simply deploys my Powershell script to users.

I wrote the script so that it is as generic as possible.  E.g. you do not need to specify a domain, or an OU etc etc the script will sort all of this out.  The only parameter you will need to supply is the GUID of your GPO that contains your printer GPP deployments.  To get that, simply select the ‘Details’ tab and copy the UniqueID (including the curly braces):

3 - GUID

I should also point out that at the moment, the script will only work if you use GPP exactly as I have described.  ie. You deploy shared printers and you target computers belonging to specific OU’s.

I will be actively working on this script so that  it also works with users in specific OU’s as well as Users being members of security groups.  Alternatively, go ahead and make any mods yourself if you cannot be bothered to wait for me.

How to use the script:

1. To use the script, you will need to change the very last line which is the entry point into the script – simply change the GUID that is currently there to the GUID that your GPO uses.

2. Once you’ve done that, UNLINK the current GPO that you use for deployments.

3. Deploy the Powershell script as a Logon script via a new GPO to your users:

a.

4 - LogonScript

b.

5 - LogonScript2

The Proof:

I found timings similar to these on all of the computers I tested.  None of the computers I tested had SSD’s.

Using Standard GPP’s:

Login1 (Profile created as never logged in before):  1:58 (Minutes: Seconds)
Login2: 1:00
Login3: 1:00

Using Powershell:

Login1 (Profile created as never logged in before):  1:02 (Minutes: Seconds)
Login2: 0:17
Login3: 0:17

That is not a typo!  Seventeen seconds reduced from over a minute!  When I tested this on some of our older computers that receive multiple printers I reduced the login time from 2 minutes 35 seconds to a staggering 25 seconds!

Why it works:

You are probably asking yourself how this works.  I asked myself the same question and I’m guessing at the answer here but…I think that GPP processes in a synchronous manner and the Powershell script processes asynchronously.  Or it could be that it is the targeting evaluation that is taking the time as I would imaging the evaluation takes place over the network.  Or a combination of both.  At this stage I have not investigated more fully however this is something I will definitely be looking in to.

Get the script:

You can find the script as it is so far here in my Github repository.

6 Comments

  1. Hi mate,

    Using this script now, it works quite well so thank you for that!

    I need a modification made but unfortunately my PS skills aren’t too polished.

    When the script checks for the computers OU its looking at “OU=Workstations,OU=IT,OU=Sydney,DC=contoso,DC=local” but my Item Level Targeting is set to look at “OU=Sydney,DC=contoso,DC=local” so no printer gets mapped.

    What modifications can I make to the script fix my issue without having to set every OU manually in ILT

    Thank you

    • Hmm…it’s been a long time since I did this – I no longer work where this is used. I had a quick look at the script again and I’m not sure what you mean here. The script should pull the ou that the workstation in question (the one running the script) is in and compares it against the GPP targeting. So if it pulls in ou=workstations and your targeting is set to ou=sydney then it would quite rightly not deploy any printers as your target is pointing at ou=Sydney and your workstation is not a member of this ou. Unless I am not understanding your question?

      • Nope you’re understanding right. What I would like the script to achieve is to deploy printers to any computer found in OU=Sydney or any of its descendants instead of doing an -eq match to OU of the workstation.

        • OK – yeah I see what you are saying – the script doesn’t take this into account whereas if you were using GPP natively ‘as is’ it would do sub-ou’s. The script is performing as if ‘Direct Member Only’ has been ticked. OK – well I can look into this but I don’t have much free time. I will put it on my list to re-vist and add but it won’t be in any immediate timescale as I am busy with other projects. This doesn’t help you but if you want to continue using the script then at least you have a work-around. As a side-note, I can thoroughly recommend Microsoft Virtual Academy’s Powershell set of courses with Jason Helmick and Jefferey Snover: https://mva.microsoft.com/en-us/training-courses/getting-started-with-powershell-3-0-jump-start-8276?l=r54IrOWy_2304984382

          • No problem, I’m glad I even got a response 2 years after you made this post 😀 thanks mate

Leave a Reply