Archive for April, 2010

PostHeaderIcon Microsoft Office 2010 And SharePoint 2010 Go RTM

Office Products Ready To Roll

As a Microsoft Fan-Man I am so happy to share my enthusiasm.  On April 16th we got the news

all went RTM.

But What Does RTM Mean?  What Does RTM Stand For?

RTM stands for “Release To Manufacturing” and it MEANS that it’s heading to market.  It’s first made available to customers with Software Assurance (SA), and will be making it’s way to us very soon.  Software Assurance folks get to download theirs on April 27th.  Suckers without it are just going to have to wait until May 1. 

Oh, those 4 days I’m going to be laughing, and rubbing it in the faces of people without SA.  No, not really

There’s still a virtual release on May 12, and there’s also a website to go along with that – http://www.the2010event.com

Gimme, Gimme, Gimme

I  can’t wait to get these installed in a production environment – Project Server administered via PowerShell, SharePoint 2010, Office 2010 distributed via App-V.

And Visual Studio 2010 pulling it all together with some slick apps. 

2010 is a great year

PostHeaderIcon PowerShell How To Ping a List of Computers

This quick free lesson in PowerShell teaches you how to use the ping class to get a list of offline computers.  It is fast and easy, and the results are much easier to work with than using ping.exe.

Using the .Net Ping Class

PowerShell is built for speed, and it leverages the .Net framework to make this happen. 

To check the computers status, a Ping request is sent to each computer in a list. 

To start pinging, an object of the Ping class is instantiated:

$ping = new-object system.net.networkinformation.ping

Easy, right?

This avoids having to use the sloppy mess of processing through the text returned by ping.exe.

What is the difference?

By using a .Net object for the ping results, we can still use the object that is returned.  We can save the objects themselves and reference them back later.  The beauty of PowerShell.  The Power.  We want (and get) much more information.  The results of

ping 192.168.1.1

is a wall of text (an array of 11 strings, actually,) while the result of

$ping.send(“192.168.1.1”)

Is a .Net object of the "system.net.networkinformation.pingreply” class.  A pingreply has a property (named ‘status’) that tells us if the ping was successful or not; the address of the ping; and the miliseconds that it takes to get the reply.

To get results that are usable, keep your ping replies in a variable of results, like this:

$pingreturns = $ping.send(“192.168.1.1”)

Alright, we’ve got the base now for finding out if the computer is reachable.

Get Your Computer List Ready

The list of computers we want to ping.  You don’t have to limit your list to only computers. If the network device has Internet Control Message Protocol (ICMP) available (most do) and turned on (depends), it will return pings when they are received. You could ping network printers, or routers, for example.

Here are some examples of loading the ping list:

Get Computer List From Textfile

If you have several computers that you want to check frequently, add them to a text file so it’s easy to save, and easy to update the file instead of modifying the script.

“computer1”,”computer2”,”192.168.1.100”,”192.168.1.1” | out-file c:\users\public\documents\pinglist.txt

Now you’ve got a text file.  Quake with fear, bitches!  Note the use of hostnames and IP Addresses.  It’s fine to do that, you can mix and match.  That list is 4 computers, not a collection of 2 computers listed by hostname and IP.

Update the list of computers as needed.

To load the list of computers:

$complist = gc c:\users\public\documents\pinglist.txt

Get Computer List Manually

$complist = “computer1”, “computer2”

Easy, simple, and easy.  To change the list, you’d change it in the script itself. 

Get Computer List From Other Parts Of The Script

$servers = get-qadcomputer –service domain.com *serv*

$complist = $servers | select name

This seems normal, but it’s actually different, because you’re saving a list of objects into $complist, instead of a list of strings.  Here’s the difference

PS C:\ScriptGenius> $stringlist = "Computer1", "Computer2"
PS C:\ScriptGenius> $stringlist[0]
Computer1
PS C:\ScriptGenius> $stringlist[0].gettype()

IsPublic IsSerial Name                                     BaseType
——– ——– —-                                     ——–
True     True     String                                   System.Object

Compare that to the item in the object list

PS C:\ScriptGenius> $objectlist = get-qadcomputer *work* | select name
PS C:\ScriptGenius> $objectlist[0]

Name
—-
SOFTGRIDWORK2

PS C:\ScriptGenius> $objectlist[0].gettype()

IsPublic IsSerial Name                                     BaseType
——– ——– —-                                     ——–
True     False    PSCustomObject                           System.Object

While the two seem at first to be the same:

$ping.send($stringlist[0])

Works.

$ping.send($objectlist[0])

Does not, but it is at least salvageable.  To make that ping work,  the name property of the psCustomObject (the computer account returned by get-qadcomputer) must be referenced.

$ping.send($objectlist[0].name)

Works.

Get Computer List From an IP Range

This will do an IP sweep for a subnet, pinging along the way.

1..254 | % {$ping.send(“192.168.1.$_”) | select address, status}

Putting it All Together

Now that we’ve seen the pieces, here’s how it all works together.

$computers = get-content C:\scriptgenius\computers.txt

$ping = new-object system.net.networkinformation.ping

$pingreturns = @()

