Thursday, June 13, 2013

What I learned at the Scripting Games - Finale!

So check out the attached event description. http://scriptinggames.org/ab31cd51bb4dff5f19a7.pdf

This one was a lot more difficult than others in the series and not just because to test your script you needed a domain to test on!

They’re handling security issues, talking to DHCP, renaming PCs and joining them to domains!

What I saw in this event was bit scary from a security point of view. Many, many scripts with usernames and passwords hardcoded, sitting there in plain text! The justification being “well the instruction was to do that, so it’s ok”. But really credentials in plaintext is NEVER ok! The line has to be somewhere and if it’s not going to be with the boss dishing out the requirements it’s got to be with the guys doing the work! Just take the time and get this stuff right, how do we win over the Bash community if we’re hardcoding credentials into our scripts?

So this was my solution;
$macs = Get-Content c:\macs.txt
$ips = @()
$i = 1

Read-Host 'Please press ENTER to supply the credentials to use on the local servers' | Out-Null
$localcred = get-credential
$localadmin = $localcred.UserName
$localpassword = $localcred.getnetworkcredential().Password

read-host "Please press ENTER to supply Domain Admin credentials" | Out-Null
$admincred = get-credential
$domainadmin = $admincred.UserName
$domainpassword = $admincred.getnetworkcredential().Password
$Domain = "company.local"
$ou = ""

foreach ($mac in $macs)
{
    $ips += Get-DhcpServerv4Lease -cn DHCP1 -ScopeId 10.0.0.0 | where {$_.clientId -eq $mac} | Select-Object ipaddress
}

foreach ($ip in $ips)
{
    $name = "SERVER"+$i
    $pc = Get-WmiObject -computername $ip.ipaddress -class "win32_ComputerSystem" -credential $localcred -Authentication
    Write-Host "Renaming "$ip.IPAddress "to $name"
    $pc.rename($name, $localpassword, $localadmin)
    Restart-Computer -wait -ComputerName $ip.IPAddress
    Write-Host "Joining " $ip.IPAddress " to $Domain"
    $pc.JoinDomainorWorkGroup($Domain, $domainpassword, $domainadmin, $ou, 3)
    Restart-Computer -ComputerName $ip.IPAddress
    $i++
}

You’ll see that at the top of the script we’re asking for credentials from the user and use them in the loop for renaming machines and joining them to the domain. The way we’re capturing them is a bit clunky but this way we’re not storing credentials anywhere. Ok we’re storing them in RAM while the script runs if you want to be pedantic. This is probably one of the more secure methods that was used in Basic Event 6 and that makes me sad.

The rest is pretty self-explanatory. I hooked into WMI and used the JoinDomainorWorkGroup method and again I discovered I was doing things the hard way. There’s a powershell commandlet called add-computer that probably could have done the job.

What I’m noticing about researching things in powershell is that a lot of the blog posts that you find while googling for answers are written for powershell 1 or 2. We’re up to powershell 3 now and 4 is coming with server 2012 R2. There’s lots of new features and commands added each release so things are becoming easier but the knowledge of the “old ways” is still out there online kind of clogging up the ease of use.


The Powershell community needs to create a good way for the novices to find the quickest and easiest solutions to their scripting challenges. The Scripting Games has been a great way to do that. Not sure how well that would scale to millions of scripters but it’ll do for now!

No comments:

Post a Comment