Category Archives: Powershell

How to generate base64 encoded SSL certificates via PowerShell for Azure


Many Azure services allow you to bring your own SSL Certificate to the cloud. While Azure provides an easy way to create and deploy resources through ARM templates, specification of what SSL certificate is a little less trivial since it's not as easy to specify an exported PEM or PFX file. In this case, Azure may look for the certificate in a base64 encoded format, so the certificate can be passed as a string (or list of characters) into the template.

Goal of this tutorial

This tutorial will walk through the commands needed to generate a self-signed certificate that is base64 encoded via PowerShell (Option 1) or base64 encode an existing PFX (Option 2), so that the certificate can be passed as a parameter into ARM templates in Azure.

Option 1: Generate and encode a self-signed certificate

Generate a self-signed certificate
$selfSignedCert = New-SelfSignedCertificate -DnsName * -NotAfter (Get-Date).AddYears(2)
Export the self-signed certificate into PFX format from Certificate manager
$pwd = ConvertTo-SecureString -String "1234" -Force -AsPlainText
Export-PfxCertificate -cert $selfSignedCert.PSPath -FilePath "selfSignedCertificate.pfx" -Password $pwd
Convert the certificate to base64 encoding
$pfxBytes = Get-Content "selfSignedCertificate.pfx" -Encoding Byte
[System.Convert]::ToBase64String($pfxBytes) | Out-File "selfSignedCertificate.txt"

Option 2: Encode from a pre-existing pfx file

Convert the certificate to base64 encoding
$pfxBytes = Get-Content "selfSignedCertificate.pfx" -Encoding Byte
[System.Convert]::ToBase64String($pfxBytes) | Out-File "selfSignedCertificate.txt"


