How To Build an AI-Driven PowerShell Code Generator (Sample Script)

Discover how to automate the extraction of PowerShell code generated by ChatGPT. After learning about the process, you will have the opportunity to review the complete source code.

Brien Posey

November 15, 2023

5 Min Read
person uses a laptop and communicates with ChatGPT
Alamy

It’s a well-known fact that ChatGPT can generate PowerShell code. Normally, after the AI-generated code is shown on the screen, users must manually copy and paste the code into a file to then create a PowerShell script. However, what if you could automate this process?

In this article, I will show you a PowerShell script that uses AI to automatically generate other PowerShell scripts.  

Before getting started, I strongly recommend reading my article on building ChatGPT-enabled PowerShell scripts. The script that I am going to show you below relies on the ChatGPT integration method explained in that article. I won’t revisit the details of the ChatGPT integration here. Instead, my focus will be explaining how to automatically export PowerShell code generated by ChatGPT.

How the PowerShell Script Works

Building a PowerShell script that uses AI to generate other PowerShell scripts primarily involves string manipulation. The script must process the response generated by ChatGPT, extract only the script code, and then write that code to a script file. To see what I mean, take a look at Figure 1.

Screenshot shows an example of PowerShell code generated by ChatGPT

Code Generator 1

Figure 1. This is what it looks like when ChatGPT generates code.

While ChatGPT generates the requested code, it also includes extraneous text unrelated to the code. Before we can produce a script file, we must eliminate everything except the actual code.

Related:Interactive Data Analytics With PowerShell, SQL, and ChatGPT (Sample Script)

Here is the portion of the code that handles the string manipulation. The complete code will be provided at the end of this article.

$Code=$aiResponse$IndexValue = $Code.IndexOf("``")$Temp1 = $Code.substring($IndexValue+3)$IndexValue = $Temp1.IndexOf("``")$Temp2 = $Temp1.substring(0, $IndexValue-1)$Code = $Temp2$FinalCode=$Code# Code to remove the word PowerShell from the beginning of the string$PS=$Code.Substring(0,10)Write-host "PS is equal to " $PSIf ($PS -eq 'powershell'){            $FinalCode=$Temp2.Substring(10)            }# Output results$File = Read-Host "Please enter a filename (without an extension)"$Filepath = "C:Scripts" + $File + ".ps1"$FinalCode | Out-File -FilePath $Filepath

In the above code block, the first step involves creating a variable named $Code. Initially, the $Code variable contains the entire text generated by ChatGPT.

Referring back to Figure 1, you will notice three characters (```) just before the code block. Therefore, another variable, $IndexValue, is established to store the count of characters before (and including) the first occurrence of the ` character.

The next line of code introduces a new variable, $Temp1. I set $Temp1 equal to $Code.substring($Indexvalue+3). This substring operation instructs PowerShell to delete the first segment of the string up to the specified character. The $IndexValue variable reflects the position of the first ` character. Since there are three consecutive characters, I appended +3 to eliminate all three. At this point, the $Temp1 variable contains the actual code and anything following it. We have successfully removed any descriptive text appearing before the actual code.

We must now get rid of any text that comes after the actual code. To do this, I have declared the $IndexValue variable once again, this time based on the $Temp1 variable, not the $Code variable. This change is made because the only occurrence of the ` characters in $Temp1 is immediately after the code.

Next, I create another variable, $Temp2. Once again, I perform a substring operation, but I handle this one a little differently. My previous substring operation simply told PowerShell how many characters to remove from the beginning of the string. This time, the substring contains two numbers (0 and $IndexValue-1). This instructs PowerShell to retain all characters before the ` and delete everything else.  Consequently, $Temp2 contains only the code block.

Before writing the output to a file, there is one more thing to do. Occasionally (though not always), when ChatGPT generates PowerShell code, the first line of the code block simply says “PowerShell.” We need to check for the existence of the word “PowerShell” and, if present, remove it. That is handled by the following block of code:

$PS=$Code.Substring(0,10)Write-host "PS is equal to " $PSIf ($PS -eq 'powershell'){            $FinalCode=$Temp2.Substring(10)            }

Here, I have created a variable named $PS, which contains the first 10 characters of our string. In case you are wondering, I have copied $Temp to $Code, hence why we are examining the first 10 characters of $Code. I then use an If statement to check if these 10 characters spell out the word “PowerShell.” If they do, those 10 characters are stripped from the string. The final string is stored in a variable called $FinalCode.

The final step in the script is to generate a script file based on the code extracted from the ChatGPT output. I do that with these three lines of code:

$File = Read-Host "Please enter a filename (without an extension)"$Filepath = "C:Scripts" + $File + ".ps1"$FinalCode | Out-File -FilePath $Filepath

The first line prompts the user to enter a filename, minus the extension. The second line establishes a variable named $Filepath to create the complete path and filename for the script file being generated. The script file is saved with a .ps1 extension in the C:Scripts folder. The third line uses the Out-File cmdlet to export the contents of the $FinalCode variable to the script file.

Complete Source Code

Here is the full source code for my script:

$Key = Get-Content C:ScriptsGPTKey.txt$ApiEndpoint = "https://api.openai.com/v1/chat/completions"$AiSystemMessage = "You are a helpful assistant"[System.Collections.Generic.List[Hashtable]]$MessageHistory = @()Function Initialize-MessageHistory ($message){    $script:MessageHistory.Clear()    $script:MessageHistory.Add(@{"role" = "system"; "content" = $message}) | Out-Null}function Invoke-ChatGPT ($MessageHistory) {    # Set the request headers    $headers = @{    "Content-Type" = "application/json"    "Authorization" = "Bearer $Key"    }  # Form the Request    $requestBody = @{        "model" = "gpt-3.5-turbo"        "messages" = $MessageHistory        "max_tokens" = 1000 # Max amount of tokens the AI will respond with        "temperature" = 0.7 # Lower is more coherent, higher is more creative.    }    # Send the request    $response = Invoke-RestMethod -Method POST -Uri $ApiEndpoint -Headers $headers -Body (ConvertTo-Json $requestBody)    # Return the message content    return $response.choices[0].message.content}#Main BodyInitialize-MessageHistory $AiSystemMessage    $userMessage = Read-Host "Enter your query: "    $MessageHistory.Add(@{"role"="user"; "content"=$userMessage})    $aiResponse = Invoke-ChatGPT $MessageHistory    Write-Host "AI: $aiResponse" -ForegroundColor Yellow# Extract the code$Code=$aiResponse$IndexValue = $Code.IndexOf("``")$Temp1 = $Code.substring($IndexValue+3)$IndexValue = $Temp1.IndexOf("``")$Temp2 = $Temp1.substring(0, $IndexValue-1)$Code = $Temp2$FinalCode=$Code# Code to remove the word PowerShell from the beginning of the string$PS=$Code.Substring(0,10)Write-host "PS is equal to " $PSIf ($PS -eq 'powershell'){            $FinalCode=$Temp2.Substring(10)            }# Output results$File = Read-Host "Please enter a filename (without an extension)"$Filepath = "C:Scripts" + $File + ".ps1"$FinalCode | Out-File -FilePath $Filepath

About the Author

Brien Posey

Brien Posey is a bestselling technology author, a speaker, and a 20X Microsoft MVP. In addition to his ongoing work in IT, Posey has spent the last several years training as a commercial astronaut candidate in preparation to fly on a mission to study polar mesospheric clouds from space.

https://brienposey.com/

Sign up for the ITPro Today newsletter
Stay on top of the IT universe with commentary, news analysis, how-to's, and tips delivered to your inbox daily.

You May Also Like