Today I post an updated version of the domain-join script I initially posted here.
In theory you can just replace the script with the new version – assuming you did not make any changes other then adjusting it to your domain / server-names.
What changed in the newer version:
- the top lines in the script hold the basic configuration parameters
- line 1: NetBIOS name of your Active Directory domain
- line 2: your DNS domain name
- line 3: your distinguished domain name / root DN of your domain
- line 4: your default OU for new workstations
- line 5: empty
- line 6: KeePass / Pleasant Password Server URL
- line 7: KeePass folder to store the password in
- the script now relies on the above parameters rather then specifying them in various areas in the script, making the whole use / adjustment of the script way easier
- advanced error handling
- after the user entered the computer name and his domain admin credentials the systems checks if it can connect to the domain and if the computer name already exists
- if the domain credentials are invalid (can be a non-admin – as long they are valid) you get a message explaining that the script will stop due to wrong credentials
- if the computer name already exists in the domain, you get a message about it and the script stops
- KeePass or Pleasant Password Server connection – if it fails to connect with the credentials provided, you get a message about it and the script will stop
- after the user entered the computer name and his domain admin credentials the systems checks if it can connect to the domain and if the computer name already exists
- adjusted messages with various colours
- white text – standard as it was before
- yellow text – highlighted information so it sticks better out for the end-user
- magenta text – handled error / failure message – this is an explanation that something stopped the script from going further
- red text – those are real PowerShell error messages – either due to not handled errors or if the error was handled plotted out to the screen as additional reference and help
For additional information, please look at the original post here.
This script is also mentioned on the API Examples page on the Pleasant Solutions web site here.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 | $MyDomainNetBIOS="CONTOSO" $MyDomain="contoso.local" $MyDomainDN="dc=contoso,dc=local" $MyDomainOU="OU=Computers,OU=USA,DC=contoso,DC=local" $KeepassURL = "https://pwdbserver01v.contoso.local:10001" $PWFolder = "Local Admins" $ScriptVersion = "1.4 - 9/5/2018 - Florian Rossmark" Clear-Host Write-Host "" Write-Host "" Write-Host "Welcome to the Domain-Join script" Write-Host "=================================" Write-Host "" Write-Host "" Write-Host "This script will do the following Steps:" Write-Host "----------------------------------------" Write-Host "- You enter the Computer Name / Host Name" -ForegroundColor Yellow Write-Host "- You enter Domain Admin credentials for a Domain-Join" -ForegroundColor Yellow Write-Host "- You enter credentials to access KeyPass Password server" -ForegroundColor Yellow Write-Host "" Write-Host "" Write-Host "Note: always type credentials without any domain-information ($MyDomainNetBIOS\) - the script will fail otherwise." Write-Host "" Write-Host "" Write-Host "" Write-Host "- The script will automatically create a KeyPass entry with all information" -ForegroundColor Yellow Write-Host "- The script will automatically create a specific local admin account for this machine" -ForegroundColor Yellow Write-Host "- The script will automatically rename the system to the given name" -ForegroundColor Yellow Write-Host "- The script will automatically join the system to the domain $MyDomain" -ForegroundColor Yellow Write-Host "" Write-Host "" Write-Host "Script Version: $ScriptVersion" Write-Host "" Write-Host "" pause #Upper area holds functions.. Function MakeUp-String([Int]$Size = 8, [Char[]]$CharSets = "ULNS", [Char[]]$Exclude) { $Chars = @(); $TokenSet = @() If (!$TokenSets) {$Global:TokenSets = @{ U = [Char[]]'ABCDEFGHJKLMNPQRSTUVWXYZ' #Upper case L = [Char[]]'abcdefghijkmnpqrstuvwxyz' #Lower case N = [Char[]]'23456789' #Numerals S = [Char[]]'!@$!@$!@$!@$' #Symbols }} $CharSets | ForEach { $Tokens = $TokenSets."$_" | ForEach {If ($Exclude -cNotContains $_) {$_}} If ($Tokens) { $TokensSet += $Tokens If ($_ -cle [Char]"Z") {$Chars += $Tokens | Get-Random} #Character sets defined in upper case are mandatory } } While ($Chars.Count -lt $Size) {$Chars += $TokensSet | Get-Random} ($Chars | Sort-Object {Get-Random}) -Join "" #Mix the (mandatory) characters and output string }; #avoid certificate issues Add-Type @" using System; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; public class ServerCertificateValidationCallback { public static void Ignore() { ServicePointManager.ServerCertificateValidationCallback += delegate ( Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors ) { return true; }; } } "@ [ServerCertificateValidationCallback]::Ignore(); #Script starts here... Clear-Host Write-Host "" Write-Host "" Write-Host "This script must be executed in a power-shell with elevated rights!" -ForegroundColor Yellow Write-Host "" Write-Host "" Write-Host "Stop the script with: CTRL + C any time..." Write-Host "" Write-Host "" Pause Clear-Host $ComputerName = Read-Host "Please enter new Computer Name" $DomainJoinCredentials = Get-Credential -Message "Enter your credentials for the domain join ($MyDomainNetBIOS) without the domain part" Try{ $ADSISearcherDE = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$MyDomain",$($DomainJoinCredentials.UserName),$($DomainJoinCredentials.GetNetworkCredential().password)) $ADSISearcher = New-Object System.DirectoryServices.DirectorySearcher($ADSISearcherDE,"(&(objectCategory=Computer)(name=$ComputerName))") $ADSISearcherResults = $ADSISearcher.FindAll() if ($ADSISearcherResults.Count -gt 0) { Clear-Host Write-Host "" Write-Host "" Write-Host "Computer account with this name '$ComputerName' already exists in the domain '$MyDomain'." -ForegroundColor Magenta Write-Host "" Write-Host "" Write-Host "You need to delete the account first or make sure you entered the right name." -ForegroundColor Magenta Write-Host "" Write-Host "" Write-Host "Script will stop now." -ForegroundColor Magenta Write-Host "" Write-Host "" Pause Exit } } Catch { Clear-Host Write-Host "" Write-Host "" Write-Host "Your Domain Admin credentials where wrong." -ForegroundColor Magenta Write-Host "" Write-Host "" Write-Host "Script will stop now." -ForegroundColor Magenta Write-Host "" Write-Host "" Write-Host "" Write-Host "================================================================================================================" Write-Host "Error Details:" Write-Host "==============" write-host "Caught exception:" -ForegroundColor Red write-host "Exception Type: $($_.Exception.GetType().FullName)" -ForegroundColor Red write-host "Exception Message: $($_.Exception.Message)" -ForegroundColor Red Write-Host "================================================================================================================" Write-Host "" Write-Host "" Pause Exit } $KeePassCredentials = Get-Credential -Message “Enter your credentials to access Keepass Server without the domain part” $localAdminUser = $("$ComputerName" + "_Admin") $PW = MakeUp-String(12) $PWencrypted = ConvertTo-SecureString $PW -AsPlainText -Force Clear-Host Write-Host "" Write-Host "" Write-Host "Checking KeePass to see if those credentials already exist" Write-Host "" Write-Host "" #Collecting MACs $colMACItems = get-wmiobject Win32_NetworkAdapter | Where-Object {$_.MACAddress -like "*:*"} foreach ($objMACItem in $colMACItems) { $MACobj = $objMACItem |select Description,MACAddress $MACs += $MACobj.MACAddress + " - " + $MACobj.Description + " " } #Collecting SN/ServiceTag and HW information $SN = "ServiceTag / SN: "+(Get-WmiObject win32_bios | select SerialNumber).SerialNumber $Model = "Model: "+(Get-WmiObject win32_computersystem | select Model).Model $Manufacturer = "Manufacturer: "+(Get-WmiObject win32_computersystem | select Manufacturer).Manufacturer $UEFIKey = wmic path softwarelicensingservice get OA3xOriginalProductKey $PWName = "Individual Admin Account on $ComputerName" $PWUser = $localAdminUser $PWPassword = $PW $PWDescription = "Hardware information: ===================== $Manufacturer $Model $SN UEFI BIOS Windows Key: ====================== $UEFIKey Known MAC Addresses: ==================== $MACs (MACs might be subject to change with Docking-Stations)" $tokenParams = @{ grant_type='password'; username=$KeePassCredentials.UserName; password=$KeePassCredentials.GetNetworkCredential().password;} Try{ $JSON = Invoke-WebRequest -Uri "$KeepassURL/OAuth2/Token" -Method POST -Body $tokenParams -ContentType "application/x-www-form-urlencoded" -UseBasicParsing $Token = (ConvertFrom-Json $JSON.Content).access_token } Catch { Clear-Host Write-Host "" Write-Host "" Write-Host "Your KeePass credentials did not work." -ForegroundColor Magenta Write-Host "" Write-Host "" Write-Host "Script will stop now." -ForegroundColor Magenta Write-Host "" Write-Host "" Write-Host "" Write-Host "================================================================================================================" Write-Host "Error Details:" Write-Host "==============" write-host "Caught exception:" -ForegroundColor Red write-host "Exception Type: $($_.Exception.GetType().FullName)" -ForegroundColor Red write-host "Exception Message: $($_.Exception.Message)" -ForegroundColor Red Write-Host "================================================================================================================" Write-Host "" Write-Host "" Pause Exit } $headers = @{ "Accept" = "application/json" "Authorization" = "$Token"} $GroupSearch = @{“search” = $PWFolder} $Group = Invoke-RestMethod -Method post -Uri "$KeepassURL/api/v4/rest/search"-body (ConvertTo-Json $GroupSearch) -Headers $headers -ContentType 'application/json' -UseBasicParsing $GroupID = $Group.Groups.Id $SearchPhrase = $PWUser $searchbody = @{“search” = $SearchPhrase} $Search = Invoke-RestMethod -Method post -Uri "$KeepassURL/api/v4/rest/search"-body (ConvertTo-Json $searchbody) -Headers $headers -ContentType 'application/json' -UseBasicParsing $SearchID = $Search.Credentials.Id $KeePassResultscnt = 0 ForEach($Result in $Search.credentials) { $CredentialID = $Result.id If ($Result.GroupId -eq $GroupID) { $KeePassResultscnt += 1 } } If ($KeePassResultscnt -ge 1) { Write-Host "Total number of results found: $cnt" -ForegroundColor Magenta Write-Host "" Write-Host "" Write-Host "ALERT - KeePass already has credentials for this system - can not proceed." -ForegroundColor Magenta Write-Host "==========================================================================" -ForegroundColor Magenta Write-Host "" Write-Host "Search-Phrase: $SearchPhrase" -ForegroundColor Magenta Write-Host "Search-Folder: $PWFolder" -ForegroundColor Magenta Write-Host "Amount of results found: $KeePassResultscnt" -ForegroundColor Magenta Write-Host "" Write-Host "" Write-Host "" Write-Host "Next Steps:" -ForegroundColor Magenta Write-Host "===========" -ForegroundColor Magenta Write-Host "- This script will exit now!" -ForegroundColor Magenta Write-Host "- No changes to the system of KeePass have been applied" -ForegroundColor Magenta Write-Host "- Go to KeePass and check if this is an old entry and can be renamed/moved" -ForegroundColor Magenta Write-Host "- Execute the script again" -ForegroundColor Magenta Write-Host "" Write-Host "" pause EXIT } Else { Write-Host "" Write-Host "" Write-Host "Writing new credentials to the KeePass server/database" Write-Host "" Write-Host "" $PWEntryDT = Get-Date -Format "O" $CredEntry = @{ Id = "00000000-0000-0000-0000-000000000000" Name = "$PWName" Username = "$PWUser" Password = "$PWPassword" Created = "$PWEntryDT" Modified = "$PWEntryDT" GroupId = "$GroupID" Notes = "$PWDescription" Url = "$ComputerName" } Invoke-RestMethod -Method post -Uri "$KeepassURL/api/v4/rest/credential/00000000-0000-0000-0000-000000000000"-body @(ConvertTo-Json $CredEntry) -Headers $headers -ContentType 'application/json' -UseBasicParsing Write-Host "" Write-Host "" Write-Host "Finished writing to KeePass server/database" Write-Host "" Write-Host "" } pause Clear-Host Write-Host "" Write-Host "" Write-Host "Please check the following information:" Write-Host "=======================================" Write-Host "" Write-Host "Computer Name: $ComputerName" -ForegroundColor Yellow Write-Host "local Admin: $localAdminUser" -ForegroundColor Yellow Write-Host "Admin-PW: $PW" -ForegroundColor Yellow Write-Host "" Write-Host "" Write-Host "Make sure the information above are correct!" Write-Host "" Write-Host "" Write-Host "Verify the local Admin and Admin-PW in KeePass!" -ForegroundColor Yellow Write-Host "" Write-Host "" pause Write-Host "" Write-Host "" Write-Host "All information are verified?" Write-Host "" Write-Host "" pause Clear-Host Write-Host "Checking and removing (if exists) old local user: $localAdminUser" Get-LocalUser -Name $localAdminUser | Remove-LocalUser Clear-Host Write-Host "Adding new local administrator account: $localAdminUser" New-LocalUser -Name $localAdminUser -Password $PWencrypted -AccountNeverExpires -PasswordNeverExpires -Description "System specific local administrator account" $NewUser = Get-LocalUser -Name $localAdminUser $AdminGroup = Get-LocalGroup -Name "Administrators" Add-LocalGroupMember -Name $AdminGroup -Member $NewUser Write-Host "" Write-Host "" Write-Host "Finished." Write-Host "" Write-Host "" pause Write-Host "" Write-Host "" Write-Host "Joining this system to the domain and reboot automatically - stay put" -ForegroundColor Yellow Write-Host "" Write-Host "" Write-Host "Note: The system will not reboot if an error occurs. Check the error message in case you see an error." -ForegroundColor Yellow Write-Host "" Write-Host "" Try{ Add-Computer -Domain $MyDomain -Credential $DomainJoinCredentials -NewName $ComputerName -Restart -Force -OUPath $MyDomainOU } Catch { Write-Host "" Write-Host "" Write-Host "Domain-Join did not work - Error:" -ForegroundColor Magenta Write-Host "" Write-Host "" Write-Host "" Write-Host "================================================================================================================" Write-Host "Error Details:" Write-Host "==============" write-host "Caught exception:" -ForegroundColor Red write-host "Exception Type: $($_.Exception.GetType().FullName)" -ForegroundColor Red write-host "Exception Message: $($_.Exception.Message)" -ForegroundColor Red Write-Host "================================================================================================================" Write-Host "" Write-Host "" Pause } Finally { Exit } |