Присоединение компьютера к домену и размещение в правильном подразделении на основе членства на сайте AD - PullRequest
0 голосов
/ 03 июля 2018

Как мне создать скрипт PowerShell, способный выполнить вышеуказанную задачу?

Я создал коллекцию кодов, которые в конечном итоге составили сценарий PowerShell, в котором использовался командлет Add-Computer для переименования компьютера, присоединения его к домену, перемещения его в подразделение на основе входных данных, предоставленных тот, который выполняет сценарий, и перезагрузите компьютер. Ранее мне давали информацию о том, что AD нельзя запрашивать (например, получать информацию о сайте AD) с компьютера рабочей группы, но в Интернете имеется множество статей о проверенных запросах LDAP с неподключенных компьютеров, поэтому это означает, что мне просто нужен правильный набор кодов.

Логика скрипта должна быть достаточно простой. Во время выполнения скрипт выполняет следующие действия ...

  1. получить подсеть компьютера (по его IP-адресу) и локальный DNS-сервер (также его локальный DC)
  2. запросить необходимые учетные данные для запроса LDAP (также используется для операции соединения)
  3. установить аутентифицированное соединение LDAP с сервером DNS / DC (полученное на шаге 1), чтобы запросить у AD информацию о сайтах
  4. получить имя сайта, соответствующее подсети, полученной на шаге 1
  5. определить, где создать / разместить результирующую учетную запись AD компьютера, на основе набора предварительно определенных условий в сценарии
  6. выполнить присоединение к домену (с необязательным переименованием компьютера) и создать / разместить учетную запись компьютера в правильном подразделении, полученном на шаге 5
  7. перезагрузите машину (необязательно, можно использовать подсказку 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 компьютера (вместо ручного ввода от той, которая работает сценарий).

...