Link to home
Start Free TrialLog in
Avatar of Marc Davis
Marc DavisFlag for United States of America

asked on

PowerShell to install cert using CertUtil on Remote Servers

Hi,

I am trying to run a Powershell to install a cert on a remote machine.

I am using the Invoke-Command for the remote and the ScriptBlock with the Start-Process.

I know there is a credential parameter option and I have tried it with it and without. Same results. Also, the intent is to run it under the same user which it the default I believe with the absence of the -Credential.

The command I am executing is:

Invoke-Command -ComputerName "$an" -ScriptBlock  { Start-Process -Verb RunAs certutil.exe -f –p "$using:PFXPassword" –importpfx "$using:PFXFile"; write-host "Executed certutil" }

Open in new window


The response is:
Parameter cannot be processed because the parameter name 'p' is ambiguous. Possible matches include: -PassThru -PipelineVariable -FilePath.

So there is a -p on the CertUtil as well there are different -P's with the Start-Process hence the ambiguous.

How do I/can I work this to run the command?

What am I missing?

Any information would be greatly appreciated.
Avatar of footech
footech
Flag of United States of America image

The process you want to start is "certutil.exe".  Arguments that you wish to pass to it should be done so with the -ArgumentList parameter of the Start-Process cmdlet.  You can try this.
Start-Process -Verb RunAs -FilePath "certutil.exe" -ArgumentList "-f –p $($using:PFXPassword) –importpfx $($using:PFXFile)"

Open in new window

Sometimes you can pass all the arguments as a single string, other times it's helpful to break them up into a string array.
Avatar of Marc Davis

ASKER

Hi, that got past the error but it did not do anything.

It seems like it never executed the "certutil" and especially passing the argument list.

Am I misunderstanding what you are saying?

Thanks
Actually let me clarify...

Command that you identified @footech it works locally and I have to take off the $($using...) and just have the $PFXPassword and $PFXFile.

However, that *will not* do the remote as I need to run on other servers.

So this:

