Getting started with Azure OpenAI and PowerShell

You probably have been playing around with Chat GPT lately, and have seen its amazing capabilities. Recently Microsoft invested heavily in OpenAI, and now there is an Azure version available called Azure OpenAI. I have written a guide on how to take advantage of this service by using PowerShell and Rest API calls. I’m focusing on the text completion endpoint, which is basically the same as Chat GPT. You can see the other endpoints listed here.

Here is also the link to the docs/learn pages for Azure OpenAI.

Our end goal today is to get a reply like the one below in PowerShell. Here I asked Azure OpenAI for an end user adoption tip for Microsoft Teams.



We start this guide by setting up an Azure OpenAI resource.

Go to https://oai.azure.com/

If you already have access to Azure OpenAI, click Create a resource.

Fill out the following and click Review/Create. The name you set here, is the Resource name, and you will need it in the PowerShell script further down.

Click Create.

Wait while the resource is deploying.

Click Go to resource.

Click on the Model Deployment menu.

Click Create, give it a name, select a text model, and click Save. The deployment name you set here, you will need in the PowerShell scripts further down.

API Key

You can authenticate with an API Key doing calls against Azure OpenAI. It’s the same as when you use a secret working with Graph API. There are two keys, and you can choose which one you want to use. This is just to simplify with key rotation, as you see you can regenerate them.

Click on Keys and Endpoint. Copy either Key 1 or Key 2. Need this in the PowerShell script.

Copy these two function into your PowerShell editor. Make sure you have the AzAccounts module.

function Get-AzureOpenAIToken{
<# .SYNOPSIS
Get an azure token for user or managed identity thats required to authenticate to Azure OpenAI with Rest API.
Also construct the header if you are using an Azure OpenAI API key instead of Azure AD authentication.
.PARAMETER ManagedIdentity
Use this parameter if you want to use a managed identity to authenticate to Azure OpenAI.
.PARAMETER User
Use this parameter if you want to use a user to authenticate to Azure OpenAI.
.PARAMETER APIKey
Use this parameter if you want to use an API key to authenticate to Azure OpenAI.
.EXAMPLE
# Manually specify username and password to acquire an authentication token:
Get-AzureOpenAIToken -APIKey "ghgkfhgfgfgkhgh"
Get-AzureOpenAIToken -ManagedIdentity $true
Get-AzureOpenAIToken -User $true
.NOTES
Author: Alexander Holmeset
Twitter: @AlexHolmeset
Website: https://www.alexholmeset.blog
Created: 09-02-2023
Updated:
Version history:
1.0.0 - (09-02-2023) Function created
#>
[CmdletBinding()]
param (
[Parameter(Mandatory=$false)]
[string]$APIKey,
[Parameter(Mandatory=$false)]
[string]$ManagedIdentity,
[Parameter(Mandatory=$false)]
[string]$User
)
Process {
$ErrorActionPreference = "Stop"
if (Get-Module -ListAvailable -Name Az.Accounts) {
# Write-Host "You have the Az.Accounts module installed"
}
else {
Write-Host "You need to install the Az.Accounts module";
break
}
If(!$MyHeader){
If($ManagedIdentity -eq $true){
"managed"
try {
Connect-AzAccount -Identity
$MyTokenRequest = Get-AzAccessToken -ResourceUrl "https://cognitiveservices.azure.com&quot;
$MyToken = $MyTokenRequest.token
If(!$MyToken){
Write-Warning "Failed to get API access token!"
Exit 1
}
$Global:MyHeader = @{"Authorization" = "Bearer $MyToken" }
}
catch [System.Exception] {
Write-Warning "Failed to get Access Token, Error message: $($_.Exception.Message)"; break
}
}
If($User -eq $true){
"USER"
try {
Connect-AzAccount
$MyTokenRequest = Get-AzAccessToken -ResourceUrl "https://cognitiveservices.azure.com&quot;
$MyToken = $MyTokenRequest.token
If(!$MyToken){
Write-Warning "Failed to get API access token!"
Exit 1
}
$Global:MyHeader = @{"Authorization" = "Bearer $MyToken" }
}
catch [System.Exception] {
Write-Warning "Failed to get Access Token, Error message: $($_.Exception.Message)"; break
}
}
If($APIkey){
"APIKEY"
$Global:MyHeader = @{"api-key" = $apikey }
}
}
}
}
function Get-Completion {
<# .SYNOPSIS
Get a text completion from Azure OpenAI Completion endpoint.
.PARAMETER DeploymentName
A deployment name should be provided.
.PARAMETER ResourceName
A Resource name should be provided.
.PARAMETER Prompt
A prompt name should be provided.
.PARAMETER Token
A token name should be provided.
.EXAMPLE
Get-Completion -DeploymentName $DeploymentName -ResourceName $ResourceName -maxtokens 100 -prompt "What is the meaning of life?"
.NOTES
Author: Alexander Holmeset
Twitter: @AlexHolmeset
Website: https://www.alexholmeset.blog
Created: 09-02-2023
Updated:
Version history:
1.0.0 - (09-02-2023) Function created
#>[CmdletBinding()]
param (
[parameter(Mandatory = $true, HelpMessage = "Your azure openai deployment name")]
[ValidateNotNullOrEmpty()]
[string]$DeploymentName,
[parameter(Mandatory = $true, HelpMessage = "your azure openai resource name")]
[ValidateNotNullOrEmpty()]
[string]$ResourceName,
[parameter(Mandatory = $true, HelpMessage = "Your Azure OpenAI prompt")]
[ValidateNotNullOrEmpty()]
[string]$Prompt,
[parameter(Mandatory = $true, HelpMessage = "Max number of tokens allowed to be used in this request")]
[ValidateNotNullOrEmpty()]
[int]$Maxtokens
)
Process {
$ErrorActionPreference = "Stop"
$APIVersion = "2022-12-01"
# Construct URI
$uri = "https://$ResourceName.openai.azure.com/openai/deployments/$DeploymentName/completions?api-version=$ApiVersion&quot;
# Construct Body
$Body = @"
{
"prompt": "$Prompt",
"max_tokens": $maxtokens
}
"@
try {
$Global:Request = invoke-restmethod -Method POST -Uri $uri -ContentType "application/json" -Body $body -Headers $Global:MyHeader
}
catch [System.Exception] {
Write-Warning "Failed to to POST request: $($_.Exception.Message)"; break
}
return $Request
}
}

