The Surly Admin

Father, husband, IT Pro, cancer survivor

Single Click Script to Add a Computer to the Domain

This script was inspired by a simple script I saw posted on Spiceworks, you can find the original here.  I didn’t want to post my take on the script on Spiceworks because it seemed a little rude, but I had some problems with this script.  The primary one, and this one trumps all others, was that you’re storing an extended security password in clear text!  Now, you could protect it by putting security permissions around the share where this is located and those security permissions are going to be for people who would probably know that password anyway but it still didn’t work for me.  We need a more secure method.

First attempt at the script was a simple one where you simply prompt the user for their password every time you run the script, here it is:

$domain = "myDomain"
$user = "myUserAccount"

#Don't edit below this point
$password = Read-Host -Prompt "Enter password for $user" -AsSecureString
$username = "$domain\$user"
$credential = New-Object System.Management.Automation.PSCredential($username,$password)
Add-Computer -DomainName $domain -Credential $credential

This would work quite well, but as the OP pointed out in comments, it defeats the purpose of one click.  And he’s right.  So what do we do?  Luckily PowerShell gives an answer with the Get-Credentials cmdlet and a little massaging.  So my second take on the script is below, and it will take the credentials and store it in a file.  It also supports multiple users which is nice so you don’t have to create a central “domain adding” account and you don’t want to give your Administrator account password to every desktop support guy!

AddComputer.ps1

<#
Single Click script to add computer to the domain, securely.  Creates secure password hashes
on a per user basis and stores them where you indicate.

USAGE:     .\AddComputer.ps1 <parameters>

PARAMETERS:
-User           Required.  User name with authority in the domain to add computers
-Domain         Optional.  Name of your domain
-PathToCred     Optional.  Central path to where you store the credential files, can be a UNC

Recommended you edit the Param lines below to change the defaults to match your environment.

Examples:
.\AddComputer.ps1 -user memyselfandi
.\AddComputer.ps1 memyselfandi
.\AddComputer.ps1 -User memyselfandi -Domain myDomain -PathToCred u:\itcred

#>

Param (
 [String]$User = $(Throw "You must provide a user name"),
 [String]$Domain = "myDomain",
 [String]$PathToCred = "U:"
 ) # these are all default values, adjust to fit your environment

#Make sure our path string has a trailing backslash
If ($PathToCred[$PathToCred.Length - 1] -ne "\")
{    $PathToCred += "\"
}

#Now create file string
$File = $PathToCred + "JoinDomain-$User.crd"

#And find out if it's there, if not create it
If (-not (Test-Path $File))
{    (Get-Credential).Password | ConvertFrom-SecureString | Set-Content $File
}

#Load the credential file
$Password = Get-Content $File | ConvertTo-SecureString
$Credential = New-Object System.Management.Automation.PsCredential($User,$Password)

#Add the computer to the domain
Add-Computer -DomainName $Domain -Credential $Credential

Script works great, but there is one required parameter, the username (see line #22).  We could definitely set a default here but it will have to be overridden every time you want another user–if you have 6 desktop guys then setting the default to one of them doesn’t do you much good if you’re the one of the other 5 guys.  But before we solve that, let’s run through the script real quick.

Lines 21-25 get parameters from outside the script.  Named parameters are User, Domain and PathToCred.  The last two can be set with defaults to match your environment and the first one you have to supply in order for the script to work otherwise it’ll throw and error and quit.

Lines 28-30 I just make sure you have a trailing backslash on your path so when I construct a file path later it works.

Line 33 construct that file path.  This includes the user name so every person who uses this script will have their own secure password file.

Lines 35-38 checks to see if that user file exists.  If it doesn’t we’re going to use the Get-Credentials cmdlet to prompt you for your password and then save it to your user file.

Lines 41-42 load the user file and create a PsCredential object.  This is the object PowerShell uses to pass secure credentials to other cmdlets.  In our case, the Add-Computer cmdlet.

Line 45 this is is, what all of this was leading up to.  We use the Add-Computer cmdlet to add the localhost to the specified domain (either by setting the parameter or using the default domain) and use the credentials the user has inputted.

So the first time a user runs this script it will prompt them for their username and password (though we really only keep the password) and then adds the computer to the domain.  The next time that user uses this script it will automatically read their password from the user file and add that computer without prompting.

But we still haven’t solved the one-click issue because I still need to run the script with a parameter!  Which means opening PowerShell, going to where the script is kept and running it with the -User parameter.  The answer to this is a simple batch file customized for every user who is going to use this script.  Create a text file and call it by the user’s name with a .bat extension.

PowerShell.exe -ExecutionPolicy Bypass -File .\AddComputer.ps1 myName

That’s it, problem solved.  Now all a desktop user has to do is double click their script and it will automatically add that computer to the domain using their credentials, only prompting them for the password the first time.

So, what do we do if the password changes?!  Hmmm….

Advertisement

August 10, 2012 - Posted by | PowerShell | ,

7 Comments »

  1. Ok, bonus points if you can spot the fundamental flaw in the script….

    Comment by Martin | August 10, 2012 | Reply

    • workstations dont have powershell on it by default ????

      Comment by nehraaz | June 3, 2014 | Reply

      • Windows workstations have had PowerShell installed by default since Vista was released. In 2005. If you’re still on Windows XP then I simply can’t encourage you enough to finish your transition to Win7 or Win8! Good luck!

        Comment by Martin9700 | June 3, 2014

  2. […] Powershell is the Secure Credential object, or PSCredential object.  I even wrote about using it here and here.  But a recent script request over at Spiceworks has shed some light on the PSCredential […]

    Pingback by PSCredential Object Secure? « The Surly Admin | October 29, 2012 | Reply

  3. Thought I’d try your initial script, as I haven’t found one yet that functions on Win10 pro.
    Saved in notepad as .vbs.
    Ran it and received a script host error on line 1 character 1. It doesn’t like the $. Says invalid character with code of 800A0408.
    ??

    Comment by Kim | December 9, 2015 | Reply

    • Welcome Kim. Since it’s a PowerShell script saving it as a vbScript won’t work too well! Rename it to .ps1, open PowerShell and run it from there. This might help: http://ss64.com/ps/syntax-run.html

      Comment by Martin9700 | December 9, 2015 | Reply

      • Hahaha, well, I guess that would explain it.
        As you can tell, I don’t do much more than batch files. I tried to figure out how to do it with a batch file, but, discovered that it required netdom, which isn’t natively present in Win 7. Anyway, I digress, I renamed your script and ran it, of course I had to change the execution policy manually, but, it did run and returned a code of 1355, which I understand is ‘domain cannot be found/contacted’. I ran it on my network to try and that was an expected result. My only question would be, instead of setting the execution policy manually, can it not be added to the script to run before the join? I placed this: Set-ExecutionPolicy Unrestricted at the top of the script, but, it still failed to execute. Does there need to be a /force switch in it?
        Thank you for your help.

        Comment by Kim | December 9, 2015


Leave a Reply to PSCredential Object Secure? « The Surly Admin Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: