How can I use PowerShell to find a website's certificate? - powershell

I am trying to use PowerShell to query a website and see what SSL certificate (name) it is using for HTTPS bindings. Then I would like to trace back to see what CA issued the cert.
I am having trouble querying the website to find out what SSL certificate is bound. The IIS 7.5 GUI shows a friendly name.
After I get the websites SSL certificate the plan is to use PowerShell to search the Certificate stores by FriendlyName (or thumbprint, or some other value).
Here is what I have so far:
Query store for cert info:
get-childitem cert:\LocalMachine\my | ft issuer, subject, notafter, FriendlyName
check for active bindings
get-itemproperty 'IIS:\Sites\(SITENAME)' -name bindings
I'm not sure where this information is stored, and I have no luck searching for it with PowerShell, in the web.config and applicationhost.config. Google searching has not been helpful so far.
Any info, links to information, or documentation on how certs are handled / stored in IIS is appreciated.

To get the site SSL binding check out: IIS:\SslBinding
You can get the binding port like this:
dir IIS:\SslBindings | ? {$_.Port -eq 1443} | Select *
The Thumbprint and Store properties will be of interest.
You can get the actual cert using:
get-item cert:\LocalMachine\$theStore\$theThumbprint
e.g.
get-item cert:\LocalMachine\My\29F025A78F537D931A8CF05B00EB81DB84160CF3 | select *

Related

Dump subject CN, NotBefore, NotAfter from x509 custom folder

Since I am issuing certificates for my employees, I need to have a data table, namely subject CN, NotBefore, NotAfter. I tried to write a bat file using certutil as well as PS scripts from stackoverflow but never succeeded. There are too many certificates, I can't manually check each one. How can I get the name and expiration metrics from all the certificates that are in the folder? Thank you in advance for your response.

Powershell - Unable to look for a registry value

I have McAfee Drive Encryption installed on my Machine and trying to query the application using Powershell, however there is a really strange issue happening.
When i go the Uninstall Key in the registry, i can see McAfee Drive Encryption there, however it does not find it when i run the following command:
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Where { $_.DisplayName -match "McAfee Drive" } | select DisplayName, DisplayVersion
now i tried to simply put the code as: Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*
and it lists all the applications in there but not the McAfee Value!, i have tried this on another account / Machine and that worked fine, so wondering if anyone had a similar issue at all?
Any Help is appreciated.

If a particular certificate file .crt or .cer etc has been installed and is active