At last copy this small script into your editor, and paste your API Key in the correct parameter.

Get-AzureOpenAIToken -APIKey "Enter API Key here"
$DeploymentName = "TextModel"
$ResourceName = "AzureOpenAIAlex"
$Prompt = "What is microsoft teams?"
$Request = Get-Completion -DeploymentName $DeploymentName -ResourceName $ResourceName -Maxtokens 100 -Prompt $Prompt
"Genetrated text:"
$Request.choices.text
"Token cost"
$Request.usage

Here is the output you see when authenticating with the API Key.


Azure AD User Auth

You can get a user-based token from Azure AD by logging on with the AzAccounts module in PowerShell. This way you are secured by MFA and no need for a API Key.

Go to the Azure OpenAI resource you created above.

Go to the Access Control menu.

Click on Add role assignment.

Search for and select the Cognitive Services User role, and click next.

Select “User, group or service principal”, click Select members and search/select your user. Click Select.
Click Review/assign two times.

Click on Role assignments to confirm that the user is added to the role.


Now open up PowerShell and make sure you have the AzAccounts module.

Copy these two functions into your PowerShell editor.

function Get-AzureOpenAIToken{
<# .SYNOPSIS
Get an azure token for user or managed identity thats required to authenticate to Azure OpenAI with Rest API.
Also construct the header if you are using an Azure OpenAI API key instead of Azure AD authentication.
.PARAMETER ManagedIdentity
Use this parameter if you want to use a managed identity to authenticate to Azure OpenAI.
.PARAMETER User
Use this parameter if you want to use a user to authenticate to Azure OpenAI.
.PARAMETER APIKey
Use this parameter if you want to use an API key to authenticate to Azure OpenAI.
.EXAMPLE
# Manually specify username and password to acquire an authentication token:
Get-AzureOpenAIToken -APIKey "ghgkfhgfgfgkhgh"
Get-AzureOpenAIToken -ManagedIdentity $true
Get-AzureOpenAIToken -User $true
.NOTES
Author: Alexander Holmeset
Twitter: @AlexHolmeset
Website: https://www.alexholmeset.blog
Created: 09-02-2023
Updated:
Version history:
1.0.0 - (09-02-2023) Function created
#>
[CmdletBinding()]
param (
[Parameter(Mandatory=$false)]
[string]$APIKey,
[Parameter(Mandatory=$false)]
[string]$ManagedIdentity,
[Parameter(Mandatory=$false)]
[string]$User
)
Process {
$ErrorActionPreference = "Stop"
if (Get-Module -ListAvailable -Name Az.Accounts) {
# Write-Host "You have the Az.Accounts module installed"
}
else {
Write-Host "You need to install the Az.Accounts module";
break
}
If(!$MyHeader){
If($ManagedIdentity -eq $true){
"managed"
try {
Connect-AzAccount -Identity
$MyTokenRequest = Get-AzAccessToken -ResourceUrl "https://cognitiveservices.azure.com&quot;
$MyToken = $MyTokenRequest.token
If(!$MyToken){
Write-Warning "Failed to get API access token!"
Exit 1
}
$Global:MyHeader = @{"Authorization" = "Bearer $MyToken" }
}
catch [System.Exception] {
Write-Warning "Failed to get Access Token, Error message: $($_.Exception.Message)"; break
}
}
If($User -eq $true){
"USER"
try {
Connect-AzAccount
$MyTokenRequest = Get-AzAccessToken -ResourceUrl "https://cognitiveservices.azure.com&quot;
$MyToken = $MyTokenRequest.token
If(!$MyToken){
Write-Warning "Failed to get API access token!"
Exit 1
}
$Global:MyHeader = @{"Authorization" = "Bearer $MyToken" }
}
catch [System.Exception] {
Write-Warning "Failed to get Access Token, Error message: $($_.Exception.Message)"; break
}
}
If($APIkey){
"APIKEY"
$Global:MyHeader = @{"api-key" = $apikey }
}
}
}
}
function Get-Completion {
<# .SYNOPSIS
Get a text completion from Azure OpenAI Completion endpoint.
.PARAMETER DeploymentName
A deployment name should be provided.
.PARAMETER ResourceName
A Resource name should be provided.
.PARAMETER Prompt
A prompt name should be provided.
.PARAMETER Token
A token name should be provided.
.EXAMPLE
Get-Completion -DeploymentName $DeploymentName -ResourceName $ResourceName -maxtokens 100 -prompt "What is the meaning of life?"
.NOTES
Author: Alexander Holmeset
Twitter: @AlexHolmeset
Website: https://www.alexholmeset.blog
Created: 09-02-2023
Updated:
Version history:
1.0.0 - (09-02-2023) Function created
#>[CmdletBinding()]
param (
[parameter(Mandatory = $true, HelpMessage = "Your azure openai deployment name")]
[ValidateNotNullOrEmpty()]
[string]$DeploymentName,
[parameter(Mandatory = $true, HelpMessage = "your azure openai resource name")]
[ValidateNotNullOrEmpty()]
[string]$ResourceName,
[parameter(Mandatory = $true, HelpMessage = "Your Azure OpenAI prompt")]
[ValidateNotNullOrEmpty()]
[string]$Prompt,
[parameter(Mandatory = $true, HelpMessage = "Max number of tokens allowed to be used in this request")]
[ValidateNotNullOrEmpty()]
[int]$Maxtokens
)
Process {
$ErrorActionPreference = "Stop"
$APIVersion = "2022-12-01"
# Construct URI
$uri = "https://$ResourceName.openai.azure.com/openai/deployments/$DeploymentName/completions?api-version=$ApiVersion&quot;
# Construct Body
$Body = @"
{
"prompt": "$Prompt",
"max_tokens": $maxtokens
}
"@
try {
$Global:Request = invoke-restmethod -Method POST -Uri $uri -ContentType "application/json" -Body $body -Headers $Global:MyHeader
}
catch [System.Exception] {
Write-Warning "Failed to to POST request: $($_.Exception.Message)"; break
}
return $Request
}
}

