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

Install-ADDcoreComponent contains wrong redirPath #16

Open
PatrickOnGit opened this issue Mar 7, 2023 · 5 comments
Open

Install-ADDcoreComponent contains wrong redirPath #16

PatrickOnGit opened this issue Mar 7, 2023 · 5 comments
Labels
enhancement New feature or request

Comments

@PatrickOnGit
Copy link

PatrickOnGit commented Mar 7, 2023

The function tries to redirect default user / computer location to "OU=Provisioning" but the OU in SQLite is called "OU=Provision"

                #$RedirPath = "OU=Provisioning,OU=$($FocusHash['Stage']),OU=Tier-2,$DomDN"
                $RedirPath = "OU=Provision,OU=$($FocusHash['Stage']),OU=Tier-2,$DomDN"

This information should come out of the SQLite DB and not being hardcoded.

It should also use the well known GUIDs not the names:

                #$CompWKO = $WellKnownObjects | Where-Object {$_ -like "*CN=Computers,*"}
                $CompWKO = $WellKnownObjects | Where-Object {$_ -match '\:AA312825768811D1ADED00C04FD8D5CD\:'}

                # Corrected to "Users" and using wellknown GUID
                #$UserWKO = $WellKnownObjects | Where-Object {$_ -like "*CN=Computers,*"}
                $UserWKO = $WellKnownObjects | Where-Object {$_ -match '\:A9D1CA15768811D1ADED00C04FD8D5CD\:'}
@merddyin
Copy link
Owner

merddyin commented Mar 7, 2023

Good call out on the bad name...I believe I have this fixed in the active code base already, but I'll double check. As for using the wellknown GUID, that is a good idea...admittedly this was one of the items I was still working on figuring out how to do without using the Microsoft AD module. The active code base currently just calls the old DOS commands as I haven't had any time to work this item in the lab.

@merddyin merddyin added the enhancement New feature or request label Mar 7, 2023
@PatrickOnGit
Copy link
Author

