Как мне создать скрипт PowerShell, способный выполнить вышеуказанную задачу?
Я создал коллекцию кодов, которые в конечном итоге составили сценарий PowerShell, в котором использовался командлет Add-Computer
для переименования компьютера, присоединения его к домену, перемещения его в подразделение на основе входных данных, предоставленных тот, который выполняет сценарий, и перезагрузите компьютер. Ранее мне давали информацию о том, что AD нельзя запрашивать (например, получать информацию о сайте AD) с компьютера рабочей группы, но в Интернете имеется множество статей о проверенных запросах LDAP с неподключенных компьютеров, поэтому это означает, что мне просто нужен правильный набор кодов.
Логика скрипта должна быть достаточно простой. Во время выполнения скрипт выполняет следующие действия ...
- получить подсеть компьютера (по его IP-адресу) и локальный DNS-сервер (также его локальный DC)
- запросить необходимые учетные данные для запроса LDAP (также используется для операции соединения)
- установить аутентифицированное соединение LDAP с сервером DNS / DC (полученное на шаге 1), чтобы запросить у AD информацию о сайтах
- получить имя сайта, соответствующее подсети, полученной на шаге 1
- определить, где создать / разместить результирующую учетную запись AD компьютера, на основе набора предварительно определенных условий в сценарии
- выполнить присоединение к домену (с необязательным переименованием компьютера) и создать / разместить учетную запись компьютера в правильном подразделении, полученном на шаге 5
- перезагрузите машину (необязательно, можно использовать подсказку Y / N)
Так далеко, вот мой код:
# CMD.exe /c powershell -executionpolicy bypass C:\scriptLocation\thisScript.ps1
# ==============================================================================
# Function RESTART Y-N
Function RestartYN {
$Restart=''
WHILE ($Restart -notin 'y', 'n') {
Write-Host "Please make sure to save your work if you wish to restart the computer now. " -foregroundcolor magenta -backgroundcolor white
Write-Host
Write-Host " Restart this computer now? (Y/N)? " -foregroundcolor black -backgroundcolor yellow
Write-Host " [ Y = NOW | N = LATER ] " -foregroundcolor black -backgroundcolor yellow -nonewline
$Restart = Read-Host
Write-Host
}
IF ($Restart -eq 'y') {
Write-Host
Write-Host "You have answered 'Yes'. Pressing any key will restart this computer... " -foregroundcolor yellow -backgroundcolor darkgreen
Write-Host
[void][System.Console]::ReadKey($true)
Write-Host "The computer is now RESTARTING..." -foregroundcolor magenta
Restart-Computer -force
}
ELSEIF ($Restart -eq 'n') {
Write-Host
Write-Host "You have answered 'No'. Changes will take effect when computer is restarted." -foregroundcolor yellow -backgroundcolor darkred
Write-Host
Write-Host "Ending this script... This session will end as soon as you press any key... " #-nonewline
Write-Host " " -nonewline
[void][System.Console]::ReadKey($true)
Write-Host
EXIT
}
}
# ==============================================================================
# Function Get credentials first
Function Get-CredsFIrst {
$Creds = Get-Credential -Message "Enter the domain account to use in executing this operation (eg. TESTDOMAIN\UserName):" -EA SilentlyContinue -WarningAction SilentlyContinue -ev getCredEV
$username = $creds.username
$password = $creds.GetNetworkCredential().password
# Get current domain using logged-on user's credentials
$CurrentDomain = "LDAP://" + ([ADSI]"").distinguishedName
$domain = New-Object System.DirectoryServices.DirectoryEntry($CurrentDomain,$UserName,$Password)
if ($creds -eq $null)
{
Write-Host
write-host "Credentials are empty. Please enter your credentials and make sure they are not empty." -foregroundcolor red -backgroundcolor white
Write-Host
Get-CredsFIrst
}
else
{
Write-Host
ExecJoin
}
}
# ==============================================================================
# Function: Execute Join: FINAL COMMAND if all else works: Join the computer to the domain, rename it, and restart it.
FUNCTION ExecJoin {
Write-Host " ~~~~~~ Attempting to perform requested operation. Please wait... ~~~~~~ " -foregroundcolor magenta -backgroundcolor white
$LocDN = "OU=$OU2,OU=OFFICES,DC=testdom,dc=net"
$Result=Add-Computer -DomainName testdom.net -OUPath $LocDN -Credential $Creds -NewName $WS_NewName -passthru -Errorvariable ACError -EA SilentlyContinue -WarningAction SilentlyContinue
Write-Host
IF ($Result.hasSucceeded)
{ Write-Host " ======== This computer has been successfully joined to TESTDOMAIN. ========= " -ForeGroundColor white -backgroundcolor darkgreen
Write-Host
Write-Host "----------------------------------------------------------------------------" -foreground green
Write-Host " CHANGES Successfully Made to this Computer" -foreground green
Write-Host " Please note that the following changes were " -nonewline
Write-Host "successfully" -foregroundcolor white -backgroundcolor darkgreen -nonewline
Write-Host " made "
Write-Host " to this computer as a result of this operation:"
Write-Host
Write-Host
Write-Host " * Computer's NEW NAME : " -nonewline
Write-Host $WS_NewName -foregroundcolor green
Write-Host
Write-Host " * Joined DOMAIN : " -nonewline
Write-Host "TESTDOMAIN" -foregroundcolor green
Write-Host
Write-Host " * OU (TWO-LETTER Code) : " -nonewline
Write-Host $OU2 -foregroundcolor green
Write-Host " "
Write-Host " * Location Name : " -nonewline
Write-Host $OUlong -foregroundcolor green
Write-Host " "
Write-Host
Write-Host " This computer has to be restarted for the changes to take effect. " -ForegroundColor black -backgroundcolor darkYellow
Write-Host
RestartYN
}
ELSE # ($Result.hasNotSucceeded)
{ Write-Host " ==== Error performing the operation. See resulting message below. ===== " -foregroundcolor white -backgroundcolor red
Write-Host
Write-Host $ACError[0].Exception.Message -ForegroundColor yellow # -backgroundcolor yellow
Write-Host
Write-Host "============================================================================" -foregroundcolor red
Write-Host
Write-Host
Write-Host " To resolve errors, please make sure the following prerequisite conditions are met:"
Write-Host
Write-Host " (1) Verify that this computer has not already been joined to TESTDOMAIN." -foregroundcolor yellow
Write-Host " Also make sure that this computer has no pending reboot requirement." -foregroundcolor yellow
Write-Host " (2) Verify PROPER DNS SERVER IP ADDRESS values in network adapter settings." -foregroundcolor yellow
Write-Host " A good indication is if you can SUCCESSFULLY PING the domain testdom.net." -foregroundcolor yellow
Write-Host " (3) Verify that you are using VALID CREDENTIALS and that the account has" -foregroundcolor yellow
Write-Host " the REQUIRED PERMISSIONS to join this computer to the domain." -foregroundcolor yellow
Write-Host " (4) Verify that the NEW COMPUTER NAME is VALID and AVAILABLE for use."-foregroundcolor yellow
Write-Host
Write-Host " If you would need assistance resolving the errors, please contact support." -foregroundcolor darkyellow
Write-Host
Write-Host " If you would like to retry this task without exiting, you may do so. " -foregroundcolor cyan -backgroundcolor darkgray
Write-Host
Pause
RETRY
}
}
# ==============================================================================
# Funtion: Retry if JOIN fails for whatever reason
Function Retry {
$Retry = ''
WHILE ($Retry -notin 'y', 'n') {
Write-Host " Would you like to RETRY this JOIN operation? (Y/N)" -foregroundcolor yellow
Write-Host " [Ctrl+C terminates script] " -foregroundcolor darkgray -nonewline
Write-Host
Write-Host ' [ Y - Retry | N - End ] ' -foreground yellow -nonewline
$Retry = Read-Host
Write-Host }
IF ($Retry -eq 'y') {
Write-Host
Write-Host "You have answered 'Yes'. You will need to define your parameters again. " -foregroundcolor darkgreen -backgroundcolor white
Write-Host
Pause
$WS_NewName = $null
$OU2 = $null
$OUlong = $null
clear-host
Define-Parameters
} ELSEIF ($Retry -eq 'n') {
Write-Host
Write-Host "You have answered 'No'. If you must retry, Please run this script again. " -foregroundcolor yellow -backgroundcolor darkgray
Write-Host
Write-Host "Ending this script... This session will end as soon as you press any key... " #-nonewline
Write-Host " " -nonewline
[void][System.Console]::ReadKey($true)
Write-Host
EXIT
}
}
# ==============================================================================
# Function: Y/N
FUNCTION YesOrNo {
$Answer = ''
WHILE ($Answer -notin 'y', 'n') {
Write-Host "If the parameters above are correct, you may proceed."
Write-Host "Otherwise, you can enter them again."
Write-Host
Write-Host "[Ctrl+C terminates script] " -foregroundcolor darkgray # -nonewline
Write-Host 'All correct and ready to proceed? [Y/N] ' -foreground yellow -nonewline
$Answer = Read-Host
Write-Host }
IF ($Answer -eq 'y') {
Write-Host
Write-Host "You have answered 'Yes'. You will now be asked for your user credentials. " -foregroundcolor darkgreen -backgroundcolor white
Write-Host
Pause
# Write-Host
Write-Host
Write-Host "Please enter your credentials for this operation and wait for the results. " -foregroundcolor magenta -backgroundcolor white
# Write-Host
Get-CredsFIrst
} ELSEIF ($Answer -eq 'n') {
Write-Host
Write-Host "You have answered 'No'. You will need to define your parameters again. " -foregroundcolor yellow -backgroundcolor darkgray
Write-Host
$WS_NewName = $null
$OU2 = $null
$OUlong = $null
Pause
Clear-Host
Define-Parameters
}
}
# ==============================================================================
# Function: Summary and confirmation screen for defined parameters.
FUNCTION Confirm-Parameters {
Write-Host "----------------------------------------------------------------------------" -foreground yellow
Write-Host " CONFIRM Your Parameters" -foreground yellow
Write-Host " Please confirm that you are joining this computer to " -nonewline
Write-Host "TESTDOMAIN" -foregroundcolor darkblue -backgroundcolor gray -nonewline
Write-Host " with" # -foreground yellow
Write-Host " the following parameters:" # -foreground yellow
Write-Host
Write-Host " * Computer's NEW NAME : " -nonewline
Write-Host $WS_NewName -foregroundcolor yellow
Write-Host
Write-Host " * TARGET location OU : " -nonewline
Write-Host $OU2 -foregroundcolor yellow
Write-Host " "
Write-Host " * Office location : " -nonewline
Write-Host $OUlong -foregroundcolor yellow
Write-Host " "
YesOrNo
}
# ==============================================================================
# Function: Define the parameters
Function Define-Parameters {
$WS_NewName = $null
$OU2 = $null
$OUlong = $null
Write-Host "----------------------------------------------------------------------------" -foreground cyan
Write-Host " DEFINE Your Parameters" -foreground cyan
Write-Host " Please enter needed values for joining this computer to " -nonewline
Write-Host "TESTDOMAIN" -foregroundcolor darkblue -backgroundcolor gray -nonewline
Write-Host ":"
Write-Host
Set-WSName
}
# Function Set New WS Name
Function Set-WSName {
$WS_NewName = $null
DO {
$WS_NewName = Read-Host -Prompt " * NEW NAME of computer (8-15 chars) "
} UNTIL ($WS_NewName.Length -gt 7 -and $WS_NewName.Length -lt 16) # -and $WS_NewName -notmatch '^\d+$' -and $WS_NewName -notmatch 'desktop*' -and $WS_NewName -match '^\w[\w-]*$')
''
$WS_NewName = $WS_NewName.ToUpper()
IF ($WS_NewName -match '^\d+$' -or $WS_NewName -match 'desktop*' -or $WS_NewName -notmatch '^\w[\w-]*$')
{
Write-Host "Warning: " -foregroundcolor yellow -nonewline
Write-Host "$WS_NewName" -foregroundcolor yellow -backgroundcolor darkgray -nonewline
Write-Host " is NOT valid as a new name." -foregroundcolor yellow
Write-Host
Write-host -foregroundcolor darkyellow "Name can consist of alphanumeric characters (A-Z, a-z, 0-9), but cannot "
Write-host -foregroundcolor darkyellow "consist purely of numeric ones (0-9), should not start with 'DESKTOP' or"
Write-host -foregroundcolor darkyellow "'desktop', and cannot contain spaces or periods (.). Please try again."
Write-Host
Set-WSName
}
Else {
SetOU
}
}
# ==============================================================================
# Function Set OU value
Function SetOU {
$OU2 = $null
$OUlong = $null
Write-Host
DO {
$OU2 = Read-Host -Prompt " * Target OU (TWO-LETTER location code) "
} UNTIL ($OU2 -match '^[a-z]{2}$')
''
$WS_NewName = $WS_NewName.ToUpper()
$OU2=$OU2.ToUpper()
IF ($OU2 -eq 'HQ') {
$OUlong = 'Head Quarters'
} ELSEIF ($OU2 -eq 'NA') {
$OUlong = 'North America'
} ELSEIF ($OU2 -eq 'SA') {
$OUlong = 'South America'
} ELSEIF ($OU2 -eq 'EU') {
$OUlong = 'Europe'
} ELSEIF ($OU2 -eq 'AS') {
$OUlong = 'Asia'
}
ELSE {
Write-Host "Warning: " -foregroundcolor yellow -nonewline
Write-Host "$OU2" -foregroundcolor yellow -backgroundcolor darkgray -nonewline
Write-Host " is NOT yet defined in script as an existing OU in AD." -foregroundcolor yellow
Write-Host
Write-Host "Value entered should be a valid 2-letter code for the office where the" -foregroundcolor darkyellow
Write-Host "computer being joined belongs to. Please make sure you enter a valid " -foregroundcolor darkyellow
Write-Host "OU (or contact support regarding this error." -foregroundcolor darkyellow
SetOU
}
$WS_NewName = $WS_NewName.ToUpper()
$OU2=$OU2.ToUpper()
Confirm-Parameters
}
# ==============================================================================
# Function: PAUSE
FUNCTION Pause ($Message = " Press any key to continue . . . ") {
IF ((Test-Path variable:psISE) -and $psISE) {
$Shell = New-Object -ComObject "WScript.Shell"
$Button = $Shell.Popup("Click OK to continue.", 0, "Script Paused", 0)
}
ELSE {
Write-Host " [Ctrl+C terminates script] " -foregroundcolor darkgray # -nonewline
Write-Host $Message -NoNewline
[void][System.Console]::ReadKey($true)
}
Write-Host
Write-Host
}
# ==============================================================================
# Funtion: RETRY-nwtest if previous nwtest fails for whatever reason
Function RETRY-nwtest {
$nwtestRetry = ''
WHILE ($nwtestRetry -notin 'y', 'n') {
Write-Host
Write-Host "Would you like to RETRY the name resolution check? (Y/N)" -foregroundcolor yellow
Write-Host "[Ctrl+C terminates script] " -foregroundcolor darkgray # -nonewline
Write-Host '[ Y - Retry | N - End ] ' -foreground yellow -nonewline
$nwtestRetry = Read-Host
Write-Host }
IF ($nwtestRetry -eq 'y') {
Write-Host
Write-Host "You have answered 'Yes'. Will now proceed to repeat name resolution check. " -foregroundcolor darkgreen -backgroundcolor white
Write-Host
Pause
$WS_NewName = $null
$OU2 = $null
$OUlong = $null
clear-host
TestNR
} ELSEIF ($nwtestRetry -eq 'n') {
Write-Host
Write-Host "You have answered 'No'. If you must retry, Please run this script again. " -foregroundcolor yellow -backgroundcolor darkgray
Write-Host
Write-Host "Ending this script... This session will end as soon as you press any key... " #-nonewline
Write-Host " " -nonewline
[void][System.Console]::ReadKey($true)
Write-Host
EXIT
}
}
# ==============================================================================
# Function: Test Name Resolution
FUNCTION TestNR {
Write-Host
Write-Host "Testing name resolution for domain name " -foregroundcolor magenta -backgroundcolor white -NoNewline
Write-Host "testdom.net" -foregroundcolor darkgreen -backgroundcolor white -NoNewline
Write-Host ". Please wait for result... " -foregroundcolor magenta -backgroundcolor white # -NoNewline
$testnrtask=Test-Connection -count 3 -ComputerName "testdom.net" -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
Write-Host
IF ($testnrtask.hasSucceeded)
{
Test-Connection -ComputerName "testdom.net" -count 1
Write-Host
Write-Host "This computer successfully resolves the name " -foregroundcolor green -nonewline
Write-Host "testdom.net" -foregroundcolor darkgreen -BackgroundColor white -nonewline
Write-Host ". Proceeding to the next step... " -foregroundcolor green
Write-Host
pause
Clear-Host
Define-Parameters
}
ELSE
{
Test-Connection -count 1 -ComputerName "testdom.net" -ErrorVariable tcerror -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
Write-Host
write-host $tcerror[0].Exception.Message -ForegroundColor Yellow
Write-Host
Write-Host "--------------------------------------------------------------------------- " -foregroundcolor yellow # -backgroundcolor white
Write-Host
Write-Host " Check your network connection status. Verify PROPER DNS SERVER IP ADDRESS" -foregroundcolor darkyellow # -backgroundcolor darkred
Write-Host " value(s) in your network adapter settings. A good indication of this" -foregroundcolor darkyellow # -backgroundcolor darkred
Write-Host " is if you can SUCCESSFULLY RESOLVE and PING the DNS domain name of the" -foregroundcolor darkyellow # -backgroundcolor darkred
Write-Host " Active Directory domain that you are joining (in this case, testdom.net)." -foregroundcolor darkyellow # -backgroundcolor darkred
Write-Host
Write-Host " After making the necessary corrections to your network settings, you may repeat this check. " -foregroundcolor darkcyan -backgroundcolor black
Write-Host
Pause
Write-Host
Write-Host
RETRY-nwtest
}
}
# ==============================================================================
# Function: CheckNW
FUNCTION CheckNW {
$choice = ''
WHILE ($choice -notin 'y', 'n') {
Write-Host "Would you like to check if name resolution is working for the name " -foreground darkyellow -nonewline
Write-Host "testdom.net" -foreground darkblue -backgroundcolor gray -nonewline
Write-Host "? (Y/N)" -foreground darkyellow
Write-Host "[Ctrl+C terminates script] " -foregroundcolor darkgray
Write-Host '[ Y - Check | N - Skip ] ' -nonewline
$choice = Read-Host
Write-Host }
IF ($choice -eq 'y') {
Write-Host
Write-Host "You have answered 'Yes'. Will now proceed with the name resolution check. " -foregroundcolor darkgreen -backgroundcolor white
Write-Host
Pause
Clear-Host
TestNR
} ELSEIF ($choice -eq 'n') {
Write-Host
Write-Host "You have answered 'No'. Will now skip the step to check name resolution. " -foregroundcolor yellow -backgroundcolor darkgray
Write-Host
$WS_NewName = $null
$OU2 = $null
$OUlong = $null
Pause
Clear-Host
Define-Parameters
}
}
# ==============================================================================
# START: Display name and purpose of invoked script
Set-ItemProperty -ea silentlycontinue "HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds" -Name "ConsolePrompting" -Value $True
$Path = $MyInvocation.MyCommand.Definition
Clear-Host
Write-Host " "
Write-Host -foreground cyan "Now running [" -nonewline
Write-Host $path -foregroundcolor yellow -nonewline
Write-Host -foreground cyan "]. This will allow you to do the following in a single-step process:"
Write-Host " "
Write-Host "(1)" -foreground gray -nonewline
Write-Host " RENAME " -foreground cyan -nonewline
Write-Host "this computer" -foreground gray
Write-Host "(2)" -foreground gray -nonewline
Write-Host " JOIN " -foreground cyan -nonewline
Write-Host "it to TESTDOMAIN" -foreground gray
Write-Host "(3)" -foreground gray -nonewline
Write-Host " MOVE " -foreground cyan -nonewline
Write-Host "it to target OU" -foreground gray
Write-Host "(4)" -foreground gray -nonewline
Write-Host " REBOOT " -foreground cyan
Write-Host " "
Write-Host " "
Write-Host "PREREQUISITE" -foreground darkmagenta -BackgroundColor gray -nonewline
Write-Host ": Please make sure you are configured with the correct DNS server IP address."
Write-Host " If so, you should be able to at least " -nonewline
Write-Host "PING testdom.net" -foreground darkyellow -nonewline
Write-Host "."
Write-Host " "
CheckNW
EXIT
Что я не смог понять, так это правильный код, который включал бы использование соединения LDAP для считывания информации сайтов AD с CN=Sites,CN=Configuration,DC=Testddom,DC=net
и код для создания необходимых IF
условий на основе сайтов. соответствие -to-OU, чтобы определить значение, которое следует использовать для переменной $OUlong
, которая должна содержать DN
из OU
, где должна быть размещена учетная запись AD компьютера (вместо ручного ввода от той, которая работает сценарий).