FriedrichWeinmann / GPOTools

MIT License
84 stars 7 forks source link

How to map the identities inside DomainSysvol\GPO\Machine\Preferences\Groups\Groups.xml? #5

Open rgl opened 4 years ago

rgl commented 4 years ago

I've created a GPO (in the EXAMPLE domain) which adds the EXAMPLE\Domain Users group into the Remote Desktop Users group in Computer Configuration\Preferences\Control Panel Settings\Local Users and Groups pane:

image

Then I've exported the GPO with:

$env:PSModulePath ="$env:PSModulePath;$PWD" # $PWD contains this repo code.
import-module gpotools
mkdir xxx
Get-GPO RDP | Backup-GptPolicy -Path "$PWD\xxx"

Then in another domain, the MARS domain, I've tried to import it as:

PS C:\Users\vagrant\Desktop> Restore-GptPolicy -Path xxx -Name RDP

Action                   Step          Success Target
------                   ----          ------- ------
Importing Policy Objects Import Object True    @{DisplayName=RDP; Id=78987f77-3d9d-4a0e-8bd1-34c18d85ab44; Owner=EXA...
Update Gpo Permission    Success       True    RDP
Update Gpo Permission    Success       True    RDP
Update Gpo Permission    Success       True    RDP
Update Gpo Permission    Success       True    RDP
Update Gpo Permission    Success       True    RDP
Update Gpo Permission    Success       True    RDP
Update Gpo Permission    Success       True    RDP
Get-OU : Cannot bind argument to parameter 'DistinguishedName' because it is an empty string.
At line:187 char:71
+ ...  | Where-Object { -not (Get-OU -DistinguishedName $_.TargetOU -Server ...
+                                                       ~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-OU], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Get-OU

Get-OU : Cannot bind argument to parameter 'DistinguishedName' because it is an empty string.
At line:190 char:83
+ ... Exists | Where-Object { Get-OU -DistinguishedName $_.TargetOU -Server ...
+                                                       ~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-OU], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Get-OU

Even with those last error, Restore-GptPolicy seems to have done everything except the last step that calls Import-GptLink @common -Name $Name, which I think its safe to ignore for now, as its only related to create the link between the GPO and the domain (and I think its only failing because there is no OU in this example domain).

After the import, it has successfully created/restored the RDP GPO, but it didn't modify/translate/map EXAMPLE\Domains Users to MARS\Domain Users:

image

I've even tried to execute Restore-GptPolicy as:

Restore-GptPolicy -Path xxx -Name RDP -IdentityMapping @{'EXAMPLE\Domain Users' = 'MARS\Domain Users'}
Restore-GptPolicy -Path xxx -Name RDP -IdentityMapping @{'EXAMPLE\Domain Users' = 'Domain Users'}
Restore-GptPolicy -Path xxx -Name RDP -IdentityMapping @{'Domain Users' = 'Domain Users'}

But it didn't work, as the end result was the same.

This particular GPO stores its data in GPO\{567AD9E6-EFB4-4343-8FBB-450E06A69DA8}\DomainSysvol\GPO\Machine\Preferences\Groups\Groups.xml as:

<Groups clsid="{3125E937-EB16-4b4c-9934-544FC6D24D26}">
    <Group clsid="{6D4A79E4-529C-4481-ABD0-F5BD7EA93BA7}" name="Remote Desktop Users (built-in)" image="2" changed="2020-02-17 17:51:24" uid="{77C5D323-FB42-444B-9B55-B8B7CA514452}">
        <Properties action="U" newName="" description="RDP" deleteAllUsers="1" deleteAllGroups="1" removeAccounts="0" groupSid="S-1-5-32-555" groupName="Remote Desktop Users (built-in)">
            <Members>
                <Member name="EXAMPLE\Domain Users" action="ADD" sid="S-1-5-21-3337870207-1605875919-3034210958-513"/>
            </Members>
        </Properties>
    </Group>
</Groups>

Do you known why it didn't work? Or how I can make this work? Or do I have to handle groups.xml myself?

BTW, I'm using https://github.com/rgl/windows-domain-controller-vagrant to launch these example domains.

FriedrichWeinmann commented 4 years ago

Heya, thanks for bringing that up with the distinguished name and the OU - definitely need to catch this in a more graceful manner!

As for the group mapping: At the moment - unfortunately - it requires explicitly using the -Identity parameter and specifying which identities to include. The next version - which is already commissioned, I just need to find the time, probably first week of March - will see that fixed, along with some other issues in the current version.

Anyway, this should do it (and keep working after the update):

Get-GPO RDP | Backup-GptPolicy -Path "$PWD\xxx" -Identity 'Domain Users'

Why did the mapping not help?

It requires the export/backup to also have exported the identity. It is designed to allow you to map to entirely different names. I probably should add the ability to add mappings explicitly, no matter the previous export ...

FriedrichWeinmann commented 4 years ago

Also: Thank you for the very detailed report! I wish every report were that clear :)

rgl commented 4 years ago

I failed to mention that I was using the current development version.

I redid the export using Get-GPO RDP | Backup-GptPolicy -Path "$PWD\xxx" -Identity 'Domain Users' but it didn't change anything, the exported files are the same (minus the backup id and dates).

So I'm not sure if I should have used the released version (installed with Install-Module GPOTools) or the development version.

BTW, thank you for creating this library that puts some sanity in this whole GPO enchilada!

rgl commented 4 years ago

I redid the test using the version from Install-Module GPOTools as:

Get-GPO RDP | Backup-GptPolicy -Path "$PWD\yyy" -Identity 'Domain Users'

Then tried to restore with:

Restore-GptPolicy -Path yyy -Name RDP
Restore-GptPolicy -Path yyy -Name RDP -IdentityMapping @{'EXAMPLE\Domain Users' = 'Domain Users'}
Restore-GptPolicy -Path yyy -Name RDP -IdentityMapping @{'EXAMPLE\Domain Users' = 'MARS\Domain Users'}

But all failed at:


Action  : Importing Policy Objects
Step    : Import Object
Target  : @{DisplayName=RDP; Id=78987f77-3d9d-4a0e-8bd1-34c18d85ab44; Owner=EXAMPLE\Enterprise Admins; CreationTime=17/02/2020 17:50:27;
          ModificationTime=17/02/2020 17:51:24; WmiFilter=}
Success : True
Data    : {@{DisplayName=RDP; Id=78987f77-3d9d-4a0e-8bd1-34c18d85ab44; Owner=EXAMPLE\Enterprise Admins; CreationTime=17/02/2020 17:50:27;
          ModificationTime=17/02/2020 17:51:24; WmiFilter=}, C:\Users\vagrant\Desktop\yyy\GPO\MARS.TEST.migtable}
Error   :

Could not find imported identities to match. Please run Import-GptIdentitiy first!
At C:\Program Files\WindowsPowerShell\Modules\GPOTools\0.1.0\GPOTools.psm1:1803 char:4
+             throw 'Could not find imported identities to match. Pleas ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (Could not find ...dentitiy first!:String) [], RuntimeException
    + FullyQualifiedErrorId : Could not find imported identities to match. Please run Import-GptIdentitiy first!
FriedrichWeinmann commented 4 years ago

Hm ... curious :( Really should work with the -Identity parameter.

Also the error really shouldn't be happening! (Importing identities is the first step in the restore process) "Should" ... truly an awesome word ^^ Will look into it tonight, when I'm off the clock.

FriedrichWeinmann commented 4 years ago

Apologies, didn't get to it and business interfered, will unfortunately not be able to get back to this before Sunday, sorry :(

rgl commented 4 years ago

No worries! Thanks for looking into it!

rgl commented 3 years ago

@FriedrichWeinmann, I've retried with 0.3.0 and it still shows the following errors:

Get-OU : Cannot bind argument to parameter 'DistinguishedName' because it is an empty string.
At C:\Program Files\WindowsPowerShell\Modules\GPOTools\0.3.0\GPOTools.psm1:2189 char:71
+ ...  | Where-Object { -not (Get-OU -DistinguishedName $_.TargetOU -Server ...
+                                                       ~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-OU], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Get-OU

Get-OU : Cannot bind argument to parameter 'DistinguishedName' because it is an empty string.
At C:\Program Files\WindowsPowerShell\Modules\GPOTools\0.3.0\GPOTools.psm1:2192 char:83
+ ... Exists | Where-Object { Get-OU -DistinguishedName $_.TargetOU -Server ...
+                                                       ~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-OU], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Get-OU

Those errors seem to map to the following source lines:

  1. https://github.com/FriedrichWeinmann/GPOTools/blob/0cee486e2ec37d3567c20bcdebe031b3ab9bbf35/GPOTools/functions/Import-GptLink.ps1#L195
  2. https://github.com/FriedrichWeinmann/GPOTools/blob/0cee486e2ec37d3567c20bcdebe031b3ab9bbf35/GPOTools/functions/Import-GptLink.ps1#L198

To fix this, is it correct to ignore all links which have an empty TargetOU property value? If so, can I submit a MR?