DSCResources/myAdHelper.psm1
#Tries to get-module, if impossible then add necessary windows feature, then import module function LoadModuleFeature { Param ($Module, $Feature) if ((Get-Module -Name $Module -ListAvailable) -eq $null) { Write-Host "Adding Feature $Feature" Add-WindowsFeature $Feature -ErrorAction SilentlyContinue Write-Host "Adding Module $Module" Import-Module $Module -ErrorAction SilentlyContinue } } #allows to use hardcoded tokens in DSC configs, being replaced by real value function ReplacePartitionTokens { param ( [String]$Identity, [String]$Server, [System.Management.Automation.PSCredential]$Credential ) $myParams = @{ } + $PSBoundParameters $myParams.Remove('Ensure') | out-null $myParams.Remove('Identity') | out-null LoadModuleFeature -Module ActiveDirectory -Feature RSAT-AD-PowerShell try { $ADRootDSE = Get-ADRootDSE @myParams if ($ADRootDSE) { $Conf = $ADRootDSE.configurationNamingContext $Domain = $ADRootDSE.defaultNamingContext $Schema = $ADRootDSE.schemaNamingContext $Result = $Identity -Replace ("(?s)%%configuration%%", $Conf) -Replace ("(?s)%%domain%%", $Domain) -Replace ("(?s)%%schema%%", $Schema) } } catch [Exception] { $Err = $_.Exception.GetType().FullName + ' - ' + $_.Exception.Message $Result = $null } if ($Err) { Write-Host $Err } $Result } function myGetAdObject { [OutputType([System.Collections.Hashtable])] param ( [String]$Identity, [String]$Server, [String]$Filter, [String]$SearchBase, $Properties, [System.Management.Automation.PSCredential]$Credential ) $myParams = @{ } + $PSBoundParameters $myParams.Remove('Ensure') | out-null $myParams.Remove('Debug') | out-null $myParams.Remove('ErrorAction') | out-null $myParams.Remove('Verbose') | out-null LoadModuleFeature -Module ActiveDirectory -Feature RSAT-AD-PowerShell try { $myAdObject = Get-ADObject @myParams } catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { $Err = 'Object not found' } catch [Microsoft.ActiveDirectory.Management.ADServerDownException] { $Err = 'Server not ready' } catch [System.Security.Authentication.AuthenticationException] { $Err = 'Authentication rejected' } catch [Exception] { $Err = $_.Exception.GetType().FullName + ' - ' + $_.Exception.Message $myAdObject = $null } if ($Err) { Write-Host $Err } $myAdObject } function StartAndWaitWaitForProcessEnd { [CmdletBinding()] param ( [parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String]$Path, [String]$Arguments, [PSCredential]$Credential, [Int]$Delay = 7200, [String]$TaskName, [String]$ProcessToWaitFor ) if ( (Test-Path $Path) -eq $false) { throw "Unable to find file: $Path" break } $Parent = [io.path]::GetDirectoryName($Path) $ProcessName = [io.path]::GetFileNameWithoutExtension($Path) $TaskAction = New-ScheduledTaskAction -Execute $Path -Argument $Arguments -WorkingDirectory $Parent $Task = Register-ScheduledTask -TaskName $TaskName -Action $TaskAction -User $Credential.UserName -Password $Credential.GetNetworkCredential().Password -RunLevel Highest -ErrorAction SilentlyContinue -Force if ($Task -ne $null -and $Task.State -eq "Ready") { Start-ScheduledTask -TaskName $TaskName $start = [DateTime]::Now; $ProcessId = 0; do { Write-Verbose "Waiting for process to start: $Path" Write-Host "Waiting for process to start: $Path" $IsExchSetupRunning = IsProcessRunning -ProcessName $ProcessToWaitFor Start-Sleep -Seconds 3 } while ($IsExchSetupRunning -eq $false -and ([DateTime]::Now - $start).TotalSeconds -lt 60) if ($IsExchSetupRunning -eq $false) { throw "Unable to start process within 60 seconds: $Path" } else { Write-Verbose "Waiting for process to end: $Path" Write-Host "Waiting for process to end: $Path" $start = [DateTime]::Now; do { $IsExchSetupRunning = IsProcessRunning -ProcessName $ProcessToWaitFor Start-Sleep -Seconds 3 } while ($IsExchSetupRunning -eq $true -and ([DateTime]::Now - $start).TotalSeconds -lt $Delay) if ($IsExchSetupRunning -eq $true) { Write-Error "Process not finished: $Path" Stop-ScheduledTask -TaskName $TaskName } Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false -ErrorAction SilentlyContinue } } else { throw "Failed to start Scheduled Task $TaskName" } } #Checks whether setup is running by looking for if the ExSetup.exe process currently exists function IsProcessRunning { param ([string]$ProcessName) return ((Get-Process -Name $ProcessName -ErrorAction SilentlyContinue) -ne $null) } |