BulkUpdateOfVirtualInstanceOfSAP_TrustedAccess/BulkMigrationScript.ps1 (197 lines of code) (raw):
# Define a parameter to accept the path to the JSON file
param(
[string]$JsonFilePath
)
# Function to process the input JSON file and return the parsed data
function ProcessInputFile($JsonFilePath)
{
# Check if the file path is provided
if (-not $JsonFilePath) {
Write-Host "Please provide the path to the JSON file using -JsonFilePath parameter."
Exit
}
# Check if the file exists
if (-not (Test-Path -Path $JsonFilePath -PathType Leaf)) {
Write-Host "The specified JSON file does not exist: $JsonFilePath"
Exit
}
# Read and parse the JSON file
$MigrationScriptInput = Get-Content -Path $JsonFilePath | ConvertFrom-Json
Write-Host "Migration Script Input from $JsonFilePath- $MigrationScriptInput"
return $MigrationScriptInput
}
# Function to get a list of SAP Virtual Instance (SVI) resource IDs based on the input
function GetListofResourceId($MigrationScriptInput)
{
# Extract SubscriptionId from the input
$SubscriptionId = $MigrationScriptInput.SubscriptionId
# Initialize arrays to store SVIs for processing and those that cannot be processed
$ProcessableSVIs = @()
$UnprocessedSVIs = @()
# Check if SubscriptionId is provided
if ($SubscriptionId)
{
# Retrieve a list of all SVIs in the specified subscription
$ListOfAllSVIs = Get-AzWorkloadsSapVirtualInstance -SubscriptionId $SubscriptionId
# Iterate over the list of SVIs
foreach ($svi in $ListOfAllSVIs) {
# Access individual SVI properties
$sviState = $svi.properties.state
$sviId = $svi.id
# Check if SVI is in a processable state
if ($sviState -ieq "RegistrationComplete" -or $sviState -ieq "SoftwareInstallationPending")
{
$ProcessableSVIs+=$sviId
}
else {
# Store details of unsupported SVIs
$unsupportedSviDetails = @{
id = $svi.id
Reason = "UnsupportedProvisioningState: "+$sviState
}
$UnprocessedSVIs+=$unsupportedSviDetails
}
}
}
# Check if specific ResourceIds are provided in the input
if ($MigrationScriptInput.ResourceIds)
{
# Iterate over the provided ResourceIds
foreach ($id in $MigrationScriptInput.ResourceIds)
{
try
{
# Retrieve details of SVI using the provided ResourceId
$sviDetails = Get-AzWorkloadsSapVirtualInstance -InputObject $id -ErrorAction Stop
}
catch
{
# Handle the case where SVI details cannot be retrieved
$unsupportedSviDetails = @{
id = $sviId
Reason = $_.Exception.Message
}
$UnprocessedSVIs+=$unsupportedSviDetails
continue
}
# Access individual SVI properties
$sviState = $sviDetails.state
# Check if SVI is in a processable state
if ($sviState -ieq "RegistrationComplete" -or $sviState -ieq "SoftwareInstallationPending")
{
$ProcessableSVIs+=$sviDetails.id
}
else
{
# Create a new object dynamically for unsupported SVIs
$unsupportedSviDetails = @{
id = $sviDetails.id
Reason = "UnsupportedProvisioningState: $sviState"
}
$UnprocessedSVIs+=$unsupportedSviDetails
}
}
}
# Output the lists of processable and unprocessable SVIs to a text file
$filePath = "sviStatus.txt"
Set-Content -Path $filePath -Value "SVIs to be Processed::"
foreach ($entry in $ProcessableSVIs) {
Add-Content -Path $filePath -Value $entry
}
Add-Content -Path $filePath -Value "SVIs cannot be Processed::"
foreach ($entry in $UnprocessedSVIs) {
$output = "ID: " + $entry.id + ", Reason: " + $entry.Reason
Add-Content -Path $filePath -Value $output
}
return $ProcessableSVIs
}
# Script block containing functions to patch SVIs
$PatchSVI = {
function PatchSVIwithNetworkAccessType($resourceId, $networkAccessType)
{
try {
# Attempt to patch SVI with network access type
Write-Host "Patch SVI ManagedResourcesNetworkAccessType: '$networkAccessType' for ResourceId: $resourceId."
$patchPrivate = Update-AzWorkloadsSapVirtualInstance -InputObject $resourceId -ManagedResourcesNetworkAccessType $networkAccessType
Write-Host "Patch SVI Successful for $resourceId."
}
catch {
Write-Host "An error occurred:"
Write-Host $_
}
}
function PatchSVIwithIdentityandNetworkAccessType($resourceId, $networkAccessType, $userAssignedidentity)
{
try {
# Retrieve SVI and MSI details
$svi = Get-AzWorkloadsSapVirtualInstance -InputObject $resourceId
$msi = $svi.identity
# Patch SVI with identity and network access type
$patchNone = Update-AzWorkloadsSapVirtualInstance -InputObject $resourceId -IdentityType "None"
Start-Sleep -Seconds 150
Write-Host "Patch SVI ManagedResourcesNetworkAccessType: '$networkAccessType' for ResourceId: $resourceId."
$patchPrivate = Update-AzWorkloadsSapVirtualInstance -InputObject $resourceId -IdentityType "UserAssigned" -ManagedResourcesNetworkAccessType $networkAccessType -UserAssignedIdentity @{ $userAssignedidentity = @{}; }
Write-Host "Patch SVI Successful for $resourceId."
}
catch {
Write-Host "An error occurred:"
Write-Host $_
}
}
}
# Function to check if the required module exists, and install it if not
function CheckModuleExists
{
if (Get-Module -ListAvailable -Name "Az.Workloads") {
Write-Host "Az.Workloads exists"
}
else {
Write-Host "Module does not exist. Installing Module."
Install-Module -Name Az.Workloads -AllowClobber -Force
}
}
# Main function to orchestrate the script execution
function main
{
# Check if Az.Workloads module exists or install it
CheckModuleExists
# Process the input JSON file
$input = ProcessInputFile($JsonFilePath)
# Get a list of SVIs to patch
$SVIsToPatch = GetListofResourceId($input)
# Set the default network access type if not provided
$networkAccessType = $input.AccessType
if (!$networkAccessType)
{
$networkAccessType = "Private"
}
if ($networkAccessType -ne "Public" -r $networkAccessType -ne "Private")
{
Write-Host "The networkAccessType value is not supported. Please provide from [Public, Private]"
Exit
}
# Get the identity from the input
$identity = $input.identity
# Script block for patching SVIs in parallel
$patchBlock = {
param($resourceId, $networkAccessType, $userAssignedidentity, $PatchSVIwithIdentityandNetworkAccessType, $PatchSVIwithNetworkAccessType)
if ($userAssignedidentity) {
PatchSVIwithIdentityandNetworkAccessType $resourceId $networkAccessType $userAssignedidentity
}
else {
PatchSVIwithNetworkAccessType $resourceId $networkAccessType
}
Start-Sleep -Seconds 5
}
# Loop through the items and start jobs for parallel execution
foreach ($resourceId in $SVIsToPatch)
{
Start-Job -InitializationScript $PatchSVI -ScriptBlock $patchBlock -ArgumentList $resourceId, $networkAccessType, $identity
}
# Wait for all jobs to complete
Get-Job | Wait-Job
# Receive results from jobs if needed
$results = Get-Job | Receive-Job
}
# Execute the main function
main