Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Offline Domain Join with ADComputer fails when OU Path contains spaces because Start-ProcessWithTimeout doesn't properly quote arguments #608

Open
briantist opened this issue May 29, 2020 · 3 comments
Labels
bug The issue is a bug. help wanted The issue is up for grabs for anyone in the community.

Comments

@briantist
Copy link

briantist commented May 29, 2020

Details of the scenario you tried and the problem that is occurring

When using Offline Domain Join (RequestFile parameter) with the ADComputer resource, the process fails if the OU (Path parameter) contains spaces.

Running djoin.exe myself from the command line worked.

Verbose logs showing the problem

The error is very confusing:

PowerShell DSC resource MSFT_ADComputer  failed to execute Set-TargetResource functionality with error message: 
System.InvalidOperationException: Failed to create the Offline Domain Join (ODJ) request file for the computer account 'computer02' with 
the error code '87'. (ADC0014) 
    + CategoryInfo          : InvalidOperation: (root/Microsoft/...gurationManager:String) [], CimException
    + FullyQualifiedErrorId : ProviderOperationExecutionFailure
    + PSComputerName        : localhost

I was finally able to track down a log I never knew existed (C:\Windows\Panther\UnattendGC\setupact.log), where I could that a successful run (via command line) looked like this:

2020-05-28 19:45:35, Info                         [djoin.exe] Unattended Join: Begin
2020-05-28 19:45:35, Info                         [djoin.exe] Unattended Join: Provision computer account
2020-05-28 19:45:35, Info                         [djoin.exe] Unattended Join: 	Domain: ab.contoso.com
2020-05-28 19:45:35, Info                         [djoin.exe] Unattended Join: 	Machine:computer02
2020-05-28 19:45:35, Info                         [djoin.exe] Unattended Join: 	MachineOU:OU=Some Servers,OU=Operations,OU=Hosts,DC=ab,DC=contoso,DC=com
2020-05-28 19:45:35, Info                         [djoin.exe] Unattended Join: The operation will target the DC: dc102.ab.contoso.com
2020-05-28 19:45:35, Info                         [djoin.exe] Unattended Join: Provisioning blob will be saved to a file C:/ODJ/computer02.txt

An unsuccessful run (via DSC):

2020-05-28 19:46:55, Info                         [djoin.exe] Unattended Join: Begin
2020-05-28 19:46:55, Info                         [djoin.exe] Unattended Join: Provision computer account
2020-05-28 19:46:55, Info                         [djoin.exe] Unattended Join: 	Domain: ab.contoso.com
2020-05-28 19:46:55, Info                         [djoin.exe] Unattended Join: 	Machine:computer02
2020-05-28 19:46:55, Info                         [djoin.exe] Unattended Join: 	MachineOU:OU=Some

Suggested solution to the issue

The error occurs because when the ADComputer resource needs to run djoin.exe, it uses the common utility function Start-ProcessWithTimeout, which uses Start-Process. It creates an array of arguments for the -ArgumentList parameter, but Start-Process does not do quoting for you, so you must quote individual arguments yourself if they contain spaces.

This is covered in the documentation for Start-Process in the -ArgumentList parameter and in example 7.

Suggested solution is to apply proper quoting to the arguments passed, keeping in mind that however arcane, OU names could themselves contain quotes and backslashes and caret and all kinds of other characters that could mess up simple quoting.

The DSC configuration that is used to reproduce the issue (as detailed as possible)

Invoke-DscResource -Name ADComputer -ModuleName ActiveDirectoryDsc -Verbose -Property @{
    ComputerName = 'computer02'
    DnsHostName = 'computer02.ab.contoso.com'
    RequestFile = 'C:/ODJ/computer02.txt'
    Path = 'OU=Some Servers,OU=Operations,OU=Hosts,DC=ab,DC=contoso,DC=com'
} -Method Set

The operating system the target node is running

OsName               : Microsoft Windows Server 2016 Datacenter
OsOperatingSystemSKU : DatacenterServerEdition
OsArchitecture       : 64-bit
WindowsBuildLabEx    : 14393.3630.amd64fre.rs1_release.200407-1730
OsLanguage           : en-US
OsMuiLanguages       : {en-US}

Version and build of PowerShell the target node is running

Name                           Value                                                                
----                           -----                                                                
PSVersion                      5.1.14393.3471                                                       
PSEdition                      Desktop                                                              
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                                              
BuildVersion                   10.0.14393.3471                                                      
CLRVersion                     4.0.30319.42000                                                      
WSManStackVersion              3.0                                                                  
PSRemotingProtocolVersion      2.3                                                                  
SerializationVersion           1.1.0.1                                                              

Version of the DSC module that was used

PS C:\Windows\system32> gmo -li ActiveDirectoryDsc


    Directory: C:\Program Files\WindowsPowerShell\Modules


ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   6.0.1      ActiveDirectoryDsc                  Find-DomainController
@briantist
Copy link
Author

I tried to work around this by adding double quotes to the OU myself, as in:

Invoke-DscResource -Name ADComputer -ModuleName ActiveDirectoryDsc -Verbose -Property @{
    ComputerName = 'computer02'
    DnsHostName = 'computer02.ab.contoso.com'
    RequestFile = 'C:/ODJ/computer02.txt'
    Path = '"OU=Some Servers,OU=Operations,OU=Hosts,DC=ab,DC=contoso,DC=com"'
} -Method Set

This does successfully create the computer account in the correct OU, and it creates the ODJ file, but the rest of the commands in the DSC resource fail as it tries to move the computer to the "correct" OU and update its hostname for some reason, so the overall DSC run will fail.

@johlju
Copy link
Member

johlju commented May 31, 2020

Thanks for the detailed issue report! Sounds like the best it to make sure the argument MachineOU is properly quoted and escaped.

This article explains, as you said, that any character is allowed https://support.microsoft.com/en-us/help/909264/naming-conventions-in-active-directory-for-computers-domains-sites-and

Labeling this as help wanted so that someone in the community can run with it.

@johlju johlju added bug The issue is a bug. help wanted The issue is up for grabs for anyone in the community. labels May 31, 2020
@briantist
Copy link
Author

briantist commented May 31, 2020

One other possible (if unlikely) alternative, is to p/invoke the underlying functions that make ODJ possible, avoiding use of djoin.exe completely.

NetProvisionComputerAccount
NetRequestOfflineDomainJoin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug The issue is a bug. help wanted The issue is up for grabs for anyone in the community.
Projects
None yet
Development

No branches or pull requests

2 participants