Invoke-Command -ComputerName "$an" -ScriptBlock  { Start-Process -Verb RunAs -FilePath "certutil.exe" -ArgumentList "-f –p $($using:PFXPassword) –importpfx $($using:PFXFile)"

Open in new window

gets me past the error on the ambiguous but it doesn't not  install the PFX.

In fact, if I put the $an as my local laptop machine it doesn't work either.

Any info on how to get that to run remotely?
$PFXFile will have to be available on the remote machine.  So if it points to a location on the c: drive on your local machine, that location also has to be available on the remote machine.  If it points to a UNC location, then you get into usage of CredSSP or other options to get around the Kerberos double-hop problem.

I would think it would run locally (though it would require running from an elevated prompt).  I can't test at the moment though.
But it's not at all saying anything. For all tense and purposes, it just completes.

One of the things I previously had was:

Invoke-Command -ComputerName "$an" -Credential -EnableNetworkAccess -ScriptBlock  { certutil.exe -f –p "$using:PFXPassword" –importpfx "$using:PFXFile" }

Open in new window



That worked fine locally but when I went to do a remote...I got an access is denied.

Now, the thing is this: I have admin on both machines so it was running under the elevated locally.

Even though I am admin on the remote machine, the only way (that I can see) of running with elevated on the remote is to do the RunAs on the Start-Process.

If I the certutil command (replacing the $PFXPAssword and $PFXFile (even though it's a UNC)  it runs without a problem.

So, the commands works. I just need to do the RunAs on the remote and if the remote is my local machine it, ideally should, still work there as well (part of a unit test).

But right now, when what you provided, it's not running locally (via remote) or anything. It gets around the ambiguous error but it does not do anything leaving the question if it's even firing the certutil.exe
Try adding the -Wait parameter for Start-Process, see if that gives you anything.
Well, this is a little bit interesting:

Invoke-Command -ComputerName "$an" -ScriptBlock { Start-Process -Verb RunAs -Wait -FilePath "certutil.exe" -ArgumentList "-f –p $using:PFXPassword –importpfx $using:PFXFile" }

Open in new window


It worked locally but it did not work remotely.

In either case though, working or not, it doesn't provide any output being that it was successfully imported or that it wasn't.

But in a nutshell still wasn't deployment remotely even with the RunAs.

Is there a way to do this?
Is this not able to done through Powershell? I thought it would but there are many issues happening there. Am I missing something there?
Usually you'll get some kind of return even with an error.  I was able to do some testing (with commands I knew wouldn't succeed).
Try adding the -NoNewWindow parameter, and see if you get some output back.

We don't really need to use Start-Process here either.  Another option would be something like
Invoke-Command -ComputerName "$an" -ScriptBlock { & certutil.exe -f –p $using:PFXPassword –importpfx $using:PFXFile }

Open in new window

The only reason why I did the Start-Process was for the RunAS on the remote.

Remember, I had this initially:

Invoke-Command -ComputerName "$an" -EnableNetworkAccess -ScriptBlock  { certutil.exe -f –p "$using:PFXPassword" –importpfx "$using:PFXFile" }

Open in new window


That worked and works but the issue why I started the StartProcess was the remote installation aspects. I was getting an access is denied even though was running under a domain account that had admin access on the local and remote server as well. The local worked. The remote got the access is denied.

That is the main thing I am trying to get working here.
So does $PFXFile point to a UNC location?  It's sounding like it does.  As I mentioned, if it points to a UNC location, then you get into usage of CredSSP or other options to get around the Kerberos double-hop problem.  This isn't an issue when you're running the command on the local machine, but it is when you run it on a remote machine.
Here's a couple links with more info.
https://docs.microsoft.com/en-us/powershell/scripting/learn/remoting/ps-remoting-second-hop?redirectedfrom=MSDN&view=powershell-6
https://blogs.technet.microsoft.com/ashleymcglone/2016/08/30/powershell-remoting-kerberos-double-hop-solved-securely/
Yes, it does. It really makes sense to because the cert has 73 SAN's and it's best to have it in one location and the PFX is imported from that location.

You are right. I treied with the Enter-PSSession and all and everything works *until* I have it I go on to one machine and have the PFX at a different UNC location and try to import. I get the Access is denied.

I will take a look at this but it sounds like Kerberos double-hop is a Powershell only issue because I think I would be able to do it in a C# app?

I am going to look at these and links and see as well.

Thx and will have a response soon.
I guess I am a little confused on this. This Kerberos double-hop speaks of 3 servers (ServerA, ServerC and ServerC).

I am actually not even using 3 servers. I am using 2. ServerA and ServerB

So I'm not how how this applies either.

What am I missing there? If there are 3 servers in the double-hop yet I am only using 2?
Just an FYI, the Kerberos double-hop issue applies to more than just PowerShell.

ServerA = the local machine
ServerB = the target machine of PS Remoting
ServerC = the target machine in the UNC path
Yeah, the ServerA was going to be the initiating machine (will not be my laptop) and ServerB, ServerC, ServerD, etc were all expected to access a UNC pointing to a file on ServerA.

But that didn't work in PowerShell and I suspect it has something to do with the something like the Kerberos double-hop albeit I don't know if the same thing entirely.

I even tried with PSEXEC and encountered the same though.

The solution I came up with is that I will use the UNC on ServerA and copy the PFX to ServerB, ServerC, ServerD, etc. On each server after I copied it I will then execute the Invoke-Command with the certutil providing the PFXFile parameter as the locale disk file (whereas when it was a UNC it was failing).
Then after the certutil is completed, I will them do an invoke-command to remote the items just copied.

I have tested that out on 3 servers and it's working as expected thus far.

Do you see or think of any reasons why not to pursue that process/direction?
ASKER CERTIFIED SOLUTION
Avatar of footech
footech
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks and very much appreciated. I got past the immediate hurdle but I will definitely look into the other because you are correct, it will happen again sometime.

Thanks!