djoin.psm1
<# .Synopsis Create an DomainJoinFile to offline join a domain .DESCRIPTION This is a PowerShell frontend to the DJOIN.exe command which provides better discoverability and usability. Use -Verbose to see what DJOIN command gets executed, use -Verbose. .EXAMPLE PS> New-DomainJoinFile -Domain dev.contoso.com -ComputerName server1 -Path c:\temp\oldj PS> New-PSDrive -Name S1 -PSProvider FileSystem -Root \\Server1\c$ PS> mkdir S1:\Temp PS> Copy-Item c:\temp\oldj S1:\temp PS> Invoke-Command -computer server1 { Join-DomainUsingFile -Path c:\temp\oldb -WindowsPath C:\Windows -JoinLocalOS } #> function New-DomainJoinFile { [CmdletBinding(SupportsShouldProcess=$true)] Param ( # Name of the domain to join e.g. dev.Contoso.com [Parameter(Mandatory=$true,Position=0)] [String]$Domain, # Name of the computer to join the domain [Parameter(Mandatory=$true,Position=1)] [String]$ComputerName, # [Parameter(Mandatory=$true,Position=2)] [String]$Path, #Organization Unit (OU) where the account is created [Parameter()] [String]$MachineOU, # Reuse any existing account (password will be reset) [Parameter()] [Switch]$Reuse, # Skip account conflict detection, requires DCNAME (faster) [Parameter()] [Switch]$NoSearch, # Support using a Windows Server 2008 DC or earlier [Parameter()] [Switch]$DownLevel, # Return base64 encoded metadata blob for an answer file [Parameter()] [Switch]$Printable, # Include root Certificate Authority certificates. [Parameter()] [Switch]$RootCACerts, # Machine certificate template. # Includes root Certificate Authority certificates. [Parameter()] [String]$CertTemplate, # Semicolon-separated list of policy names. # Each name is the displayName of the GPO in AD. [Parameter()] [String]$PolicyNames, # Semicolon-separated list of policy paths. # Each path is a path to a registry policy file. [Parameter()] [String]$PolicyPaths, # Netbios Name of the computer joining the domain [Parameter()] [String]$NetBIOS, # Name of persistent site to put the computer joining the domain in. [Parameter()] [String]$PersistentSite, # Name of dynamic site to initially put the computer joining the domain in. [Parameter()] [String]$DynamicSite, # Name of primary DNS domain of the computer joining the domain. [Parameter()] [String]$PrimaryDNS ) # These statements and the use of single quotes are SECURITY CRITICAL. # Without these someone could do an injection attack (e.g. provider a parameter with a ";" to terminate the statement # and then start a new, evil, command. $Domain = [System.Management.Automation.Language.CodeGeneration]::EscapeSingleQuotedStringContent($Domain) $ComputerName = [System.Management.Automation.Language.CodeGeneration]::EscapeSingleQuotedStringContent($ComputerName) $Path = [System.Management.Automation.Language.CodeGeneration]::EscapeSingleQuotedStringContent($Path) $MachineOU = [System.Management.Automation.Language.CodeGeneration]::EscapeSingleQuotedStringContent($MachineOU) $CertTemplate = [System.Management.Automation.Language.CodeGeneration]::EscapeSingleQuotedStringContent($CertTemplate) $PolicyNames = [System.Management.Automation.Language.CodeGeneration]::EscapeSingleQuotedStringContent($PolicyNames) $PolicyPaths = [System.Management.Automation.Language.CodeGeneration]::EscapeSingleQuotedStringContent($PolicyPaths) $NetBIOS = [System.Management.Automation.Language.CodeGeneration]::EscapeSingleQuotedStringContent($NetBIOS) $PersistentSite = [System.Management.Automation.Language.CodeGeneration]::EscapeSingleQuotedStringContent($PersistentSite) $DynamicSite = [System.Management.Automation.Language.CodeGeneration]::EscapeSingleQuotedStringContent($DynamicSite) $PrimaryDNS = [System.Management.Automation.Language.CodeGeneration]::EscapeSingleQuotedStringContent($PrimaryDNS) $cmd = "djoin.exe /provision /domain '$Domain' /machine '$ComputerName' /savefile '$Path' " if ($PSBoundParameters.ContainsKey('MachineOU')) { $cmd += "/MACHINEOU '$MachineOU' " } if ($Reuse.IsPresent) { $cmd += "/Reuse " } if ($NoSearch.IsPresent) { $cmd += "/NoSearch " } if ($DOWNLEVEL.IsPresent) { $cmd += "/DOWNLEVEL " } if ($Printable.IsPresent) { $cmd += "/PRINTBLOB " } if ($RootCACerts.IsPresent) { $cmd += "/RootCACerts " } if ($PSBoundParameters.ContainsKey('MachineOU')) { $cmd += "/MACHINEOU '$MachineOU' " } if ($PSBoundParameters.ContainsKey('CertTemplate')) { $cmd += "/CertTemplate '$CertTemplate' " } if ($PSBoundParameters.ContainsKey('PolicyNames')) { $cmd += "/POLICYNAMES '$PolicyNames' " } if ($PSBoundParameters.ContainsKey('PolicyPaths')) { $cmd += "/POLICYPaths '$PolicyPaths' " } if ($PSBoundParameters.ContainsKey('NetBIOS')) { $cmd += "/NetBIOS '$NetBIOS' " } if ($PSBoundParameters.ContainsKey('PersistentSite')) { $cmd += "/PSITE '$PersistentSite' " } if ($PSBoundParameters.ContainsKey('DynamicSite')) { $cmd += "/DSITE '$DynamicSite' " } if ($PSBoundParameters.ContainsKey('PrimaryDNS')) { $cmd += "/PRIMARYDNS '$PrimaryDNS' " } if ($PSBoundParameters.ContainsKey("Verbose")) { Write-Verbose $cmd } if ($PSCmdlet.ShouldProcess($domain, "Domain join computer [$computerName]")) { Invoke-Expression $cmd } } <# .Synopsis Join a domain using a DomainJoinFile .DESCRIPTION This is a PowerShell frontend to the DJOIN.exe command which provides better discoverability and usability. .EXAMPLE PS> New-DomainJoinFile -Domain dev.contoso.com -ComputerName server1 -Path c:\temp\oldj PS> New-PSDrive -Name S1 -PSProvider FileSystem -Root \\Server1\c$ PS> mkdir S1:\Temp PS> Copy-Item c:\temp\oldj S1:\temp PS> Invoke-Command -computer server1 { Join-DomainUsingFile -Path c:\temp\oldb -WindowsPath C:\Windows -JoinLocalOS } #> function Join-DomainUsingFile { [CmdletBinding(SupportsShouldProcess=$true)] Param ( # Path to the DomainJoinFile [Parameter(Mandatory=$true,Position=0)] [ValidateScript({test-path $_})] [String]$Path, # Path to Windows directory in an offline image [Parameter(Mandatory=$true,Position=1)] [ValidateScript({test-path $_})] [String]$WindowsPath, # WindowsPath specifies the locally running OS [Parameter()] [Switch]$JoinLocalOS ) # These statements and the use of single quotes are SECURITY CRITICAL. # Without these someone could do an injection attack (e.g. provider a parameter with a ";" to terminate the statement # and then start a new, evil, command. $Path = [System.Management.Automation.Language.CodeGeneration]::EscapeSingleQuotedStringContent($Path) $WindowsPath = [System.Management.Automation.Language.CodeGeneration]::EscapeSingleQuotedStringContent($WindowsPath) if ($JoinLocalOS.IsPresent) { $TargetString = "Local computer [$(hostname)]" }else { $TargetString = "Offine computer" } if ($PSCmdlet.ShouldProcess($TargetString, "Use [$Path] to domain join")) { if ($JoinLocalOS.IsPresent) { djoin.exe /requestodj /LoadFile '$Path' /Windowspath '$WindowsPath' /LocalOS }else { djoin.exe /requestodj /LoadFile '$Path' /Windowspath '$WindowsPath' } } } |