And at last, add the following script to your editor, and run the whole thing.

Get-AzureOpenAIToken -User $true
$DeploymentName = "TextModel"
$ResourceName = "AzureOpenAIAlex"
$Prompt = "What is microsoft teams?"
$Request = Get-Completion -DeploymentName $DeploymentName -ResourceName $ResourceName -Maxtokens 100 -Prompt $Prompt
"Genetrated text:"
$Request.choices.text
"Token cost"
$Request.usage

Here you see the output when authenticating as a user.

Azure Automation with Managed Identity

The best way to fully automate this is to use Azure Automation with a managed identity. This way we don’t need to handle any API key storing.

Go to portal.azure.com and search for Automation Account.

Click Create.

Fill out and click review/create.

Click Create.

Click Go to resource.

Scroll down, go to the Identity menu, and make sure the System Assigned toggle says On. Click Azure role assignments.

Click Add role assignment.

Select the Scope to be subscription, choose the same subscription as where you have your Azure OpenAI deployment, and choose the Cognitive Services User role.. Click Save.

Refresh to make sure the role is assigned:

Go to the Modules page of the Automation Account to confirm you have the Az.Accounts module installed.

Go to the runbooks menu, and click Create runbook.

Select the following and click Create.

In the runbook editor copy/paste this function to generate the token needed to authenticate against Azure OpenAI.

