Activity: Protecting Secrets in PowerShell

Using the following code block used to authenticate from previous scripts we will protect the secret. Replace the BLOCK text with details from your environment.

#The Client ID from App Registrations
$clientId = "CLIENT ID"
 
#The Tenant ID from App Registrations
$tenantId = "TENANT ID"
 
#The Client ID from certificates and secrets section
$clientSecret = 'CLIENTSECRET'

# Construct the authentication URL
$uri = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
 
 
# Construct the body to be used in Invoke-WebRequest
$body = @{
    client_id     = $clientId
    scope         = "https://graph.microsoft.com/.default"
    client_secret = $clientSecret
    grant_type    = "client_credentials"
}
 
# Get Authentication Token
$tokenRequest = Invoke-WebRequest -Method Post -Uri $uri -ContentType "application/x-www-form-urlencoded" -Body $body -UseBasicParsing
 
# Extract the Access Token
$token = ($tokenRequest.Content | ConvertFrom-Json).access_token

We need to install the PowerShell modules for secrets management. Do so with the following command and run in a PowerShell prompt.

Install-Module Microsoft.PowerShell.SecretManagement, Microsoft.PowerShell.SecretStore

Once installed we’ll need to create a Secrets Vault. This will securely store your secrets.

Register-SecretVault -Name SecretStore -ModuleName Microsoft.PowerShell.SecretStore -DefaultVault

Once we have done this we’ll want to create a secret. Lets create a secret with using the value in $clientSecret above.

Set-Secret -Name AppSecret -Secret "CLIENTSECRET"

It will ask for a password, enter something simple that you would remember. This is just for the workshop, typically you’d use a longer password. This password will allow the stored secret to be retrieved for an hour. You can use the Unlock-SecretStore command and enter the password and access will be available for another hour.

You can then use the following code to get the secret.

Get-Secret AppSecret -AsPlainText

The updated script would look like the block below.

#The Client ID from App Registrations
$clientId = "CLIENT ID"
 
#The Tenant ID from App Registrations
$tenantId = "TENANT ID"
 
#The Client ID from certificates and secrets section
$clientSecret = Get-Secret AppSecret -AsPlainText

# Construct the authentication URL
$uri = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
 
 
# Construct the body to be used in Invoke-WebRequest
$body = @{
    client_id     = $clientId
    scope         = "https://graph.microsoft.com/.default"
    client_secret = $clientSecret
    grant_type    = "client_credentials"
}
 
# Get Authentication Token
$tokenRequest = Invoke-WebRequest -Method Post -Uri $uri -ContentType "application/x-www-form-urlencoded" -Body $body -UseBasicParsing
 
# Extract the Access Token
$token = ($tokenRequest.Content | ConvertFrom-Json).access_token

This should authenticate as before, but will not require the client secret to be in plain text. You could also do the same with the Client ID if you wished to obfuscate the other half of the credential.