Skip to content

Commit 49b3657

Browse files
authored
Adding Options parameter to Computer resource (#381)
1 parent 4a66e7c commit 49b3657

File tree

5 files changed

+196
-3
lines changed

5 files changed

+196
-3
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
55

66
## [Unreleased]
77

8+
### Added
9+
- Computer
10+
- Support Options Parameter for domain join - Fixes [Issue #234](https://github.com/dsccommunity/ComputerManagementDsc/issues/234).
11+
812
## [8.5.0] - 2021-09-13
913

1014
### Added

source/DSCResources/DSC_Computer/DSC_Computer.psm1

Lines changed: 131 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ $FailToRenameAfterJoinDomainErrorId = 'FailToRenameAfterJoinDomain,Microsoft.Pow
4545
4646
.PARAMETER Server
4747
The Active Directory Domain Controller to use to join the domain.
48+
49+
.PARAMETER Options
50+
Specifies advanced options for the Add-Computer join operation.
4851
#>
4952
function Get-TargetResource
5053
{
@@ -84,7 +87,12 @@ function Get-TargetResource
8487

8588
[Parameter()]
8689
[System.String]
87-
$Server
90+
$Server,
91+
92+
[Parameter()]
93+
[ValidateSet('AccountCreate', 'Win9XUpgrade', 'UnsecuredJoin', 'PasswordPass', 'JoinWithNewName', 'JoinReadOnly', 'InstallInvoke')]
94+
[System.String[]]
95+
$Options
8896
)
8997

9098
Write-Verbose -Message ($script:localizedData.GettingComputerStateMessage -f $Name)
@@ -150,6 +158,9 @@ function Get-TargetResource
150158
151159
.PARAMETER Server
152160
The Active Directory Domain Controller to use to join the domain.
161+
162+
.PARAMETER Options
163+
Specifies advanced options for the Add-Computer join operation.
153164
#>
154165
function Set-TargetResource
155166
{
@@ -188,7 +199,12 @@ function Set-TargetResource
188199

189200
[Parameter()]
190201
[System.String]
191-
$Server
202+
$Server,
203+
204+
[Parameter()]
205+
[ValidateSet('AccountCreate', 'Win9XUpgrade', 'UnsecuredJoin', 'PasswordPass', 'JoinWithNewName', 'JoinReadOnly', 'InstallInvoke')]
206+
[System.String[]]
207+
$Options
192208
)
193209

194210
Write-Verbose -Message ($script:localizedData.SettingComputerStateMessage -f $Name)
@@ -247,6 +263,15 @@ function Set-TargetResource
247263
$addComputerParameters.Add("Server", $Server)
248264
}
249265

266+
if (-not [System.String]::IsNullOrEmpty($Options))
267+
{
268+
<#
269+
See https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/add-computer?view=powershell-5.1#parameters for available options and their description
270+
#>
271+
Assert-ResourceProperty @PSBoundParameters
272+
$addComputerParameters.Add('Options', $Options)
273+
}
274+
250275
# Rename the computer, and join it to the domain.
251276
try
252277
{
@@ -422,6 +447,9 @@ function Set-TargetResource
422447
423448
.PARAMETER Description
424449
The value assigned here will be set as the local computer description.
450+
451+
.PARAMETER Options
452+
Specifies advanced options for the Add-Computer join operation.
425453
#>
426454
function Test-TargetResource
427455
{
@@ -461,7 +489,12 @@ function Test-TargetResource
461489

462490
[Parameter()]
463491
[System.String]
464-
$Server
492+
$Server,
493+
494+
[Parameter()]
495+
[ValidateSet('AccountCreate', 'Win9XUpgrade', 'UnsecuredJoin', 'PasswordPass', 'JoinWithNewName', 'JoinReadOnly', 'InstallInvoke')]
496+
[System.String[]]
497+
$Options
465498
)
466499

467500
Write-Verbose -Message ($script:localizedData.TestingComputerStateMessage -f $Name)
@@ -648,3 +681,98 @@ function Get-LogonServer
648681
}
649682

650683
Export-ModuleMember -Function *-TargetResource
684+
685+
<#
686+
.SYNOPSIS
687+
This function validates the parameters passed. Called by Set-Resource.
688+
Will throw an error if any parameters are invalid.
689+
690+
.PARAMETER Name
691+
The desired computer name.
692+
693+
.PARAMETER DomainName
694+
The name of the domain to join.
695+
696+
.PARAMETER JoinOU
697+
The distinguished name of the organizational unit that the computer
698+
account will be created in.
699+
700+
.PARAMETER Credential
701+
Credential to be used to join a domain.
702+
703+
.PARAMETER UnjoinCredential
704+
Credential to be used to leave a domain.
705+
706+
.PARAMETER WorkGroupName
707+
The name of the workgroup.
708+
709+
.PARAMETER Description
710+
The value assigned here will be set as the local computer description.
711+
712+
.PARAMETER Options
713+
Specifies advanced options for the Add-Computer join operation.
714+
#>
715+
function Assert-ResourceProperty
716+
{
717+
[CmdletBinding()]
718+
param
719+
(
720+
[Parameter(Mandatory = $true)]
721+
[ValidateLength(1, 15)]
722+
[ValidateScript( { $_ -inotmatch '[\/\\:*?"<>|]' })]
723+
[System.String]
724+
$Name,
725+
726+
[Parameter()]
727+
[System.String]
728+
$DomainName,
729+
730+
[Parameter()]
731+
[System.String]
732+
$JoinOU,
733+
734+
[Parameter()]
735+
[System.Management.Automation.PSCredential]
736+
$Credential,
737+
738+
[Parameter()]
739+
[System.Management.Automation.PSCredential]
740+
$UnjoinCredential,
741+
742+
[Parameter()]
743+
[System.String]
744+
$WorkGroupName,
745+
746+
[Parameter()]
747+
[System.String]
748+
$Description,
749+
750+
[Parameter()]
751+
[System.String]
752+
$Server,
753+
754+
[Parameter()]
755+
[ValidateSet('AccountCreate', 'Win9XUpgrade', 'UnsecuredJoin', 'PasswordPass', 'JoinWithNewName', 'JoinReadOnly', 'InstallInvoke')]
756+
[System.String[]]
757+
$Options
758+
)
759+
760+
if ($options -contains 'PasswordPass' -and
761+
$options -notcontains 'UnsecuredJoin')
762+
{
763+
New-InvalidArgumentException `
764+
-Message $script:localizedData.InvalidOptionPasswordPassUnsecuredJoin `
765+
-ArgumentName 'PasswordPass'
766+
}
767+
768+
if ($Options -contains 'PasswordPass' -and
769+
$options -contains 'UnsecuredJoin' -and
770+
-not [System.String]::IsNullOrEmpty($Credential.UserName))
771+
{
772+
773+
New-InvalidArgumentException `
774+
-Message $script:localizedData.InvalidOptionCredentialUnsecuredJoinNullUsername `
775+
-ArgumentName 'Credential'
776+
}
777+
778+
}

source/DSCResources/DSC_Computer/DSC_Computer.schema.mof

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,7 @@ class DSC_Computer : OMI_BaseResource
99
[Write, Description("The name of the workgroup.")] String WorkGroupName;
1010
[Write, Description("The value assigned here will be set as the local computer description.")] String Description;
1111
[Write, Description("The Active Directory Domain Controller to use to join the domain")] String Server;
12+
[Write, Description("Specifies advanced options for the Add-Computer join operation"), ValueMap{"AccountCreate","Win9XUpgrade","UnsecuredJoin","PasswordPass","JoinWithNewName","JoinReadOnly","InstallInvoke"}, Values{"AccountCreate","Win9XUpgrade","UnsecuredJoin","PasswordPass","JoinWithNewName","JoinReadOnly","InstallInvoke"}] String Options[];
1213
[Read, Description("A read-only property that specifies the organizational unit that the computer account is currently in.")] String CurrentOU;
1314
};
15+