I am having difficulty trying to get if a particular certificate from a certain path on a drive eg "c:\path\MyCert.crt" has been installed and if it is active.
I have the following:
$crt = New-Object System.Security.Cryptography.X509Certificates.X509Certificate;
$crt.Import("c:\path\MyCert.crt");
write-host "MyCert.crt expires after: " $crt.GetExpirationDateString();
$crt.GetName();
Which displays:
MyCert.crt expires after: 11/12/2021 2:12:31 AM
C=..., O="...", OU=..., OU="...", CN=...
Tried:
[bool](dir cert:\LocalMachine\ | ? { $_.subject -like "cn=MyCert" })
but not sure if this tells me if it is installed and active?
Can someone please help.
Like #TessellatingHeckler suggested, you should compare thumbprints, as this will tell you if the specific certificate is installed. Otherwise you could end up getting but a true value even if the certificate has been renewed or something else has happened to change the cert.
The other problem you'll come across is that, by default, Get-ChildItem (alias DIR) won't search down a path recursively, so you'll only see the folders that a Certificate can live inside by running what you've got in your example:
[1] PS C:\> dir cert:\LocalMachine\
Name : TrustedPublisher
Name : ClientAuthIssuer
Name : Remote Desktop
Name : Root
Name : TrustedDevices
Name : CA
...
You'll also notice that importing a crt file as an 'X509Certificate' object won't show you the thumbprint. You have two options here, look at the file using the Get-PfxCertificate (I'm not sure when this was introduced so I'm not sure if you'll have it available), or you can import the crt file as an 'X509Certificate2' object.
Forgive me for expanding out the alias' in your snippet, but the following will do the trick:
$crt = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$crt.Import('c:\certs\CertFile.crt');
[bool](Get-ChildItem cert:\LocalMachine\ -Recurse | Where { $_.Thumbprint -eq $crt.Thumbprint })

Using New-SelfSignedCertificate for wildcard certificates

I have found this answer, but it doesn't seem to work when trying to create a wildcard certificate.
I have taken the following steps:
Added a certificate to my server with the Powershell command.
New-SelfSignedCertificate -DnsName myhostname01,*.myhostname01 -CertStoreLocation Cert:\LocalMachine\My
(I slightly censored the URL to avoid potentially unsafe situations).
Next, I used the SSL certificate in a binding on my IIS server.
I visited the page in Chrome. As expected, the certificate is marked unsafe.
I saved a local copy of the certificate, and manually added a copy of of the certificate to my Chrome trusted CA's. However, the certificate is still not recognized:
The details of the certificate look like this:
Now, the certificates and URL I am visiting and have set up in my hosts file are all the same. There are no spelling errors. My question: am I using New-SelfSignedCertificate wrong? Or am I doing something wrong somewhere else?
For anyone else who might arrive at this question clinging onto what's left of their sanity, the answer that ended up working for me was this:
New-SelfSignedCertificate -Subject *.my.domain -DnsName my.domain, *.my.domain -CertStoreLocation Cert:\LocalMachine\My -NotAfter (Get-Date).AddYears(10)
A SSL wild card certificate should have one subject with the wildcard and the rest of the DNS names should be in the Subject Alternative Name, which is provided by the DNSName parameter. I believe the example below will do what you want.
Example
New-SelfSignedCertificate -Subject *.myhostname01 -DnsName myhostname01 -CertStoreLocation Cert:\LocalMachine\My
dir Cert:\LocalMachine\My\ | Where-Object {$_.Subject -eq 'CN=*.myhostname01'} | ForEach-Object {
[PSCustomObject] #{
Subject = $_.Subject
SAN = $_.DnsNameList
}
}
Result
Subject SAN
------- ---
CN=*.myhostname01 {myhostname01}
References
Wikipedia - Wildcard Certicate
Technet - New-SelfSignedCertificate

How to trust a certificate in Windows Powershell

I am using Windows 7, and want to run signed scripts from Powershell, the security-settings of Powershell are set to "all-signed", and my scripts are signed with a valid certificate from my company. I have also added the .pfx-file to my local certificate store (right-clicked the pfx-file and installed).
However, when I start a signed script, I get a message that says:
"Do you want to run software from this untrusted publisher?
File Z:\Powershell Signed Scripts\signed.ps1 is published by CN=[MyCompanyName] and is not trusted on your system. Only run scripts from
trusted publishers.
[V] Never run [D] Do not run [R] Run once [A] Always run [?] Help
(default is "D"):"
Since I want to automatically call these scripts on my systems, I would like to add my imported certificate to the trusted list on my system, so that I do not get a message anymore when I run a signed script for the first time. How can I make my certificate a trusted one?
How to trust a certificate in Windows Powershell
Indeed, you can do this without any mmc :)
First, check the location of your personal certificate named for example "Power" :
Get-ChildItem -Recurse cert:\CurrentUser\ |where {$_ -Match "Power"} | Select PSParentPath,Subject,Issuer,HasPrivateKey |ft -AutoSize
(This one should be empty:)
gci cert:\CurrentUser\TrustedPublisher
Build the command with the path to your certificate:
$cert = Get-ChildItem Certificate::CurrentUser\My\ABLALAH
Next work on certificate store (Here I work on two certificate store : user & computer)
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store "TrustedPublisher","LocalMachine"
$store.Open("ReadWrite")
$store.Add($cert)
$store.Close()
Check, you should find your certificate :
ls cert:\CurrentUser\TrustedPublisher
Sounds like you need to verify that the script is signed properly and that you have the correct certificate installed in the correct certificate store.
Use the Get-AuthenticodeSignature cmdlet to get information about the signed script.
Also review Scott's guide for signing certificates.