Nate
Nate

Reputation: 65

I'm having issues trying to remotely install certificates on a list of servers using PowerShell

I've been tasked with updating some certificates on some remote servers. We have a TON of servers and not all of them have these certs installed.

To make a short story long....

There are 2 different certs that I'm looking for, we'll call the DevCert and CertCert. I have a list of ALL the servers in a .csv file on a remote server. I have a script that will go through all of the servers and check to see if either the Dev Cert or Cert Cert are installed. I have it working to where it will spit out 3 different output files: Results.csv, Dev.csv and Cert.csv. These output files have 3 columns, Server Name, Cert and Dev. Results lists every server and has a "Yes" in the column of which cert is installed or a "--" in both columns if neither cert is installed on that server. The dev.csv lists only the servers that have the Dev Cert and the Cert.csv only lists the servers with the Cert Cert installed. This was all working perfectly.

I then started to add the functionality to update just the Cert Cert, importing the Cert Cert from a remote server, and installing it on all the servers in the Cert.csv list. Here is my code:

$credential = Get-Credential -UserName MyUserName -Message 'Enter Password'

$Servers = Invoke-Command -ComputerName ServerName5000.domain -Credential $Credential -ScriptBlock { Get-Content -Path "E:\Temp\Servers.csv" } | Select-Object -Skip 1

$devThumbprint =  "ThumbPrint"
$certThumbprint = "ThumbPrint"

Write-Host "Processing..."

$results = foreach ($Server in $Servers) {
   $devCertExists = Invoke-Command -ComputerName $Server -Credential $credential -ScriptBlock { Test-Path Cert:\LocalMachine\My\$using:devThumbprint }
   $certCertExists = Invoke-Command -ComputerName $Server -Credential $credential -ScriptBlock { Test-Path Cert:\LocalMachine\My\$using:certThumbprint }
   
   if ($devCertExists -and $certCertExists) {
      [PSCustomObject]@{
         ServerName = $Server
         DevCert = "Yes"
         CertCert = "Yes"
      }
   } elseif ($devCertExists) {
      [PSCustomObject]@{
         ServerName = $Server
         DevCert = "Yes"
         CertCert = "--"
      }
   } elseif ($certCertExists) {
      [PSCustomObject]@{
         ServerName = $Server
         DevCert = "--"
         CertCert = "Yes"
      }
   } else {
      [PSCustomObject]@{
         ServerName = $Server
         DevCert = "---"
         CertCert = "---"
      }
   }
   
   Write-Progress `
      -Activity "Processing servers..." `
      -Status "Processing server: $Server" `
      -PercentComplete (($Servers.IndexOf($s) + 1) / $Servers.Count * 100)
}


$certServers = $results | Where-Object { $_.CertCert -eq "Yes" }
foreach ($server in $certServers) {
   Invoke-Command -ComputerName ServerName5000.domain -Credential $credential -ScriptBlock {
      Import-PfxCertificate -FilePath "E:\Installs\Certcert.pfx" -CertStoreLocation Cert:\LocalMachine\My -Password (ConvertTo-SecureString -String 'WATERMELON' -AsPlainText -Force)
   }
}

This code seemed to work, it checked all my servers and sorted the ones that had the old Cert cert on it, but it turns out that it only installed the updated version of the cert onto ServerName5000.domain, which is where I wanted the list of servers to import the new cert FROM. So from doing some research I edited this block:

$certServers = $results | Where-Object { $_.CertCert -eq "Yes" }
foreach ($server in $certServers) {
   Invoke-Command -ComputerName ServerName5000.domain -Credential $credential -ScriptBlock {
      Import-PfxCertificate -FilePath "E:\Installs\Certcert.pfx" -CertStoreLocation Cert:\LocalMachine\My -Password (ConvertTo-SecureString -String 'WATERMELON' -AsPlainText -Force)
   }
}

to

$certServers = $results | Where-Object { $_.CertCert -eq "Yes" }
foreach ($server in $certServers) {
   Invoke-Command -ComputerName $server -Credential $credential -ScriptBlock {
     Import-Certificate -FilePath "E:\Installs\WildCardCert\wildcard2024Entrust.cert.sc.egov.usda.gov.pfx" -CertStoreLocation Cert:\LocalMachine\My -Password (ConvertTo-SecureString -String 'BIGFOOT' -AsPlainText -Force)
   }
}

Now, it still sorts all of my servers on the original list and tells me what certs are installed on which server, but it throws an error instead up installing the new cert:

Invoke-Command : One or more computer names are not valid. If you are trying to pass a URI, use the -ConnectionUri parameter, or pass URI objects instead of strings. At C:\Users\script.ps1:49 char:4

+ CategoryInfo          : InvalidArgument: (System.String[]:String[]) [Invoke-Command], ArgumentException
+ FullyQualifiedErrorId : PSSessionInvalidComputerName,Microsoft.PowerShell.Commands.InvokeCommandCommand

Can anyone point me in the right direction from here? Any ideas?

Upvotes: 0

Views: 75

Answers (0)

Related Questions