source/DSCResources/DSC_Computer/en-US/DSC_Computer.strings.psd1

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@ ConvertFrom-StringData @'
1616
CheckingWorkgroupMemberMessage = Checking if the machine is a member of workgroup '{0}'.
1717
DomainNameAndWorkgroupNameError = Only DomainName or WorkGroupName can be specified at once.
1818
ComputerNotInDomainMessage = This machine is not a domain member.
19+
InvalidOptionPasswordPassUnsecuredJoin = Domain Join option 'PasswordPass' may not be specified if 'UnsecuredJoin' is specified.
20+
InvalidOptionCredentialUnsecuredJoinNullUsername = 'Credential' username must be null if 'UnsecuredJoin' is specified.
1921
'@

tests/Unit/DSC_Computer.Tests.ps1

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,34 @@ try
683683
Assert-MockCalled -CommandName Add-Computer -Exactly -Times 0 -Scope It -ParameterFilter { $WorkGroupName }
684684
}
685685

686+
It 'Changes ComputerName and changes Domain to new Domain with Options passed' {
687+
Mock -CommandName Get-WMIObject -MockWith {
688+
[PSCustomObject] @{
689+
Domain = 'Contoso.com';
690+
Workgroup = 'Contoso.com';
691+
PartOfDomain = $true
692+
}
693+
}
694+
695+
Mock -CommandName Get-ComputerDomain -MockWith {
696+
'contoso.com'
697+
}
698+
699+
Mock -CommandName Add-Computer
700+
701+
Set-TargetResource `
702+
-Name $notComputerName `
703+
-DomainName 'adventure-works.com' `
704+
-Credential $credential `
705+
-UnjoinCredential $credential `
706+
-Options @('InstallInvoke') `
707+
-Verbose | Should -BeNullOrEmpty
708+
709+
Assert-MockCalled -CommandName Rename-Computer -Exactly -Times 0 -Scope It
710+
Assert-MockCalled -CommandName Add-Computer -Exactly -Times 1 -Scope It -ParameterFilter { $DomainName -and $NewName }
711+
Assert-MockCalled -CommandName Add-Computer -Exactly -Times 0 -Scope It -ParameterFilter { $WorkGroupName }
712+
}
713+
686714
It 'Should try a separate rename if ''FailToRenameAfterJoinDomain'' occured during domain join' {
687715
$message = "Computer '' was successfully joined to the new domain '', but renaming it to '' failed with the following error message: The directory service is busy."
688716
$exception = [System.InvalidOperationException]::new($message)
@@ -1179,6 +1207,35 @@ try
11791207
Get-LogonServer | Should -Not -BeNullOrEmpty
11801208
}
11811209
}
1210+
1211+
Context 'DSC_Computer\Assert-ResourceProperty' {
1212+
It 'Should throw if PasswordPass and UnsecuredJoin is present but credential username is not null' {
1213+
$errorRecord = Get-InvalidArgumentRecord `
1214+
-Message ($LocalizedData.InvalidOptionCredentialUnsecuredJoinNullUsername) `
1215+
-ArgumentName 'Credential'
1216+
1217+
{
1218+
Assert-ResourceProperty `
1219+
-Name $env:COMPUTERNAME `
1220+
-Options @('PasswordPass', 'UnsecuredJoin') `
1221+
-Credential $credential `
1222+
-Verbose
1223+
} | Should -Throw $errorRecord
1224+
}
1225+
1226+
It 'Should throw if PasswordPass is present in options without UnsecuredJoin' {
1227+
$errorRecord = Get-InvalidArgumentRecord `
1228+
-Message ($LocalizedData.InvalidOptionPasswordPassUnsecuredJoin) `
1229+
-ArgumentName 'PasswordPass'
1230+
1231+
{
1232+
Assert-ResourceProperty `
1233+
-Name $env:COMPUTERNAME `
1234+
-Options @('PasswordPass') `
1235+
-Verbose
1236+
} | Should -Throw $errorRecord
1237+
}
1238+
}
11821239
}
11831240
}
11841241
}

0 commit comments

Comments
 (0)