mirror of
https://github.com/NetSPI/MicroBurst
synced 2026-06-08 12:01:29 +00:00
219 lines
11 KiB
PowerShell
219 lines
11 KiB
PowerShell
<#
|
|
File: Get-AzBatchAccountData.ps1
|
|
Author: Karl Fosaaen (@kfosaaen), NetSPI - 2023
|
|
Description: PowerShell functions for dumping Azure Batch commands, environmental variables, etc.
|
|
#>
|
|
|
|
function Get-AzBatchAccountData{
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
PowerShell function for dumping information from Azure Batch Accounts.
|
|
.DESCRIPTION
|
|
The function will dump available information for an Azure Batch Account. This includes environmental variables, tasks, jobs, etc.
|
|
.PARAMETER Subscription
|
|
Subscription to use.
|
|
.PARAMETER folder
|
|
The folder to output to.
|
|
.EXAMPLE
|
|
PS C:\> Get-AzBatchAccountData -folder BatchOutput -Verbose
|
|
VERBOSE: Logged In as kfosaaen@example.com
|
|
VERBOSE: Dumping Batch Accounts from the "Sample Subscription" Subscription
|
|
VERBOSE: 1 Batch Account(s) Enumerated
|
|
VERBOSE: Attempting to dump data from the testspi account
|
|
VERBOSE: Attempting to dump keys
|
|
VERBOSE: 1 Pool(s) Enumerated
|
|
VERBOSE: Attempting to dump pool data
|
|
VERBOSE: 13 Job(s) Enumerated
|
|
VERBOSE: Attempting to dump job data
|
|
VERBOSE: Completed dumping of the testspi account
|
|
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
Param(
|
|
[Parameter(Mandatory=$false,
|
|
HelpMessage="Subscription to use.")]
|
|
[string]$Subscription = "",
|
|
|
|
[Parameter(Mandatory=$false,
|
|
HelpMessage="Folder to output to.")]
|
|
[string]$folder = ""
|
|
)
|
|
|
|
# Check to see if we're logged in
|
|
$LoginStatus = Get-AzContext
|
|
$accountName = ($LoginStatus.Account).Id
|
|
if ($LoginStatus.Account -eq $null){Write-Warning "No active login. Prompting for login."
|
|
try {Connect-AzAccount -ErrorAction Stop}
|
|
catch{Write-Warning "Login process failed."}
|
|
}
|
|
else{}
|
|
|
|
|
|
# Subscription name is technically required if one is not already set, list sub names if one is not provided "Get-AzSubscription"
|
|
if ($Subscription){
|
|
Select-AzSubscription -SubscriptionName $Subscription | Out-Null
|
|
}
|
|
else{
|
|
# List subscriptions, pipe out to gridview selection
|
|
$Subscriptions = Get-AzSubscription -WarningAction SilentlyContinue
|
|
$subChoice = $Subscriptions | Out-GridView -Title "Select One or More Subscriptions" -PassThru
|
|
foreach ($sub in $subChoice) {Get-AzBatchAccountData -Subscription $sub -folder $folder}
|
|
return
|
|
}
|
|
|
|
Write-Verbose "Logged In as $accountName"
|
|
|
|
|
|
# Check Folder Path
|
|
if ($folder -ne ""){
|
|
if(Test-Path $folder){}
|
|
else{New-Item -ItemType Directory $folder | Out-Null}
|
|
}
|
|
else{$folder = $PWD.Path}
|
|
|
|
# Stop the change warnings
|
|
Update-AzConfig -DisplayBreakingChangeWarning $false | Out-Null
|
|
|
|
Write-Verbose "Dumping Batch Accounts from the `"$((get-azcontext).Subscription.Name)`" Subscription"
|
|
|
|
#Get list of Batch Accounts
|
|
$batchAccounts = Get-AzBatchAccount
|
|
|
|
Write-Verbose "`t$($batchAccounts.Count) Batch Account(s) Enumerated"
|
|
|
|
$batchAccounts | ForEach-Object{
|
|
|
|
$currentBatchAccount = $_.AccountName
|
|
|
|
Write-Verbose "`t`tAttempting to dump data from the $currentBatchAccount account"
|
|
|
|
# Get Account Keys
|
|
Try{
|
|
Write-Verbose "`t`t`tAttempting to dump keys"
|
|
$batchKeys = Get-AzBatchAccountKeys -AccountName $_.AccountName
|
|
"Primary Key: "+$batchKeys.PrimaryAccountKey | Out-File -Append "$folder\$currentBatchAccount-Keys.txt"
|
|
"Secondary Key: "+$batchKeys.SecondaryAccountKey | Out-File -Append "$folder\$currentBatchAccount-Keys.txt"
|
|
}
|
|
Catch{Write-Verbose "`t`t`tNo ListKeys Permissions on the $currentBatchAccount Batch Account"}
|
|
|
|
|
|
# Get Batch Context
|
|
$batchContext = Get-AzBatchAccount -AccountName $_.AccountName
|
|
|
|
# Get Batch Pools
|
|
$batchPools = Get-AzBatchPool -BatchContext $batchContext -Verbose:$false
|
|
|
|
Write-Verbose "`t`t`t$($batchPools.Count) Pool(s) Enumerated"
|
|
Write-Verbose "`t`t`t`tAttempting to dump pool data"
|
|
|
|
# For Each Pool, get the ENV variables and commands from the start task
|
|
$batchPools | ForEach-Object {
|
|
"Pool: "+$_.Id | Out-File -Append "$folder\$currentBatchAccount-Pools.txt"
|
|
"Start Task Command: "+$_.StartTask.CommandLine | Out-File -Append "$folder\$currentBatchAccount-Pools.txt"
|
|
if($_.StartTask.EnvironmentSettings.Values -ne $null){
|
|
"Start Task ENV: "| Out-File -Append "$folder\$currentBatchAccount-Pools.txt"
|
|
$tempKey = $_.StartTask.EnvironmentSettings
|
|
$_.StartTask.EnvironmentSettings.keys | ForEach-Object{"`t"+$_+"="+$tempKey.$_ | Out-File -Append "$folder\$currentBatchAccount-Pools.txt"}
|
|
}
|
|
if($_.StartTask.ResourceFiles.StorageContainerUrl -ne $null){
|
|
"Start Task Files: "+$_.StartTask.ResourceFiles.StorageContainerUrl+"`n`n" | Out-File -Append "$folder\$currentBatchAccount-Pools.txt"
|
|
}
|
|
}
|
|
|
|
# Get list of Jobs
|
|
$batchJobs = Get-AzBatchJob -BatchContext $batchContext -Verbose:$false
|
|
|
|
Write-Verbose "`t`t`t$($batchJobs.Count) Job(s) Enumerated"
|
|
Write-Verbose "`t`t`t`tAttempting to dump job data"
|
|
|
|
# For Each Job, get the ENV variables and commands from the tasks
|
|
$batchJobs | ForEach-Object {
|
|
# Job Manager
|
|
"==================== Job ID: "+$_.Id+" ====================" | Out-File -Append "$folder\$currentBatchAccount-Jobs.txt"
|
|
"Job Manager Task Command: "+$_.JobManagerTask.CommandLine | Out-File -Append "$folder\$currentBatchAccount-Jobs.txt"
|
|
if($_.JobManagerTask.EnvironmentSettings.Values -ne $null){
|
|
"Job Manager ENV: "| Out-File -Append "$folder\$currentBatchAccount-Jobs.txt"
|
|
$tempKeyJM = $_.JobManagerTask.EnvironmentSettings
|
|
$_.JobManagerTask.EnvironmentSettings.keys | ForEach-Object{"`t"+$_+"="+$tempKeyJM.$_ | Out-File -Append "$folder\$currentBatchAccount-Jobs.txt"}
|
|
}
|
|
if($_.JobManagerTask.ResourceFiles.StorageContainerUrl -ne $null){
|
|
"Job Manager Task Files: "+$_.JobManagerTask.ResourceFiles.StorageContainerUrl+"`n" | Out-File -Append "$folder\$currentBatchAccount-Jobs.txt"
|
|
}
|
|
|
|
# Job Prep
|
|
"Job Preparation Task Command: "+$_.JobPreparationTask.CommandLine | Out-File -Append "$folder\$currentBatchAccount-Jobs.txt"
|
|
if($_.JobPreparationTask.EnvironmentSettings.Values -ne $null){
|
|
"Job Preparation ENV: "| Out-File -Append "$folder\$currentBatchAccount-Jobs.txt"
|
|
$tempKeyJP = $_.JobPreparationTask.EnvironmentSettings
|
|
$_.JobPreparationTask.EnvironmentSettings.keys | ForEach-Object{"`t"+$_+"="+$tempKeyJP.$_ | Out-File -Append "$folder\$currentBatchAccount-Jobs.txt"}
|
|
}
|
|
if($_.JobPreparationTask.ResourceFiles.StorageContainerUrl -ne $null){
|
|
"Job Preparation Task Files: "+$_.JobPreparationTask.ResourceFiles.StorageContainerUrl+"`n" | Out-File -Append "$folder\$currentBatchAccount-Jobs.txt"
|
|
}
|
|
|
|
# Job Release
|
|
"Job Release Task Command: "+$_.JobReleaseTask.CommandLine | Out-File -Append "$folder\$currentBatchAccount-Jobs.txt"
|
|
|
|
if($_.JobReleaseTask.EnvironmentSettings.Values -ne $null){
|
|
"Job Release ENV: "| Out-File -Append "$folder\$currentBatchAccount-Jobs.txt"
|
|
$tempKeyJR = $_.JobReleaseTask.EnvironmentSettings
|
|
$_.JobReleaseTask.EnvironmentSettings.keys | ForEach-Object{"`t"+$_+"="+$tempKeyJR.$_ | Out-File -Append "$folder\$currentBatchAccount-Jobs.txt"}
|
|
}
|
|
if($_.JobReleaseTask.ResourceFiles.StorageContainerUrl -ne $null){
|
|
"Job Release Task Files: "+$_.JobReleaseTask.ResourceFiles.StorageContainerUrl+"`n" | Out-File -Append "$folder\$currentBatchAccount-Jobs.txt"
|
|
}
|
|
|
|
# Get advanced ENV Settings
|
|
if($_.CommonEnvironmentSettings.Values -ne $null){
|
|
"Common ENV Settings: "| Out-File -Append "$folder\$currentBatchAccount-Jobs.txt"
|
|
$tempKeyENV = $_.CommonEnvironmentSettings
|
|
$_.CommonEnvironmentSettings.keys | ForEach-Object{"`t"+$_+"="+$tempKeyENV.$_ | Out-File -Append "$folder\$currentBatchAccount-Jobs.txt"}
|
|
}
|
|
|
|
# Extra line to break up jobs
|
|
"`n"| Out-File -Append "$folder\$currentBatchAccount-Jobs.txt"
|
|
}
|
|
|
|
# Get all the extra Sub-Tasks
|
|
$AccessToken = Get-AzAccessToken -ResourceUrl "https://batch.core.windows.net/"
|
|
if ($AccessToken.Token -is [System.Security.SecureString]) {
|
|
$ssPtr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($AccessToken.Token)
|
|
try {
|
|
$batchToken = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($ssPtr)
|
|
} finally {
|
|
[System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($ssPtr)
|
|
}
|
|
} else {
|
|
$batchToken = $AccessToken.Token
|
|
}
|
|
$jobsList = ((Invoke-WebRequest -Verbose:$false -Uri "https://$($batchContext.AccountEndpoint)/jobs?api-version=2022-10-01.16.0&maxresults=1000&paginationeffort=1" -Headers @{Authorization="Bearer $batchToken"}).Content | ConvertFrom-Json).value
|
|
$jobsList | ForEach-Object{
|
|
$currentJob = $_.id
|
|
|
|
# List Job-sub-tasks
|
|
$subTasks = ((Invoke-WebRequest -Verbose:$false -Uri "$($_.url)/tasks?api-version=2022-10-01.16.0&maxresults=1000&%24select=id%2Curl" -Headers @{Authorization="Bearer $batchToken"}).Content | ConvertFrom-Json).value
|
|
$subTasks | ForEach-Object{
|
|
$jobRuns = (Invoke-WebRequest -Verbose:$false -Uri "$($_.url)?api-version=2022-10-01.16.0" -Headers @{Authorization="Bearer $batchToken"}).Content | ConvertFrom-Json
|
|
$jobRuns | ForEach-Object{
|
|
|
|
"==================== Job ID: $currentJob === Sub-Task ID: $($_.id) ====================" | Out-File -Append "$folder\$currentBatchAccount-Jobs.txt"
|
|
"Sub-Task Command: "+$_.commandLine | Out-File -Append "$folder\$currentBatchAccount-Jobs.txt"
|
|
|
|
if($_.environmentSettings -ne "{}"){
|
|
"Sub-Task ENV: " | Out-File -Append "$folder\$currentBatchAccount-Jobs.txt"
|
|
"`t"+$_.environmentSettings.name+"="+$_.environmentSettings.value | Out-File -Append "$folder\$currentBatchAccount-Jobs.txt"
|
|
}
|
|
|
|
if($_.resourceFiles -ne $null){
|
|
"Sub-Task Files: "+($_.resourceFiles).storageContainerUrl+"`n" | Out-File -Append "$folder\$currentBatchAccount-Jobs.txt"
|
|
}
|
|
"`n"| Out-File -Append "$folder\$currentBatchAccount-Jobs.txt"
|
|
}
|
|
}
|
|
}
|
|
|
|
Write-Verbose "`t`tCompleted dumping of the $currentBatchAccount account"
|
|
}
|
|
} |