At this point, if you open selfSignedCertificate.txt, you should see a long list of characters compromised of letters, numbers, and a few symbols, which is your base64 version of your certificate. See example below (...s denote I removed a large portion of the text, you won't see that in your file).


This text can be used-as within your templates now (although, in general, try to never code these values into your templates, these values should be passed as parameters into the template).

Exporting TPM Owner Key and BitLocker Recovery Password from Active Directory via PowerShell

Synopsis: When looking up a BitLocker Recovery Password or TPM Owner Key, the process can be quite laborious.  This post contains a PowerShell script to help automate the process of manually looking at attributes in Active Directory to pull such information.

Download a copy of the script here (make sure to remove the .txt at the end): Get-TPMandBitlockerInfo.ps1.txt

Run the script with PowerShell

Get-TPMOwnerInfo - Run with PowerShell

Here are the results it should return
Get-TPMOwnerInfo - PowerShell


Here is a copy of the script in Plain Text

    Automates the process on gathering BitLocker recovery password and TPM owner password.

    This script will lookup multiple attribute in Active Directory and display the correlating
    values that hold sensitive BitLocker information.  Additionally, the TPM Owner Password
    can be exported to a .tpm file, which can be used to make changes to the correlating machine.

    File Name      : Get-TPMandBitlockerInfo.ps1
    Author         : Jack Stromberg (
    Prerequisite   : PowerShell V2 over Vista and upper
    Version History: 2/5/2015 (original release)

    Script posted over at:

Write-Host "~Enter in the correct credentials to access the BitLocker and TPM Owner attributes~"
$UserName = Read-Host "Enter User Name" 
$Password = Read-Host -AsSecureString "Enter Your Password" 
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $UserName , $Password 

# Get input on which machine to lookup
$computer = Read-Host 'Enter in machine name'

# Import our Active Directory PowerShell commands
Import-Module ActiveDirectory

# Check if the Computer Object exists in AD
$computerObject = Get-ADComputer -Filter {cn -eq $computer} -Property msTPM-OwnerInformation, msTPM-TpmInformationForComputer -Credential $credential
if($computerObject -eq $null){
    Write-Host "Computer object not found.  Exiting the script..."
    Cmd /c pause

# Windows Vista and 7 stores the TPM owner password in the msTPM-OwnerInformation attribute, check that first.
# If the key hasn't been stored there, check the msTPM-TpmInformationForComputer object to see if it was backed up on a Win 8 or greater machine
if($computerObject.'msTPM-OwnerInformation' -eq $null){
    #Check if the computer object has had the TPM info backed up to AD
    if($computerObject.'msTPM-TpmInformationForComputer' -ne $null){
        # Grab the TPM Owner Password from the msTPM-InformationObject
        $TPMObject = Get-ADObject -Identity $computerObject.'msTPM-TpmInformationForComputer' -Properties msTPM-OwnerInformation  -Credential $credential
        $TPMRecoveryKey = $TPMObject.'msTPM-OwnerInformation'
        $TPMRecoveryKey = '<not set>'
    # Windows 7 and older OS TPM Owner Password
    $TPMRecoveryKey = $computerObject.'msTPM-OwnerInformation'

# Check if the computer object has had a BitLocker Recovery Password backed up to AD
$BitLockerObject = Get-ADObject -Filter {objectclass -eq 'msFVE-RecoveryInformation'} -SearchBase $computerObject.DistinguishedName -Properties 'msFVE-RecoveryPassword' -Credential $credential | Select-Object -Last 1
    $BitLockerRecoveryKey = $BitLockerObject.'msFVE-RecoveryPassword'
    $BitLockerRecoveryKey = '<not set>'

#Print out our findings
Write-Host 'TPM Owner Recovery Key:' $TPMRecoveryKey
Write-Host 'BitLocker Recovery Password:' $BitLockerRecoveryKey

# Export TPM Owner Password File
if($computerObject.'msTPM-TpmInformationForComputer' -ne $null){
    $exportToFile = Read-Host 'Would you like to export the recovery key [y or n]'
    if($exportToFile -ne 'y'){

    $TPMOwnerFile = '<?xml version="1.0" encoding="UTF-8"?><ownerAuth>' + $TPMRecoveryKey + '</ownerAuth>'
    $TPMOwnerFile | Out-File "TPMOwnerPasswordFile.tpm"
    Cmd /c pause

ADFS v3 on Server 2012 R2 - Allow Chrome to automatically sign-in internally

Symptom: When upgrading from ADFS v2.0 to ADFS v3 built natively into Server 2012 R2, I noticed Chrome stopped auto-logging in people when trying to hit the ADFS server from inside the corporate network.

Solution: We need to allow NTLM authentication for the Google Chrome useragent.

  1. Login to your primary ADFS server
  2. NOTE: This step is no longer applicable on newer versions of Chrome.
    This is only applicable if running extremely old versions of Chrome (v50 or lower) -- the fix has been added in Chrome v51 and higher.

    Execute the following command to disable Extended Protection TokenCheck (See notes for what this is at the bottom of this article)

    1. Set-ADFSProperties –ExtendedProtectionTokenCheck None
      Set-ADFSProperties -ExtendedProtectionTokenCheck None
  3. Execute the following command to get the current list of supported user-agents for NTLM authentication
    1. [System.Collections.ArrayList]$UserAgents = Get-AdfsProperties | select -ExpandProperty WIASupportedUserAgents

  4. Execute the following command to inject the user agent into a temporary array of user agents already added to ADFS.
    1. $UserAgents.Add("Mozilla/5.0")
  5. Execute the following command to commit the change.
    1. Set-ADFSProperties -WIASupportedUserAgents $UserAgents
  6. Restart the Active Directory Federation Services service on each of the ADFS farm servers for the changes to take effect.  You do not need to make any changes to the proxy servers.
    Restart Active Directory Federation Services - Restart


Shout out to Jon Payne in the comments section below for the idea of putting all the values into an ArrayList and then committing the arraylist to ADFS vs adding in all the strings manually.

ExtendedProtectionTokenCheck - Copied directly from technet - Specifies the level of extended protection for authentication supported by the federation server. Extended Protection for Authentication helps protect against man-in-the-middle (MITM) attacks, in which an attacker intercepts a client's credentials and forwards them to a server. Protection against such attacks is made possible through a Channel Binding Token (CBT) which can be either required, allowed or not required by the server when establishing communications with clients.

PowerShell command to find all disabled users in Active Directory

Here is a quick powershell command to find all users inside of your Active Directory domain that have been marked as disabled (this will exclude disabled computers):

Get-ADUser -Filter {Enabled -eq $false} | FT samAccountName

Additionally, you can specify which additional options you would like to show by change the filter table command we are piping the results to.  For example, this command will show the samAccountName, first name, and last name of the disabled users.

Get-ADUser -Filter {Enabled -eq $false} | FT samAccountName, GivenName, Surname

If you want no formatting whatsoever and have AD spit a bunch of information back at you, try running just the Get-ADUser part with the filter applied.

Get-ADUser -Filter {Enabled -eq $false

The following command below can be used to pull a list of disabled users and computers:

Search-ADAccount -AccountDisabled


Get MD5 Hash of a file via PowerShell/Windows

Want to check the hash of a huge file you downloaded on your shady network and have a machine running powershell? Then you are in luck!

Execute the following script to output the hash of the file you want to validate:

$FilePath = "c:\Users\MyAwesomeUser\Desktop\myreallybigfilethatisprobablyaniso.iso"
$md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$hash = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes($FilePath)))
Write-Host $hash.Replace("-","")

Hope this helps!

Get samaccount/username out of Active Directory via PowerShell

Here is how to get a list of everyone's username out of active directory.

Get-ADUser -Filter * | FT SamAccountName -A

Common PowerShell Commands for Office 365

Here are some commands that are handy to use for Office 365.

#Assign user credentials to variable "LiveCred"

$LiveCred = Get-Credential

#Connect to your Cloud-hosted Exchange using the credential stored in #LiveCred

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri -Credential $LiveCred -Authentication Basic -AllowRedirection

#Import Cmdlets

Import-PSSession $Session

#Close your session

Remove-PSSession $Session

#Grant Bob Barker calendar (or any folder) rights to Adam Sandler's. The field within " " can be either the user principal name or primary alias
#Possible   rights:  Ownder, Publishing Editor, Editor, Author, Contributor, Reviewer, Custom
#Note: practice-wise (for your own mental check), the account being given access is normally to the right of the account to which you are assigning the right.

Add-MailboxFolderPermission -Identity "The.Dude:\Calendar" -AccessRights PublishingEditor -User "Test Guy"

#View permissions on a folder

Get-MailboxFolderPermission -Identity "The Dude:\Calendar"

#View all accounts that have mailbox access beyond SELF

Get-Mailbox | Get-MailboxPermission | where {$_.user.tostring() -ne "NT AUTHORITY\SELF" -and $_.IsInherited -eq $false}

#The export to a file version of above

Get-Mailbox | Get-MailboxPermission | where {$_.user.tostring() -ne "NT AUTHORITY\SELF" -and $_.IsInherited -eq $false} | Select Identity,User,@{Name='Access Rights';Expression={[string]::join(', ', $_.AccessRights)}} | Export-Csv -NoTypeInformation mailboxpermissions.csv

#Grant user Send-as to identity

Add-RecipientPermission <identity> -AccessRights SendAs -Trustee <user>

#View all boxes that have Send-as attributes on them

Get-RecipientPermission | where {($_.Trustee -ne 'nt authority\self') -and ($_.Trustee -ne 'null sid')}

PowerShell Script To Create Folders From CSV

This script will read in a csv named users.csv and create a bunch of directories from it. A log file will be written named logfile.log

# MODIFIED: Jack Stromberg
# DATE : 7/19/2012
# COMMENTS: $_.FirstName and $_.LastName are the column names in the csv file
# Get current directory and set import file in variable
$path = Split-Path -parent $MyInvocation.MyCommand.Definition
$newpath = $path + "\users.csv"
# Define variables
$log = $path + "\logfile.log"
$date = Get-Date
Function createDirs
"Created following directories (on " + $date + ") " | Out-File $log -append
"--------------------------------------------" | Out-File $log -append
Import-CSV $newpath | ForEach-Object {
$dir = $path + "\" + $_.FirstName + "." + $_.LastName + "\"
$dir = $dir.ToLower()
New-Item $dir -type directory

PowerShell - Disabled Execution

If you see an error like this in PowerShell:
File ****************** cannot be loaded because the execution of scripts is disabled on this system. Please see "get-help about_signing" for more details.

Execute the following command:
Set-ExecutionPolicy RemoteSigned