9Mar/110
Don Jones Powershell Challenge – My Answers
This is my response to Don Jones Powershell Challenge posted on 9th March 2011.
The challenge can be found here
#Problem 1 Function Change-DataServerPassword() { <# .Synopsis Change the password for the service account on servers in a given OU .Description Changes the password used for a service on all computers in a given OU. By default this is the Database Servers OU, and the DataServer service. .Parameter OUName The name of the OU where the servers exist .Parameter ServiceName The name of the service you want to target .Parameter UserName The username for the account you want to use for the service (optional) .Parameter Password The password you want to set the service account to. .Example Change-DataServerPassword -Password MyNewPassword This will set the DataServer account password on all servers in the Database Servers OU. .Example Change-DataServerPassword -OUName AnotherOU -Password MyNewPassword This will set the DataServer account password on all servers in the AnotherOU OU. .Example Change-DataServerPassword -OUName AnotherOU -ServiceName AnotherService -Password MyNewPassword This will set the AnotherService account password on all servers in the AnotherOU OU. .Example Change-DataServerPassword -OUName AnotherOU -ServiceName AnotherService -UserName AnotherUserName -Password MyNewPassword This will set the AnotherService account password for the AnotherUserName account on all servers in the AnotherOU OU. .Notes Name: Change-DataServerPassword Author: Peter Rossi Last Edited: 9th March 2011 #> Param ( [parameter(Mandatory=$true,ValueFromPipeline=$False)][String[]]$OUName="Database Servers", [parameter(Mandatory=$true,ValueFromPipeline=$False)][String[]]$ServiceName="DataServer", [parameter(Mandatory=$false,ValueFromPipeline=$False)][String[]]$UserName, [parameter(Mandatory=$true,ValueFromPipeline=$False)][String[]]$Password ) $ADSearcher = new-object DirectoryServices.DirectorySearcher("(&(objectClass=organizationalUnit)(ou=$OUName))") $OUs = $ADSearcher.FindAll() #Assuming there is only one of these OU's $ThisOU = [ADSI]$OUs[0].Path ForEach($Child in $ThisOU.psbase.children) { if($Child.ObjectCategory -like '*computer*') { $svc=gwmi win32_service -filter "name='$ServiceName'" -ComputerName $Child.Name $inParams = $svc.psbase.getMethodParameters("Change") $inParams["StartName"] = $UserName $inParams["StartPassword"] = $Password $svc.invokeMethod("Change",$inParams,$null) $Message = "Changing Passowrd for $ServiceName on " + $Child.Name Write-Host $Message } } } #Problem 2 Function Get-DiskInventory() { <# .Synopsis Returns a report of all logical drives in a given list of servers where their disk space is below the threshold set by DiskSpaceRemaining .Description Queries a list of remote servers to return a disk space report for their logical drives. .Parameter ServerListFile The path to the text file with server names .Parameter DiskSpaceRemainingGB The amount of disk space remaining that you are concerned about. .Example Get-DiskInventory -ServerListFile c:\servers.txt This will return a report of all logical drives for the servers listed in c:\servers.txt .Example Get-DiskInventory -ServerListFile c:\servers.txt -DiskSpaceRemainingGB 10 This will return a report of all logical drives for the servers listed in c:\servers.txt where there is less than 10GB remaining. .Notes Name: Get-DiskInventory Author: Peter Rossi Last Edited: 9th March 2011 #> Param ( [parameter(Mandatory=$true,ValueFromPipeline=$False)][String[]]$ServerListFile, [parameter(Mandatory=$true,ValueFromPipeline=$False)][Int[]]$DiskSpaceRemainingGB=20 ) if((Test-Path $ServerListFile) -eq $False) { Write-Host "The Server List File Doesn't Exist" Return $null } Else { $DiskSpaceInKB = $DiskSpaceRemainingGB * 1024 * 1024 $Servers = Get-Content $ServerListFile $FinalData = @() ForEach($Server in $Servers) { $Disks = gwmi win32_logicaldisk -Filter "DriveType=3 and FreeSpace <= $DiskSpaceInKB" ForEach($Disk in $Disks) { $ARow = "" | Select Server,DriveLetter,FreeSpaceGB,TotalSizeGB,PercentFreeSpace $ARow.Server = $Server $ARow.DriveLetter = $Disk.DeviceID $ARow.FreeSpaceGB = $Disk.FreeSpace/1024/1024 $ARow.TotalSizeGB = $Disk.Size/1024/1024 $ARow.PercentFreeSpace = (($Disk.FreeSpace/$Disk.Size)*100) $FinalData += $ARow } } Return $FinalData } } #Problem 3 Function Get-ADComputerInfo { <# .Synopsis Returns a report of all computers in AD .Description Queries AD for all computers and returns their Windows Version, Service Pack Version and BIOS serial number .Parameter WindowsVersion The windows version you want to filter by (optional) .Parameter ServicePackVersion The Service Pack Version you want to filter by (optional) .Example Get-ADComputerInfo This will return a report of all servers in AD .Notes Name: Get-ADComputerInfo Author: Peter Rossi Last Edited: 9th March 2011 #> Param ( [parameter(Mandatory=$False,ValueFromPipeline=$False)][String[]]$WindowsVersion, [parameter(Mandatory=$False,ValueFromPipeline=$False)][String[]]$ServicePackVersion ) $ADSearcher = new-object DirectoryServices.DirectorySearcher("(&(objectClass=computer))") $Servers = $ADSearcher.FindAll() $FinalTable = @() ForEach($ServerObj in $Servers) { $Server = [ADSI]$ServerObj.Path $ARow = "" | Select Server,WindowsVersionNumber,BIOSSerial,ServicePackVersion $BiosInfo = gwmi win32_bios -ComputerName $Server.Name $ARow.WindowsVersionNumber = $Server.operatingSystemVersion $ARow.BIOSSerial = $BiosInfo.SerialNumber $ARow.ServicePackVersion = $Server.operatingSystemServicePack $OkToAdd = $True if($WindowsVersion) { if($ARow.WindowsVersionNumber -eq $WindowsVersion) { $OkToAdd = $True } Else { $OkToAdd = $False } } If($ServicePackVersion) { if($ARow.ServicePackVersion -eq $ServicePackVersion) { $OkToAdd = $True } Else { $OkToAdd = $False } } if($OkToAdd -eq $true) { $FinalTable += $ARow } } Return $FinalTable } #Problem 4 Function Add-Users() { <# .Synopsis Creates AD users for all users in a given CSV and adds the to the Employees group .Description Takes a CSV file of new users, creates them in AD and adds them to the Employees group. .Parameter ImportCSV The path to the CSV file with the users .Example Add-Users -ImportCSV c:\Users.csv This will import all users in c:\users.csv into AD .Notes Name: Add-Users Author: Peter Rossi Last Edited: 9th March 2011 #> Param ( [parameter(Mandatory=$True,ValueFromPipeline=$False)][String[]]$ImportCSV ) if((Test-Path $ImportCSV) -eq $false) { Write-Host "The file $ImportCSV doesn't exist" return $null } Else { $ImportData = Import-Csv -Path $ImportCSV $ADSearcher = new-object DirectoryServices.DirectorySearcher("(&(objectClass=group)(name=Employees))") $Groups = $ADSearcher.FindAll() $Group = [ADSI]$Groups[0].Path $GroupMembers = $Group.Members $OUSearcher = new-object DirectoryServices.DirectorySearcher("(&(objectClass=organizationalUnit)(ou=Users))") $UsersOUs = $OUSearcher.FindAll() $UserOuObj = $UsersOUs[0].Path ForEach($User in $ImportData) { $Message = "Adding User " + $User.UserName Write-Host $Message $usersOU = [adsi]$UserOuObj $UserName = $User.UserName $Department = $User.Department $Title = $User.Title $City = $User.City $newUser = $usersOU.Create("user","cn=$UserName") $newUser.put("title", $Title) $newUser.put("department", $Department) $newUser.put("physicalDeliveryOfficeName",$City) $newUser.SetInfo() $Group.Members = $GroupMembers + $newUser } } }