function Get-AzureOpenAIToken{
<# .SYNOPSIS
Get an azure token for user or managed identity thats required to authenticate to Azure OpenAI with Rest API.
Also construct the header if you are using an Azure OpenAI API key instead of Azure AD authentication.
.PARAMETER ManagedIdentity
Use this parameter if you want to use a managed identity to authenticate to Azure OpenAI.
.PARAMETER User
Use this parameter if you want to use a user to authenticate to Azure OpenAI.
.PARAMETER APIKey
Use this parameter if you want to use an API key to authenticate to Azure OpenAI.
.EXAMPLE
# Manually specify username and password to acquire an authentication token:
Get-AzureOpenAIToken -APIKey "ghgkfhgfgfgkhgh"
Get-AzureOpenAIToken -ManagedIdentity $true
Get-AzureOpenAIToken -User $true
.NOTES
Author: Alexander Holmeset
Twitter: @AlexHolmeset
Website: https://www.alexholmeset.blog
Created: 09-02-2023
Updated:
Version history:
1.0.0 - (09-02-2023) Function created
#>
[CmdletBinding()]
param (
[Parameter(Mandatory=$false)]
[string]$APIKey,
[Parameter(Mandatory=$false)]
[string]$ManagedIdentity,
[Parameter(Mandatory=$false)]
[string]$User
)
Process {
$ErrorActionPreference = "Stop"
if (Get-Module -ListAvailable -Name Az.Accounts) {
# Write-Host "You have the Az.Accounts module installed"
}
else {
Write-Host "You need to install the Az.Accounts module";
break
}
If(!$MyHeader){
If($ManagedIdentity -eq $true){
"managed"
try {
Connect-AzAccount -Identity
$MyTokenRequest = Get-AzAccessToken -ResourceUrl "https://cognitiveservices.azure.com&quot;
$MyToken = $MyTokenRequest.token
If(!$MyToken){
Write-Warning "Failed to get API access token!"
Exit 1
}
$Global:MyHeader = @{"Authorization" = "Bearer $MyToken" }
}
catch [System.Exception] {
Write-Warning "Failed to get Access Token, Error message: $($_.Exception.Message)"; break
}
}
If($User -eq $true){
"USER"
try {
Connect-AzAccount
$MyTokenRequest = Get-AzAccessToken -ResourceUrl "https://cognitiveservices.azure.com&quot;
$MyToken = $MyTokenRequest.token
If(!$MyToken){
Write-Warning "Failed to get API access token!"
Exit 1
}
$Global:MyHeader = @{"Authorization" = "Bearer $MyToken" }
}
catch [System.Exception] {
Write-Warning "Failed to get Access Token, Error message: $($_.Exception.Message)"; break
}
}
If($APIkey){
"APIKEY"
$Global:MyHeader = @{"api-key" = $apikey }
}
}
}
}

