Skip to content

Instantly share code, notes, and snippets.

@fahadysf
Last active December 7, 2023 08:22
Show Gist options
  • Save fahadysf/9ea2cf7ec200391b13dd15003dcb49bd to your computer and use it in GitHub Desktop.
Save fahadysf/9ea2cf7ec200391b13dd15003dcb49bd to your computer and use it in GitHub Desktop.
Powershell Local DB User Creator for Panorama Template
### Needed stuff
Add-Type -AssemblyName System.Web
### GLOBAL Settings
$filePath = "C:\code\usernames.txt_CHANGE_ME"
$deviceUrl = "https://panorama_ip_or_fqdn_change_me"
$username = "admin"
$templateName = "template_name_change_me"
$Debug = $true
function Get-KeyFromXml {
param (
[string]$XmlString
)
try {
# Parse the XML string
$xml = [xml]$XmlString
# Extract the value of the <key> element
$key = $xml.response.result.key
# Return the extracted key
return $key
}
catch {
Write-Host "An error occurred while parsing the XML: $_"
return $null
}
}
function Get-KeygenResponse {
param (
[string]$Username,
[string]$Password,
[string]$ApiUrl
)
$EncodedPassword = [System.Web.HttpUtility]::UrlEncode($Password)
# Build the URL with the encoded username and password
$ApiUrlFull = $ApiUrl+"/api/?type=keygen&user=$Username&password=$EncodedPassword"
try {
# Send an HTTP GET request to the API URL
$Response = Invoke-WebRequest -Uri $ApiUrlFull -Method GET
# Return the response from the API
return $Response
}
catch {
Write-Host "An error occurred while making the API request: $_"
return $null
}
}
function Get-UserPhashOpCommand {
param (
[string]$Username,
[string]$Password,
[string]$ApiUrl,
[string]$ApiKey,
[string]$TemplateName
)
# Construct the XML data with variables
$XmlData = @"
<request>
<password-hash>
<username>$Username</username>
<password>$Password</password>
<templatename>$TemplateName</templatename>
</password-hash>
</request>
"@
# Define the API endpoint URL
$ApiUrlFull = $ApiUrl + "/api/?key=$ApiKey&type=op&cmd=$XmlData"
try {
# Make the GET request
$Response = Invoke-WebRequest -Uri $ApiUrlFull -Method GET -ContentType "application/xml"
# Return the response
return $Response
}
catch {
Write-Host "Get-UserPhashOpCommand : An error occurred while making the API request: $_"
Write-Host "API Request: $ApiUrlFull"
return $null
}
}
function Get-PhashFromXml {
param (
[string]$XmlString
)
try {
# Load the XML string
$xml = [xml]$XmlString
# Extract the value of the <phash> element
$phash = $xml.response.result.phash
# Return the extracted phash value
return $phash
}
catch {
Write-Host "An error occurred while parsing the XML: $_"
return $null
}
}
function Get-RandomPassword {
param (
[Parameter(Mandatory)]
[int] $length,
[Parameter(Mandatory)]
[int] $specialCharCount
)
if ( $Debug ) {
$DebugPreference = "Continue"
}
# Define the character set with alphanumeric characters
$charSet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'.ToCharArray()
# Define the special characters you want to include
$specialChars = '!@#$%'.ToCharArray()
# Initialize a random number generator
$rng = New-Object System.Security.Cryptography.RNGCryptoServiceProvider
$bytes = New-Object byte[]($length)
$rng.GetBytes($bytes)
$result = New-Object char[]($length)
# Generate the password with a specified number of special characters
for ($i = 0; $i -lt $length; $i++) {
if ($i -lt $specialCharCount) {
$result[$i] = $specialChars[$bytes[$i] % $specialChars.Length]
} else {
$result[$i] = $charSet[$bytes[$i] % $charSet.Length]
}
}
# Shuffle the password characters to add more randomness
$shuffledPassword = $result | Get-Random -Count $length
return (-Join $shuffledPassword)
}
function CreateUserWithPhash {
param (
[string]$Username,
[string]$Phash,
[string]$ApiUrl,
[string]$ApiKey,
[string]$TemplateName
)
$DebugPreference = "Continue"
# Construct the XML data with variables
$ElementValue = "<phash>$Phash</phash>"
# Define the API endpoint URL
$Xpath = "/config/devices/entry[@name='localhost.localdomain']/template/entry[@name='$TemplateName']/config/mgt-config/users/entry[@name='$Username']"
$headers = @{
'X-PAN-KEY' = $ApiKey
}
$formData = @{
'type' = "config"
'action' = "set"
'xpath' = $Xpath
'element' = $ElementValue
}
$ApiUrlFull = $ApiUrl + "/api/"
try {
# Make the POST request
$Response = Invoke-WebRequest -Uri $ApiUrlFull -Method POST -ContentType "application/x-www-form-urlencoded" -Body $formData -Headers $headers
# Return the response
return $Response
}
catch {
Write-Host "CreateUserWithPhash : An error occurred while making the API request: $_"
Write-Host "API Request: $ApiUrlFull"
return $null
}
}
#### Main Script Flow ###
# Prompt the user for a password without echoing the input
$securePassword = Read-Host -Prompt "Enter your password" -AsSecureString
# Convert the secure string to plain text if needed (not recommended for security reasons)
$password = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($securePassword))
$raw_response = Get-KeygenResponse -ApiUrl $deviceUrl -Username $username -Password $password
$api_key = Get-KeyFromXml -XmlString $raw_response
# Check if the userfile file exists
if ( $Debug ) {
$DebugPreference = "Continue"
}
if (Test-Path $filePath -PathType Leaf) {
# Read the file line by line and print each line
Get-Content $filePath | ForEach-Object {
$user = $_
# Create Random complex Password
$pass = Get-RandomPassword 12 2
Write-Debug "Password generated for user $user : $pass"
$EncodedPassword = [System.Web.HttpUtility]::UrlEncode($pass)
# Create the phash for the user
$raw_response = Get-UserPhashOpCommand -Username $user -Password $EncodedPassword -ApiUrl $deviceUrl -ApiKey $api_key -TemplateName $templateName
$user_phash = Get-PhashFromXml -XmlString $raw_response.Content
Write-Debug "Password Hash for user $user : $user_phash"
# Create the user in the template/entry
$response = CreateUserWithPhash -Username $user -Phash $user_phash -ApiUrl $deviceUrl -ApiKey $api_key -TemplateName $templateName
Write-Debug "User creation result for $user : $response.Content"
}
} else {
Write-Host "The specified file does not exist: $filePath"
exit
}
Write-Host "------ DONE ------"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment