The following test script (RDPServices.ps1) works on the RD-Connection Broker (Windows Server 2019-1809) with both Windows PowerShell (5.1) and Certify The Web (5.4.3) without any problems:
Hi, have you tried other Logon Type options? I’ve found that different scripts behave differently and require different logon types depending on what they are actually trying to do.
Hello Christopher,
I think I found the cause.
Regardless of which authentication or which imperonation logon type is used, the script always runs as SYSTEM.
This works on the RD-Connection Broker, but not on the other servers.
What can I do so that the script runs as a domain administrator?
Thanks Dietmar, the service does always run as SYSTEM but should be able to impersonate the user on the network in most instances, impersonation is complicated though, did you try both New Credentials and Network?
As a workaround, write a powershell script to write out the variable values that your script requires to another script, and call it from a (weekly etc) scheduled task, that way you will have complete control over the deployment scheduling and the user it runs as.
You can either write variables out as JSON to a file, then read them from your script, or write out a wrapper script which in turn calls the same script you are currently using.
Hello Christopher,
I have tested all 15 combinations of Authentication and Impersonation Logon Type - a Notepad started by the script is always executed as SYSTEM.
Am I correct in assuming that this shouldn’t be the case?
If so, are there any plans to resolve this issue in the near future?
There is some complexity/varied behaviour when impersonating within a thread vs spawning a new process and vs network access, made more complex because we host PowerShell within our process rather than launching a new powershell command line instance (which could be the solution).
I should add that there is a difference between impersonation and processes. notepad.exe is an interactive desktop session process so won’t be supported.
Here is a powershell script which should show the identity impersonation in effect:
Running that script will show results in the log, and you can see that the environment loaded is still the primary users, but the windows identity is the impersonated user.
That doesn’t explain why your networked script doesn’t work, but it does demonstrate the basic impersonation.
As a follow up to this, I am working on an alternative option for both powershell scripts and .bat etc which just lets you launch a new process (we currently impersonate in-process). This takes care of subsequent spawned processes being under the correct user etc. Many script don’t need this, but some clearly do.
Hello Christopher,
Thank you for planning an alternative option for Powershell scripts, which ensures that subsequently generated processes run under the correct user.
Can you already let me know when this feature will be available?
Hi Dietmar, this features is currently under development & testing and is planned for the next release. Releases are just done when all the targeted features and testing is complete but it’s expected next week or the week after.
On member servers, the script only works with Windows PowerShell.
With Certify The Web I get the following error message for RDWebAccess and RDGateway:
Addition: With the new option “Launch New Process” I get the following error messages:
2021-07-25 15:43:15.603 +02:00 [INF] ---- Performing Task [On-Demand or Manual Execution] :: Run Powershell Script ----
2021-07-25 15:43:15.604 +02:00 [INF] Task [Run Powershell Script] :: Task is being has been forced to run. Normal status would be [Task is enabled but will not run because primary request unsuccessful.]
2021-07-25 15:43:15.605 +02:00 [INF] Executing command via PowerShell
2021-07-25 15:43:15.606 +02:00 [ERR] Launching Process C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe as User: DOMAIN\Administrator
Error Running Script: System.ComponentModel.Win32Exception (0x80004005): Zugriff verweigert
bei System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
bei Certify.Management.PowerShellManager.ExecutePowershellAsProcess(CertificateRequestResult result, String executionPolicy, String scriptFile, Dictionary2 parameters, Dictionary2 credentials, String scriptContent, PowerShell shell, Boolean autoConvertBoolean, String[] ignoredCommandExceptions, Int32 timeoutMinutes) in D:\a\certify-service\certify-service\src\certify-build\certify\src\Certify.Shared.Compat\PowerShellManager.cs:Zeile 270.
Error: System.InvalidOperationException: Diesem Objekt ist kein Prozess zugeordnet.
bei System.Diagnostics.Process.EnsureState(State state)
bei System.Diagnostics.Process.get_HasExited()
bei Certify.Management.PowerShellManager.ExecutePowershellAsProcess(CertificateRequestResult result, String executionPolicy, String scriptFile, Dictionary2 parameters, Dictionary2 credentials, String scriptContent, PowerShell shell, Boolean autoConvertBoolean, String[] ignoredCommandExceptions, Int32 timeoutMinutes) in D:\a\certify-service\certify-service\src\certify-build\certify\src\Certify.Shared.Compat\PowerShellManager.cs:Zeile 283.
Thanks, I’ll be investigating the new issue with starting powershell as a new process over the next couple days and if we get a fix it’ll be in the next update.
Getting the same error in 2026! I wish to automate the certificate deployment to RDS services in Server 2019, but I get the same “Object reference not set to an instance of an object” with the param($result) line. Did ANYONE get this working?
I’m using the DC admin credentials, tried ALL impersonation options to no avail. I even included the lines recommended by webprofusion to check what user is running, and even when setting authentication to local(specific user) using the admin credentials, and impersonation to NewCredentials, the script runs as SYSTEM!
Our scripts run locally (and by default using an in-process version of powershell), but the powershell command may try to invoke remote calls, which may or may not work, primarily because our Windows service is Local System which has restricted network impersonation abilities. Historically this is because the service needs to reliably write to the (system) Local Machine certificate store and update IIS bindings etc.
You may be able to make this work by creating a user that is a member of Administrators and using that for the Certify background service, which could allow impersonation to work more, but I haven’t test that personally, and in the current version any update will reset the service user. I wouldn’t recommend testing that in production however.
An alternative strategy that will work is to use an Export Certificate task to store the PFX in a path of your choice, then have a Windows Scheduled Task with your own powershell script which looks for the file and if present runs your own script to deploy it, then removes/moves the original file to mark it as completed.
As background, we are not RD admins and unlike yourself we have no expertise around it’s administration, we do not maintain a domain joined RD gateway and associated remote servers to test with. People use our app for deployment to many thousands of different service types, but they very often use their own scripts to deploy the actual cert to the service that requires it.
Thanks for your response. I guess I expected the included PS scripts to be more polished. The option to export the certificate seems better suited to my needs. I will explore that option.
Yep I totally understand, we retain those tasks for compatibility with existing managed certificate renewals.
In the future we will investigate the possibility of an external task runner job/broker system where the task runner runs under the required identity, it’s just quite a complex problem when you dig into it, especially as we are now cross-platform.