Now copy this function that handles the Rest API calls against Azure OpenAI.

function Get-Completion {
<# .SYNOPSIS
Get a text completion from Azure OpenAI Completion endpoint.
.PARAMETER DeploymentName
A deployment name should be provided.
.PARAMETER ResourceName
A Resource name should be provided.
.PARAMETER Prompt
A prompt name should be provided.
.PARAMETER Token
A token name should be provided.
.EXAMPLE
Get-Completion -DeploymentName $DeploymentName -ResourceName $ResourceName -maxtokens 100 -prompt "What is the meaning of life?"
.NOTES
Author: Alexander Holmeset
Twitter: @AlexHolmeset
Website: https://www.alexholmeset.blog
Created: 09-02-2023
Updated:
Version history:
1.0.0 - (09-02-2023) Function created
#>[CmdletBinding()]
param (
[parameter(Mandatory = $true, HelpMessage = "Your azure openai deployment name")]
[ValidateNotNullOrEmpty()]
[string]$DeploymentName,
[parameter(Mandatory = $true, HelpMessage = "your azure openai resource name")]
[ValidateNotNullOrEmpty()]
[string]$ResourceName,
[parameter(Mandatory = $true, HelpMessage = "Your Azure OpenAI prompt")]
[ValidateNotNullOrEmpty()]
[string]$Prompt,
[parameter(Mandatory = $true, HelpMessage = "Max number of tokens allowed to be used in this request")]
[ValidateNotNullOrEmpty()]
[int]$Maxtokens
)
Process {
$ErrorActionPreference = "Stop"
$APIVersion = "2022-12-01"
# Construct URI
$uri = "https://$ResourceName.openai.azure.com/openai/deployments/$DeploymentName/completions?api-version=$ApiVersion&quot;
# Construct Body
$Body = @"
{
"prompt": "$Prompt",
"max_tokens": $maxtokens
}
"@
try {
$Global:Request = invoke-restmethod -Method POST -Uri $uri -ContentType "application/json" -Body $body -Headers $Global:MyHeader
}
catch [System.Exception] {
Write-Warning "Failed to to POST request: $($_.Exception.Message)"; break
}
return $Request
}
}

And finaly, paste this little script at the end.

Get-AzureOpenAIToken -ManagedIdentity $true
$DeploymentName = "TextModel"
$ResourceName = "AzureOpenAIAlex"
$Prompt = "What is microsoft teams?"
$Request = Get-Completion -DeploymentName $DeploymentName -ResourceName $ResourceName -Maxtokens 100 -Prompt $Prompt
"Genetrated text:"
$Request.choices.text
"Token cost"
$Request.usage

Enter your Deploymentname and Resourcename. Enter a prompt/question you want to be answered.
Click save and publish.

Click Start.

Here you see the output of the runbook:

Now we know how to start interacting with Azure OpenAI by using our favorite automation scripting language. I’m really looking forward to digging deeper into this, and seeing what kind of automated solutions I can create using this.

6 thoughts on “Getting started with Azure OpenAI and PowerShell

  1. […] Getting started with Azure OpenAI and PowerShell. This post provides an introduction and guide to using Azure OpenAI, Microsoft’s recently invested in AI service. It covers how to set up an Azure OpenAI resource, authenticate with an API key, authenticate with an Azure AD user, and authenticate with an Azure Automation-managed identity. It also provides sample code that can be used to interact with Azure OpenAI in PowerShell. […]

    Like

Leave a comment