Category Archives: Scripting

Querying AD with Powershell – First Shakey Steps

As I’m sure you know, I tend to jump in to learning stuff by trying out real world examples. This accelerates the learning process as there’s a desired outcome but it does make my understanding of the foundations a bit ropey. Never mind, let’s dive right in! ūüėÄ

In order to be able to query Active Directory with Powershell, we need to first load up the module that allows Powershell to understand what the heck you’re asking for. That’s the easy bit:

Import-Module ActiveDirectory

OK, so now we’ve got the ability to ask AD questions, let’s ask it for some basic info. Imagine my login is the truly imaginative USER1 in AD. To run a dead simple query, I could just type:

Get-ADUser user1

What that will do is bring up a very little list of selected fields Microsoft thought you might want. Bless ’em, they’re trying to be as helpful as they can. If you want the whole truckload, you can ask it for them:

Get-ADUser user1 -properties *

That’s going to give you the usual suspects of AD users’ properties, so you now have your SID, cn, samaccountname, department, etc. being displayed. If you don’t want all of it and you don’t just want the few provided by the normal output of Get-ADUser then we need to start doing the cool stuff in Powershell. You can pipe one command’s output into the input of the next, stay with me here it’ll make sense. By using the “|” operator you are saying that you want the output of command A fed into command B. So… command A | command B will process command A (in our case a query on a single AD user returning all of the properties for it in to command B (which we’re about to make a Select statement).

Select isn’t implemented the same way as you see in SQL, it’s a soft of cousin but the principles are the same. Here we go:

Get-ADUser user1 -properties * | Select cn, samaccountname, department, homedirectory

This one’s now a lot more friendly to you as it’s pulling back only the bits you want.
OK, moving on from querying a single user what if you wanted to get the username of everyone in the Marketing department? Well, as long as you’re using the fields in AD correctly for your users, you can use the Filter command.

The filter command is the first time you’ll see the curly bracket in this little post but it sure as heck won’t be the last! Curly brackets are implemented in a very similar way to C and C++ if you’re familiar with those two powerhouses. Imagine them as the boundaries for your complex little bit of code. Again, it makes more sense if you just see it in action:

Get-ADUser -filter {department -eq “Marketing”} -properties * |¬†Select cn

Not too impressive yet but try to remember the output of this can be used with the “|” character to output the list that you just output to the screen as the input for a command to set up a new security group for example. Now we’ve turned what could take a while for a Marketing department of say, 25 people into a short set of commands that take no time at all to achieve what you were looking to do. That’s the Power part of the name Powershell!

I’ll be back soon to add to the querying side but for now, enjoy your weekend and I’ll talk to you soon.

Making a Start with PowerShell

I’ve recently been challenging myself to learn a bit more conversational PowerShell as is where and the effort is beginning to pay off.
As with most programming or scripting languages, the going is slow to start off with (you don’t even know the comment character so you feel completely useless!) but it is making more and more sense the more I’m using it.

Basic operations can feel incredibly clunky but once you get why you have to do the hoop jumping by moving on to more complex scenarios, the necessity for accuracy become blatantly obvious.
I’m going to work through a few examples on here over the next couple of weeks so you can see the mad scientist side of my brain at work. Please bear in mind however, I am still learning. What you see here may not be the optimal solution but it will work I promise.

Also, although I know most people are ahead of this, I’m going to concentrate where possible on Windows 7’s version of PowerShell. It’s what we’re running at work and the scripts produced should be compatible with later versions. If I find differences, I’ll document them. ūüôā

Deleting and Recreating Printers Using a VB Script (Part 1)

This post expands on some concepts that I first touched on in this post which was about how you can create a backup script which can be run for a user’s connected printers.

On a similar note, I thought I’d throw in this one which I recently used for the migration of some users’ printers after a large office move. As the printers had moved with them and the printer name contained a code for the building it was in, the change was first carried out on the server to rename the affected queues, then the clients required attaching to these new queues to allow printing.

I originally thought whether it would be good practice to remove all network printers on the target PC (as shown in this post) but instead I decided to go for a more elegant and targeted solution (see Part 2). As is usual, the script below goes through the basics of what we need; Option Explicit, dimming variables, error handling and so on are omitted for the sake of brevity.
In this first example, let’s see how easy it is to remove all network printers from a user’s profile. OK, so let’s get started…

First off, we need to let the script know we’re talking about this PC and that we want to run a WMI query on the printers in the user’s profile. We also want to set up the objNetwork variable (as we’ll need that to add or remove network printers).

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") 
Set colPrinters = objWMIService.ExecQuery("Select * From Win32_Printer")

Set objNetwork = CreateObject("WScript.Network")

 

Now, we want to go through that list of printers, checking if each one is a network printer and deleting it if that’s the case.

For Each objPrinter in colPrinters
    If objPrinter.Attributes And 16 Then
        objNetwork.RemovePrinterConnection objprinter.name   
    End If
Next

 

And that’s it. You’ve now deleted all the network printers on the PC. The IF statement is the magic bit as it checks whether the printer is recognised as “16” or networked.

In part 2 I’ll show how I made this framework into something a little more targeted.

Back up Network Connected Printers via a VBScript

The following script can be used to back up all network printers connected to Windows. Its been tested on Windows XP (SP2 and SP3) and Windows 7.

The script simply outputs to the command window the syntax for a restoration script. Running this script from the command line, you’ll be able to control where this output goes rather than just being stuck with wherever I guess you want it.

Simply paste the following code to a vbs file of your choice then run it using the following command:
cscript <scriptname>.vbs //nologo > <target-filename>.vbs

Its a bit of a fiddle but it does mean this script is fire and forget. You’ll never need to change it if you server changes its name etc.

'Script to automatically generate a printer recreation script.
'The output of this script should be piped out to a .vbs file
'using the //nologo switch

Dim strDefaultPrinter

Wscript.Echo "'Automatically generated script to restore printers"
Wscript.Echo "'This script should be executed to recreate network printers only"
Wscript.Echo ""
Wscript.Echo "Set objNetwork = CreateObject(""WScript.Network"")"

strComputer = "."
strDefaultPrinter = "NotSet"

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colPrinters = objWMIService.ExecQuery("Select * From Win32_Printer")

For Each objPrinter in colPrinters
  If objPrinter.Attributes And 64 Then
    Wscript.Echo "' ** Local printer included for information only: " & objPrinter.Name
  Else
    strPrinterType = "objNetwork.AddWindowsPrinterConnection "
    Wscript.Echo strPrinterType & """" & objPrinter.Name & """"
    If objprinter.Default = True then
      StrDefaultPrinter = objPrinter.Name
    End If
  End If
Next

If StrDefaultPrinter <> "NotSet" then
  Wscript.Echo ""
  Wscript.Echo "objNetwork.SetDefaultPrinter " & """" & StrDefaultPrinter & """"
End If

Well, that’s a bit of a mouthful. Let’s break this script down so we know what’s going on.

The first portion of the script (I’m ignoring the preamble comment lines) is all about setting up variable and strDefaultPrinter which will be used later to set a default printer if its needed. We also make sure the script’s pointing at the current PC.
Next, we call the GetObject function to climb into the guts of Windows and set ourselves up for asking it a question.
The next line simply asks for a list of all installed printers.

The rest of the script steps through the list (For Each…. Next) and runs a couple of “If” statements to work out if the printer’s local (add a comment line) or networked (add a line to recreate the printer) then finally if it is a network printer, is it the default one.

When we’ve finished the loop, we drop out to a final If statement, this simply checks if the default printer was set by one of the network printers triggering the change. If not, it does nothing, if there is a default printer set, it adds the line.

Well, that’s it for now. Please slap a comment on the post if there’s any part you’d like walking through. As usual, this script represents a collection from ¬†a number of sources being skimmed for various lines of code.

Windows Explorer Command Line

Just because I’m that sad, I thought you might like a couple of handy ways to launch explorer so its where you want rather than drilling down to places.
Many people know the “Explorer X:\” trick that takes you to whatever you have as your¬†X drive but have you noticed it doesn’t have the folders listed in the left hand pane? Useless!

Here’s a few that you might not know. Let’s start with solving the problem above:

Explorer /e, X:\
That’s open explorer, with the default view (i.e. showing folders) to the¬†X drive

Explorer /e, X:\Work in Progress
Open my¬†X drive, open the Work in Progress directory, showing folders in the left hand pane (interestingly, there’s no need for speech marks even though the path contains spaces)

You can do:
Explorer /root, \\server_name\share
To open that file share, however you could just type in the path to the run box instead and it should open correctly anyhow!!

There you go, sad but may come in handy one day (when making shortcuts for users or whatever). You never know.

Update: For more, have a look at Microsoft’s Site where it details additional things like opening Explorer with a particular file highlighted and stuff. Genius!