I solved it this way (as the DOS commands didn't work)

                # Corrected to Provision
                #$RedirPath = "OU=Provisioning,OU=$($FocusHash['Stage']),OU=Tier-2,$DomDN"
                $RedirPath = "OU=Provision,OU=$($FocusHash['Stage']),OU=Tier-2,$DomDN"

                $WellKnownObjects = Get-ADObject -Identity $DomDN -Properties wellKnownObjects | Select-Object -ExpandProperty wellKnownObjects
                Write-Debug "$($LPB1)`t`tWellknownObjects:`r`n$($WellKnownObjects | Out-String)"

                # Update to use guid instead of DN as this changes after first run
                #$CompWKO = $WellKnownObjects | Where-Object {$_ -like "*CN=Computers,*"}
                $CompWKO = $WellKnownObjects | Where-Object {$_ -match '\:AA312825768811D1ADED00C04FD8D5CD\:'}
                Write-Verbose "$($LPB1)`t`tCurrent Computer OU:`t$CompWKO"
                
                # Corrected to "Users"
                #$UserWKO = $WellKnownObjects | Where-Object {$_ -like "*CN=Computers,*"}
                $UserWKO = $WellKnownObjects | Where-Object {$_ -match '\:A9D1CA15768811D1ADED00C04FD8D5CD\:'}
                Write-Verbose "$($LPB1)`t`tCurrent User OU:`t$UserWKO"

                #$NewCompWKO = $CompWKO -replace ($CompWKO.Split(':')[-1]),$RedirPath
                $NewCompWKO = $CompWKO -replace "(.*\:).*","`$1$RedirPath"
                Write-Verbose "$($LPB1)`t`tNew Computer OU:`t$NewCompWKO"

                #$NewUserWKO = $UserWKO -replace ($UserWKO.split(':')[-1]),$RedirPath
                $NewUserWKO = $UserWKO -replace "(.*\:).*","`$1$RedirPath"
                Write-Verbose "$($LPB1)`t`tNew User OU:`t$NewUserWKO"

                Write-Verbose "$($LPB2)`t`tAttempting to update default computers location"
                try {
                    Set-ADObject -Identity $DomDN -Add @{wellKnownObjects = $NewCompWKO} -Remove @{wellKnownObjects = $CompWKO}
                    Write-Verbose "$($LPB2)`t`tUpdate Default Computers:`tSuccess"
                }
                catch {
                    Write-Verbose "$($LPB2)`t`tUpdate Default Computers:`tFailed"
                    Write-Warning "Updating the default computers OU failed - Run 'redircmp.exe' manually"
                }

                Write-Verbose "$($LPB2)`t`tAttempting to update default users location"
                try {
                    Set-ADObject -Identity $DomDN -Add @{wellKnownObjects = $NewUserWKO} -Remove @{wellKnownObjects = $UserWKO}
                    Write-Verbose "$($LPB2)`t`tUpdate Default Users:`tSuccess"
                }
                catch {
                    Write-Verbose "$($LPB2)`t`tUpdate Default Users:`tFailed"
                    Write-Warning "Updating the default users OU failed - Run 'redirusr.exe' manually"
                }

@merddyin
Copy link
Owner

merddyin commented Mar 8, 2023

Yeah, using the redir DOS commands from PowerShell is a bit of a pain...especially if you are not an admin on the system in question and cannot run elevated. It can be worked around, but I'm trying to find a better approach that uses the API. I know it is possible to accomplish, it's just not straight forward and I have yet to find a good example online.

As for your own solve, unfortunately it isn't viable as it still depends on the Set-ADObject cmdlet to make the change. The updated copy of the Dev branch still has somewhat similar code unfortunately as, like I mentioned above, I haven't found the right fix yet. My current approach, because I'm for some reason loathe to comment out the code, is to allow the steps to be skipped via a switch (noredir) I added to the cmdlet.

As to why, I would note that avoiding the use of the Microsoft modules was a conscious choice initially just to avoid dependency issues in the event that the RSAT tools weren't available. Later, I discovered another issue that made this a necessity. Both Microsoft's ESAE model, and NISTs Zero Trust framework, stipulate the use of a Privileged Admin Workstation (PAW) from which all administrative activities should be performed. Also per both models, the admin performed work from the PAW should not have local administrative rights to the PAW to prevent potential misconfiguration or exposure of the PAW. As it turns out, both ADUC and the ActiveDirectory module require running elevated in order to effect changes to the directory, though ADUC is a bit inconsistent in this regard. For ADUC, this isn't a huge issue, as I have found a way to make it run without the elevation prompt and this allows the admin to make changes provided they have the required access. The ActiveDirectory module, on the other hand, has a hard coded elevation check that doesn't appear to be able to be bypassed (I cracked open the DLL and looked at the code).

Naturally this means that using the API is the correct way to go, once I figure out how to make it work. I planned to dive into the ActiveDirectory module code a bit deeper, but first I have to substantially progress my programming knowledge enough to understand all the twists and turns they have going on (you think my code is hard to follow)...or find a good example somewhere.

@PatrickOnGit
Copy link
Author

You should checkout the S.DS.P from Jiri Formacek. I makes use of S.DS.P PRotocol which is, like ADSI, on each Windows OS. But its a more basic and really fast protocol. The module is written nicely and allows to manage AD Objects. Not as simple as Microsoft module, but does not require ADWS and talks straight to LDAP(s).
Your code would get simpler by using the module as you wouldn't need all the DirectorySearcher and other .net parts. And it would simplify providing credentials instead of running it in the context of the current user.

@merddyin
Copy link
Owner

Thanks. I will certainly take a look at that module, though I'm not likely to use it to replace functionality. In actuality, there are actually several alternatives out there (such as AdsiPS and PSAD) that could also serve as replacements. While it might theoretically simplify my own code, so too would using the native Microsoft modules and just accepting their limitations. While the code would be somewhat simpler however, it wouldn't be simpler overall as it would in reality add many more lines of code that I had no hand in writing. Further, they may introduce a breaking change at some point. Mostly though, it's about removing external dependencies as much as possible, and figuring out how I can do things as efficiently as possible. I don't need general AD management functionality...I need specific AD management functionality to accomplish very specific tasks, and while my code may be verbose, it's all entirely functional in nature, with no extra fluff.

Now, naturally my stated goal of limiting dependencies leads to questions regarding the three plugins currently used with the module.

Nlog is actually part of the ModuleBuild framework that I use as part of all of my projects, and I admit it's mostly time and interest that keeps this a separate function. I might eventually write my own logging solution, but for now I can't beat the speed and completeness provided by NlogModule, which is not only a popular logging framework for many many web apps, but the module itself is a very small amount of code that rarely updates (last update is 2017).

For PSSqlite, it's a lack of knowledge around how the dll library is compiled and maintained, which comes from a general lack of programming knowledge overall that I am working to overcome...I'm learning, but slowly. I did have active plans to remove the dependency on the separate module by directly loading the already compiled dll, then writing more targeted functions that wrap the various queries into specific functions instead of using the general purpose ones. These plans have taken a back seat to the vNext effort at the present however, as vNext will shift the burden of DB queries to the API. No point in rewriting something that will be deprecated.

As for splitpipeline, I simply don't have the expertise to create a runspace management functionality on my own yet. From the little of the documentation I have been able to understand regarding creation of runspaces, it requires in depth knowledge of memory management that is simply beyond me for the moment. I can create some runspaces easily enough, but knowing how to do threadsafe updating to share execution status back to the calling thread was making my head spin.

I do acknowledge that it might be helpful to provide the ability to run with alternate credentials, and an early prototype had that capability. The issue with this however, was that it resulted in potential exposure of the admin creds. This is because, even though interactive login for admin accounts was blocked on standard workstations, this does not prevent use of the creds via PowerShell, and a secure string isn't actually all that secure as it turns out. While there are now things such as Microsoft's SecretManagement module to add more protection, admins should be using the PAW.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants