TechShizz | All posts tagged 'PowerShell'

How to update an IIS SSL certificate for an existing website using command line and PowerShell

If you need to install a new certificate on a web server that does not have a GUI (Server Core), you will need to update the current SSL certificate via command line and powershell. There are most likely more ways to do this than this method, but I find this works well for me.

1. First, if you need a new certificate, you need a new CSR. You DO NOT have to create the CSR on the server that will use the certificate. Use ANY IIS server to create and complete a new certificate request. Ensure you use 2048 bit certificates.

2. Purchase a certificate from a trusted certificate authority. I prefer SSL2Buy.com.

3. Once you have your certificate it will be downloadable as a ZIP file. It will contain .cer files. In order to install the certificate (firstly onto our GUI IIS server) we need it to be in the .pfx format, as this format lets us store the certificate's private key within it. Extract the certificates, and in IIS, complete the certificate request and select the certificate that's named www.yourdomain.com.cer - You should store the certificate in the "WebHosting" section if prompted.

4. Next, the certificate is installed, but in the wrong server. So we need to export it. Run MMC.exe, File, Add/Remove Snapins / Add the Certificates snap in, select computer account. Find the imported certificate. 

5. Export the certificate, right click, All Tasks, Export. Select .PFX format. Ensure you tick the "Make Private Key Exportable". You will be required to set a password against the certificate to protect the private key. Save the Certificate and then copy it to your IIS server (which has no GUI i.e. server core). 

6. Next we need to install the certificate with PowerShell.

PS C:\>$mypwd = Get-Credential -UserName 'Enter password below' -Message 'Enter password below'

PS C:\>Import-PfxCertificate -FilePath C:\mypfx.pfx -CertStoreLocation Cert:\LocalMachine\WebHosting -Password $mypwd.Password

7. Next we need to update the certificate on the existing binding:

We'll need to know the thumbprint of the certificate and the AppID of the website. I like to change to powershell in core, because it's good for parsing results in a readable format. Run PowerShell.exe then navigate to:

PS Cert:\LocalMachine\WebHosting\>

Run

dir | fl

You should be able to identify the certificate you have installed. Grab the Thumbprint.

8. Next we need the AppID - Run:

netsh http show sslcert

Find the AppID for your website you want to replace the SSL certificate for.

9. Next we use the AppID and Thumbprint to use the new certificate with the website - Note You need to EXIT from PowerShell before running this command - run this in CMD:

netsh http update sslcert hostnameport=www.techshizz.com:443 certhash=C4FA12345678923618B90972707121345678988811 appid={4ab64e81-e14b-4a21-b022-59fc66abcd64} certstorename=WebHosting

10. - DONE! 

How to run a Power Shell script from Task Scheduler

Problem

You are unable to get a Power Shell file to execute using the Task Scheduler

Cause

Two reasons:

  1. The execution policy needs to be set to Unrestricted
  2. The command in Task Scheduler needs to adhere to the correct syntax
  3. You must store the script in a place PowerShell trusts.
Solution

Firstly, store your powershell script in a place PowerShell trusts. To find this, open PowerShell and run:

$env:path

You will note that one of the safe places is "C:\Windows\System32".

Next, Set the execution Policy to Unrestricted using PowerShell. Open PowerShell as administrator and run:

Set-ExecutionPolicy -ExecutionPolicy Unrestricted

Press "A" to accept the changes. If you are using a computer account to run the script, you may need to set the execution policy on the local machine to Unrestricted like this:

Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope LocalMachine

Create a sheduled task as desired. On the actions tab the script must be run like this:

PowerShell.exe "C:\Windows\System32\MyScript.ps1"

Taking care to wrap the path in double quotes. 

One Drive character limit | PowerShell to find file path character length | File Path Character Limit

Problem

One Drive will not sync files with more than 400 charactes in the file path

Cause

Limitation

Solution

Use this script and execute to create a list of all files and their number of characters. Address by shortening folder and file names. 

 $pathToScan = "C:\APP1-Data\SharePointData\MW\MW - Documents" # The path to scan and the the lengths for (sub-directories will be scanned as well).
$outputFilePath = "C:\temp\PathLengths.txt" # This must be a file in a directory that exists and does not require admin rights to write to.
$writeToConsoleAsWell = $true # Writing to the console will be much slower.

