DSCResources/DSC_OfflineDomainJoin/DSC_OfflineDomainJoin.psm1
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidGlobalVars", "", Scope = "Function")] param ( ) $modulePath = Join-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent) -ChildPath 'Modules' # Import the ComputerManagementDsc Common Modules Import-Module -Name (Join-Path -Path $modulePath ` -ChildPath (Join-Path -Path 'ComputerManagementDsc.Common' ` -ChildPath 'ComputerManagementDsc.Common.psm1')) Import-Module -Name (Join-Path -Path $modulePath -ChildPath 'DscResource.Common') # Import Localization Strings $script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' <# .SYNOPSIS Joins the computer to a domain with a domain join file. .PARAMETER IsSingleInstance Specifies the resource is a single instance, the value must be 'Yes'. This value is Not used in Get-TargetResource. .PARAMETER RequestFile The full path to the Offline Domain Join Request file to use. This value is not used in Get-TargetResource. #> function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [Parameter(Mandatory = $true)] [ValidateSet('Yes')] [System.String] $IsSingleInstance, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] $RequestFile ) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.GettingOfflineDomainJoinMessage) ) -join '') <# It is not possible to read the ODJ file that was used to join a domain So it has to always be returned as blank. #> $returnValue = @{ IsSingleInstance = 'Yes' RequestFile = '' } return $returnValue } # Get-TargetResource <# .SYNOPSIS Sets the current state of the offline domain join. .PARAMETER IsSingleInstance Specifies the resource is a single instance, the value must be 'Yes'. .PARAMETER RequestFile The full path to the Offline Domain Join Request file to use. #> function Set-TargetResource { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateSet('Yes')] [System.String] $IsSingleInstance, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] $RequestFile ) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.ApplyingOfflineDomainJoinMessage) ) -join '') # Check the ODJ Request file exists if (-not (Test-Path -Path $RequestFile)) { New-InvalidArgumentException ` -Message ($script:localizedData.RequestFileNotFoundError -f $RequestFile) ` -ArgumentName 'RequestFile' } # if <# Don't need to check if the domain is already joined because Set-TargetResource wouldn't fire unless it wasn't. #> Join-Domain -RequestFile $RequestFile } # Set-TargetResource <# .SYNOPSIS Tests the current state of the machine joining a domain using an offline domain join file. .PARAMETER IsSingleInstance Specifies the resource is a single instance, the value must be 'Yes'. .PARAMETER RequestFile The full path to the Offline Domain Join Request file to use. #> function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( [Parameter(Mandatory = $true)] [ValidateSet('Yes')] [System.String] $IsSingleInstance, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] $RequestFile ) # Flag to signal whether settings are correct [System.Boolean] $desiredConfigurationMatch = $true Write-Verbose -Message ( @("$($MyInvocation.MyCommand): " $($script:localizedData.CheckingOfflineDomainJoinMessage) ) -join '') # Check the ODJ Request file exists if (-not (Test-Path -Path $RequestFile)) { New-InvalidArgumentException ` -Message ($script:localizedData.RequestFileNotFoundError -f $RequestFile) ` -ArgumentName 'RequestFile' } # if $currentDomainName = Get-DomainName if ($currentDomainName) { # Domain is already joined. Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.DomainAlreadyJoinedMessage -f $CurrentDomainName) ` ) -join '' ) } else { # Domain is not joined, so change is required. Write-Verbose -Message ( @("$($MyInvocation.MyCommand): " $($script:localizedData.DomainNotJoinedMessage) ) -join '') $desiredConfigurationMatch = $false } # if return $desiredConfigurationMatch } # Test-TargetResource <# .SYNOPSIS Uses DJoin.exe to join a Domain using a ODJ Request File. #> function Join-Domain { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [System.String] $RequestFile ) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.AttemptingDomainJoinMessage -f $RequestFile) ` ) -join '' ) $djoinResult = & djoin.exe @( '/REQUESTODJ' '/LOADFILE' $RequestFile '/WINDOWSPATH' $ENV:SystemRoot '/LOCALOS') if ($LASTEXITCODE -eq 0) { # Notify DSC that a reboot is required. $global:DSCMachineStatus = 1 } else { Write-Verbose -Message $djoinResult New-InvalidOperationException ` -Message ($script:localizedData.DjoinError -f $LASTEXITCODE) } # if Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($script:localizedData.DomainJoinedMessage -f $RequestFile) ` ) -join '' ) } # function Join-Domain <# .SYNOPSIS Returns the name of the Domain the computer is joined to or $null if not domain joined. #> function Get-DomainName { [CmdletBinding()] [OutputType([System.String])] param () # Use CIM to detect the domain name so that this will work on Nano Server. $computerSystem = Get-CimInstance -ClassName 'Win32_ComputerSystem' -Namespace root\cimv2 if ($computerSystem.Workgroup) { return $null } else { $computerSystem.Domain } } # function Get-DomainName Export-ModuleMember -Function *-TargetResource |