Generating PKCE codes with PowerShell

Proof Key for Code Exchange (PKCE) is a mechanism often used with an OAuth2 Authorization Code Grant flow to provide an enhanced level of security when authenticating to an Identity Provider such as Microsoft Graph to get an access token. In order to use PKCE a code_verifier is generated along with a code_challenge. There are numerous examples available of how to do that but not using PowerShell. This blog post details generating PKCE codes with PowerShell using my PKCE PowerShell Module for use with an OAuth2 Authorization Code Grant flow.

PKCE helps mitigate the Authorization Code interception security attack whereby a malicious actor could intercept the Authorization Code and use it to obtain an access token. With PKCE without knowing the “secret” the malicious actor isn’t able to exchange the Authorization Code for an access token.

The process flow diagram below from Auth0 details the PKCE with Authorization Code Flow process very well. As OAuth is a standard this process flow is implemented by many IDentity-as-a-Service vendors including Microsoft with Azure Active Directory. I will be posting another post specifically on using this module for PKCE with Authorization Code to Azure AD.

Update: 22 Dec 2021 This post details using this PKCE Module to generate PKCE codes and perform an Authorization Code with PKCE Flow using PowerShell to authenticate and authorize against Azure Active Directory for Microsoft Graph access.

PKCE codes with PowerShell for PKCE Authorization Code flow

PKCE Codes PowerShell Module

My PKCE PowerShell Module works on both Windows PowerShell (5.1+) and PowerShell (6.x, 7.x) and contains one cmdlet “New-PKCE” that can;

  • Generate both the code_verifier and the associated code_challenge
  • For a valid code_verifier generate the code_challenge
  • Generate a code_verifier of a user specified length as per RFC 7636

PKCE Code Generation Overview

RFC 7636 specifies that a code_verifier is;

  • 43 to 128 characters in length
  • allowed characters are a-z, A-Z, 0-9 and – _ . ~

A code_challenge is then generated by encrypting the code_verifier using SHA256.

Note: A plain option also exists where the code_verifier is resent as the code_challenge. But I will not be going into that. If you’re using PKCE please use the SHA256 option.

Module Installation

Install directly from the PowerShell Gallery (PowerShell 5.1 and above).

install-module -name PKCE


Import the Module.

import-module PKCE


Using New-PKCE to generate a code_verifier and code_challenge using the default 127 character length.



code_verifier : WoBOriV4tDoK61KVPbWM71sk5maozuSXjxRUO2fu9zIQCoH0ExenrT7clYznp15CKLy8HnnXENGBw3SuZjM0T2vaUvVJBD7ThpD2XqkjdPyekAkYFs8b4cCFaxHgFOhO
code_challenge : dKk5vCznfP9dqr7PPugOfq_cmyX1hEMzvdVT_x0ZRg0


Use New-PKCE to generate a code_verifier and code_challenge with a length of 99 for the code_verifier.

New-PKCE -length 99 | FL


code_verifier : yf82tm6q0Q9mgkFfxPXfRNyN4dhlDHrI9kKKsX5vAVhMLeW80LyutH3wx9bPh82wisluIBOsaR6Z7P0z5LMcqoOfJRayn7ZpTkD
code_challenge : YOamaHC_iqRrIkSusU2FEMahO2BVJz1KZzEQ9o6j5kE


Using New-PKCE to generate a code_challenge for a specified code_verifier.

New-PKCE -codeVerifier '0_EUVyNBjAFIAKg7xqw-3WC5xAZkx..~~xqndi4WRc1NCCEdXUScvCfDsVygmDQQ~eIZiVamZsQp3XhqL9TuH5~9U-BRBvI3KeOtalT.~uByhfTcGhnd9gHySopRaeLN' | FL


code_verifier : 0_EUVyNBjAFIAKg7xqw-3WC5xAZkx..~~xqndi4WRc1NCCEdXUScvCfDsVygmDQQ~eIZiVamZsQp3XhqL9TuH5~9U-BRBvI3KeOtalT.~uByhfTcGhnd9gHySopRaeLN
code_challenge : gewJaAUliqSe-nMhl48sutkX4ayfCtcPc-72jRnAPMA


Generate a code_challenge and code_verifier and assign them to variables for use in an OAuth2 Authorization Code Grant flow.

$pkceCodes = New-PKCE 
$codeChallenge = $pkceCodes.code_challenge
$codeVerifier = $pkceCodes.code_verifier
$pkceCodes | FL


code_verifier : n8bOz65bchiqsu5dW1JTRWBGWlkbmKUCXR5CRiUqrdqIBeSvTlOjS8i9xsgpVVMBXEgjNKDBKhFNDnzFa4yp87v3fZNgPA2MtFEIrtdjoRkvtmAwrj3uCcyf1A4h7ZGY
code_challenge : T1nH0TteC6QN7p4upQ4GPT_x0nWCfKMrtTi5-mptrvg


On the surface generating a PKCE code_verifier is quite simple, but there are a few nuances. Nuances that once I had written it I knew I was going to need it over and over so have published it as a PowerShell module.

Source code is on GitHub here.