# Open a new file stream (nice and fast) and write all the paths and their lengths to it.
$outputFileDirectory = Split-Path $outputFilePath -Parent
if (!(Test-Path $outputFileDirectory)) { New-Item $outputFileDirectory -ItemType Directory }
$stream = New-Object System.IO.StreamWriter($outputFilePath, $false)
Get-ChildItem -Path $pathToScan -Recurse -Force | Select-Object -Property FullName, @{Name="FullNameLength";Expression={($_.FullName.Length)}} | Sort-Object -Property FullNameLength -Descending | ForEach-Object {
$filePath = $_.FullName
$length = $_.FullNameLength
$string = "$length : $filePath"

# Write to the Console.
if ($writeToConsoleAsWell) { Write-Host $string }

#Write to the file.
$stream.WriteLine($string)
}
$stream.Close()


One Drive character limit | PowerShell to find file path character length | File Path Character Limit

Problem

One Drive will not sync files with more than 400 charactes in the file path

Cause

Limitation

Solution

Use this script and execute to create a list of all files and their number of characters. Address by shortening folder and file names. 

 $pathToScan = "C:\APP1-Data\SharePointData\MW\MW - Documents" # The path to scan and the the lengths for (sub-directories will be scanned as well).
$outputFilePath = "C:\temp\PathLengths.txt" # This must be a file in a directory that exists and does not require admin rights to write to.
$writeToConsoleAsWell = $true # Writing to the console will be much slower.

# Open a new file stream (nice and fast) and write all the paths and their lengths to it.
$outputFileDirectory = Split-Path $outputFilePath -Parent
if (!(Test-Path $outputFileDirectory)) { New-Item $outputFileDirectory -ItemType Directory }
$stream = New-Object System.IO.StreamWriter($outputFilePath, $false)
Get-ChildItem -Path $pathToScan -Recurse -Force | Select-Object -Property FullName, @{Name="FullNameLength";Expression={($_.FullName.Length)}} | Sort-Object -Property FullNameLength -Descending | ForEach-Object {
$filePath = $_.FullName
$length = $_.FullNameLength
$string = "$length : $filePath"

# Write to the Console.
if ($writeToConsoleAsWell) { Write-Host $string }

#Write to the file.
$stream.WriteLine($string)
}
$stream.Close()


DNS Time Based Policy

We can configure DNS in server 2016 to DENY, IGNORE or ALLOW the response of DNS requests. Here are the commands required to configure this. 

#Get current server time
Get-Date -DisplayHint Time

#Get current DNS Policies
Get-DnsServerQueryResolutionPolicy -ZoneName demo.com

#Add a new Policy called "Time-Policy" to deny dns requests between 4AM and 11PM.
Add-DnsServerQueryResolutionPolicy -zoneName demo.com -Name "Time-Policy" -Action DENY -TimeOfDay "eq,04:00-23:00" -ProcessingOrder 2

#Check result
Get-DnsServerQueryResolutionPolicy -ZoneName demo.com

#Change Processing order (1 takes precedence)
Set-DnsServerQueryResolutionPolicy -ZoneName demo.com -Name "Time-Policy" -ProcessingOrder 1

#Check result
Get-DnsServerQueryResolutionPolicy -ZoneName demo.com

#Remove the time policy
Remove-DnsServerQueryResolutionPolicy -zoneName demo.com -Name "Time-Policy" -Force

#Re-add the time policy but with IGNORE request instead
Add-DnsServerQueryResolutionPolicy -zoneName demo.com -Name "Time-Policy" -Action IGNORE -TimeOfDay "eq,04:00-23:00" -ProcessingOrder 1

#Remove Time policy again
Remove-DnsServerQueryResolutionPolicy -zoneName hmm.com -Name "Time-Policy" -Force

#Add time policy to DENY between 11PM and Midnight, Order 1
Add-DnsServerQueryResolutionPolicy -zoneName demo.com -Name "Time-Policy" -Action DENY -TimeOfDay "eq,23:00-23:59" -ProcessingOrder 1 

#Check Result
Get-DnsServerQueryResolutionPolicy -ZoneName demo.com

#Change Policy order to 3
Set-DnsServerQueryResolutionPolicy -ZoneName demo.com -Name "Time-Policy" -ProcessingOrder 3

#Check result
Get-DnsServerQueryResolutionPolicy -ZoneName demo.com