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

How to Use PowerShell to Create a Stopwatch and Alarm

So you want a quick and easy stopwatch with PowerShell to time how long you’ve been at a task?  Want to see how long it takes for your coworkers to realize you’re awesome?  Would you like to use PowerShell as a timer or alarm clock?   You can easily use PowerShell to keep track of how long an antivirus scan or checkdisk is taking on another system!

PowerShell contains many of the .NET class library by default, but there are thousands more waiting for you to connect them.

The Stopwatch class is available as part of the System.Diagnostics namespace. To gain access to the classes in it you have to load the namespace.

[System.Reflection.Assembly]::LoadWithPartialName(“System.Diagnostics”)

Once loaded, you can create a stopwatch object.

$sw = new-object system.diagnostics.stopwatch

now that you’ve got your stopwatch, you have access to the methods and properties of the stopwatch class:

Method
Usage
Notes
Start $sw.start() Begin the stopwatch counting
Stop $sw.stop() Stops the stopwatch counting
Reset $sw.reset() Stops the counter and sets elapsed to zero

 

Property
Usage
Notes
IsRunning $sw.IsRunning Returns True/False
Elapsed $sw.Elapsed Returns all elapsed information
.Days $sw.elapsed.days Integer (Int32) days
(how many whole days)
.Hours $sw.elapsed.hours Int32 Hours
.Minutes $sw.elapsed.minutes Int32 Minutes
.Seconds $sw.elapsed.seconds Int32 Seconds
.Milliseconds Int32 Milliseconds
.Ticks Int64 Ticks
.TotalDays You get the point
.TotalHours and
.TotalMinutes this table is getting
.TotalSeconds crowded
.TotalMilliseconds
ElapsedTicks $sw.elapsedticks does not require “elapsed.ticks”
ElapsedMilliseconds $sw.elapsedmilliseconds does not require “elapsed.milliseconds”
Excellent, dude.  I now know one more useless thing to do with PowerShell.

Wrong!  you now know 2 useless things to do with PowerShell:

Tracking Time and Setting Alarms

A note about this:  There IS a measure-command cmdlet in Powershell, which is great because it automatically starts the timer when the command starts, and ends it when the command is over.  But there are some drawbacks to using measure-command:

  • Output is suppressed, like this:

get-qaduser domain\me

returns my acct, but:

”measure-command {get-qaduser domain\me }”

returns the time it takes to get my acct. It does not output my user account to the screen.

  • It runs on only one script block.  If you want to time several commands, or check to see how long a whole process takes (especially if you have an external force like a coworker or other department) a measure-command isn’t going to work.

Things you can time: Here is just a small sample of things you can time.

  1. Your coworkers breaks (but not your own, right?)
  2. How long a Chkdisk or Defrag runs on a machine.
  3. How long it takes your coffee go cool off (or your Mountain Dew to warm up – try doing THAT with measure-command.
  4. How long it takes to parse through enormous lists of users/computers/anything else.

How to set an alarm: Want to work on a project for 20 minutes?  Or how bout start playing an annoying song 15 minutes after you leave for lunch?

while ($sw.elapsed.minutes –lt 20) {$null}; invoke-item “C:\users\public\Music\Sample Music\kalimba.mp3”

3 parts really make this work.

1) (elapsed.minutes -lt 20)  –  We identify our alarm time – in this case “don’t do anything until the timer hits 20 minutes”.

2) {$null}  – While we’re waiting we just do nothing.

3) invoke-item c:\music.mp3 – “invoke-item” means open the file with it’s default program – for me it plays in Media Player, or Winamp – depending on what machine I’m on.  

When the music plays, you know the timer is up!

ilovepowershell.com Quick-Commands:

Load the diagnostic objects:
[System.Reflection.Assembly]::LoadWithPartialName(“System.diagnostics”)

Create a stopwatch:
$sw = new-object system.diagnostics.stopwatch

Create an alarm:
while ($sw.elapsed.minutes –lt 20) {$null}; invoke-item “c:\users\public\music\sample music\kalimba.mp3”

All Praise To God

Dear God,

Thank you for blessing me with a love of learning and problem solving.  Because of the gifts you have given me, I am able to pass on these gifts to others.

I dedicate this site to you, and it is for you that I work and learn.  It is on your behalf that I spread the word through PowerShell.  Please bless this site to be a place where my technical friends can learn PowerShell and develop their scripting skills.  And please bless the readers of this site with a deeper understanding of not only PowerShell, but please come into their lives and bless them, too.

Thank you for all you do,

Michael