foreach ($entry in $computers) {

  $pingreturns += $ping.send($entry)

}

An array is used here to collect multiple ping results.  When completed, this can be used like this.

$pingreturns[4].status

or

$pingreturns | ? {$_.status –ne “success”} | select address

Instead of piping that to “select address” we could just as easily take action on those failed IP addresses.  Like sending the list of offline computers to the administrative team on on-call person via email.

PostHeaderIcon Powershell for Windows: How To Move A Computer Account Using The Command Line

How to Move a Computer Account From Within Powershell

I’m going to show you how to move a computer account to its new OU in just one line.

Not only that, I don’t even need to know the name of the OU it’s going to be placed in. That piece of information is going to come from a reference computer that’s in the same department. In this case the computer that I’m referencing is actually the older system that the new pc is replacing, so I’m sure it will be the correct OU.

After I add the computer onto the domain it is created in the Computers container.  I don’t like the computer container because it’s not an OU and I can’t apply policies directly to it.  I don’t even know that I would apply GPO’s there if I could.  I probably wouldn’t.  But now that I can’t, it makes me furious!  Also worth mentioning is I do NOT pre-stage the computer.  Why?  Two reasons:

Why I Don’t Pre-Stage Computers In My Domain

  1. Because to pre-stage a computer I would have to know where it goes.  I do not know the OU that this computer should go in, so I cannot pre-stage it.  At least, I should say that statistically my chances of dropping it into the correct OU by luck alone aren’t great.
  2. Because I am bad like that.  You might be the type that pre-stages computers,  but I’m not.  Most of the time I am a messy type that uses PowerShell to clean up after my messes; and occasionally I’m a clean type that uses PowerShell to make it appear that I’m messy.

Using the .NET Framework with PowerShell to Work With AD

Microsoft’s PowerShell comes ready to use the .Net framework classes, so it is possible to use the System.DirectoryServices.DirectoryEntry and DirectorySearcher classes.  But even with the simplicity of PowerShell, that code starts out looking like this.

Note: The one line version of this is awesome and it’s coming up soon so keep reading

PS C:\Windows\system32> $domain = new-object directoryentry
New-Object : Cannot find type [directoryentry]: make sure the assembly containing this type is loaded.

See?  It doesn’t even start out easy.  This is gross.  Here’s how you can really create the object. If you try this, at least it works, but it’s even more confusing. 

PS C:\Windows\system32> $domain = new-object system.directoryservices.directoryentry
PS C:\Windows\system32>

No error.  Still, you’re just getting started with finding an Active Directory account.  Next, you would have to create a new object of type DirectorySearcher, set filters and then find the account, like this

$domainsearcher.FindOne()

That’s just to get one account, and you’ll still have to go through the steps getting the parent container of the reference account, finding the new account, updating the parent container attribute, then confirm changes.

My Boss Would Love it if I Pre-Staged My Computers in Active Directory

If accessing the .Net framework was all PowerShell could do to help me move an account, I think I would have given up.  If PowerShell were limited like this I would have gone back to pre-staging computers with AD Users and Computers, and my boss would have won. 

He would say to me “So, you have finally have seen the light.  I knew you would.  This PowerShell thing does not work, and you have no way to make your messy ways be clean.  This is why I tell all of you: keep the Computers OU clean, and pre-stage your computers”. 

Me crying while using Active Directory Users and ComputersHere’s a picture of me crying because I’m forced to use Active Directory Users and Computers

My boss loves it when I use this tool.  I do not.

Note:  I have removed this picture for 2 reasons:

1) You may never see me cry.

2) You may never see me use Active Directory Users and Computers.

A PowerShell Secret Weapon – Quest Activeroles ADManagement

For this little bit of PowerShell goodness, I use the Quest Activeroles Admanagement tools.  Microsoft now has cmdlets for working with Active Directory, but I’ve never used them.  Microsoft was too slow on this one, and Quest got it done. 

I will try the Microsoft variety, because I am a huge Microsoft fanman.  But so far, I just keep using the Quest tools because I know them and they’re second nature to me now.

Load the quest.activeroles.admanagement snapin to your PowerShell session.  This absolutely does not count towards my one line that I promised you because:

  1. You could have just as easily gotten into a ADManagement Shell, which is placed in your Programs Start Menu when you install the Quest snapin.
  2. You should already have this added to your profile, so the tools are loaded every time you start a session.

The Command To Script Moving a Computer

Given:

  • A computer (“new-pc”) added to the domain, and not prestaged.
  • A computer (“old-pc)” already on the domain and in the OU where “new-pc” is supposed to go.
  • An OU (“Mystery-OU”) that old-pc is and where new-pc goes.  Notice in the one-liner I do not use “Mystery-OU”, because I do not know what OU it is
  • A domain (“ilovepowershell.com”) in which new and old computers are organized into units of organization called OU’s.

move-qadobject –identity ‘ilovepowershell.com\new-pc’ –newparentcontainer (get-qadcomputer –service “ilovepowershell.com” old-pc).parentcontainer

 

Follow ILovePowerShell on Twitter

Real Time Web Analytics