Powershell Loop with two variables - azure

I am looking for a way to pipe many (100 paired variables) items into this powershell script. Each single command has two variables ResourceGroup and AccountName. I can build an array, but not sure how to get the script to execute the paired variables.
EDIT: Would there be any way to import these variables from CSV , or pull them directly.
$rgName = "<resource-group>"
$accountName = "<storage-account>"
$location = "<location>"
# Create a storage account with MinimumTlsVersion set to TLS 1.1.
New-AzStorageAccount -ResourceGroupName $rgName `
-AccountName $accountName `
-Location $location `
-SkuName Standard_GRS `
-MinimumTlsVersion TLS1_1
# Read the MinimumTlsVersion property.
(Get-AzStorageAccount -ResourceGroupName $rgName -Name $accountName).MinimumTlsVersion
# Update the MinimumTlsVersion version for the storage account to TLS 1.2.
Set-AzStorageAccount -ResourceGroupName $rgName `
-AccountName $accountName `
-MinimumTlsVersion TLS1_2
# Read the MinimumTlsVersion property.
(Get-AzStorageAccount -ResourceGroupName $rgName -Name $accountName).MinimumTlsVersion

If you want to group variables together, you could use an array of System.Management.Automation.PSCustomObject, then iterate this array and run your code:
param (
[Parameter(Mandatory = $true)]
[PSCustomObject[]]
$StorageAccountData
)
foreach ($obj in $StorageAccountData) {
$rgName = $obj.ResourceGroupName
$accountName = $obj.AccountName
$location = $obj.Location
# Create a storage account with MinimumTlsVersion set to TLS 1.1.
New-AzStorageAccount -ResourceGroupName $rgName `
-AccountName $accountName `
-Location $location `
-SkuName Standard_GRS `
-MinimumTlsVersion TLS1_1
# Read the MinimumTlsVersion property.
(Get-AzStorageAccount `
-ResourceGroupName $rgName `
-Name $accountName).MinimumTlsVersion
# Update the MinimumTlsVersion version for the storage account to TLS 1.2.
Set-AzStorageAccount `
-ResourceGroupName $rgName `
-AccountName $accountName `
-MinimumTlsVersion TLS1_2
# Read the MinimumTlsVersion property.
(Get-AzStorageAccount `
-ResourceGroupName $rgName `
-Name $accountName).MinimumTlsVersion
}
Then you could run this script like so:
PS C:\Users\user> $storageAccountData = #(
>> [PSCustomObject]#{
>> ResourceGroupName = 'storageRG'
>> AccountName = 'storage1'
>> Location = 'australiaeast'
>> }
>> [PSCustomObject]#{
>> ResourceGroupName = 'storageRG'
>> AccountName = 'storage2'
>> Location = 'australiaeast'
>> }
>> )
PS C:\Users\user> script.ps1 -StorageAccountData $storageAccountData
If you want to pipe this into the script, you can create a function and use ValueFromPipeline:
function MyFunction {
[CmdletBinding()]
param (
[Parameter(
Mandatory = $true,
ValueFromPipeline = $true
)]
[PSCustomObject[]]
$StorageAccountData
)
# rest of your code
}
Then pass the array of PSCustomObject down then pipeline to this function with $storageAccountData | MyFunction. Make sure to dot source the script to load the function into your preferred scope before calling the function.
Update
If you wanted to read from a CSV file(e.g. storage-accounts.csv):
AccountName,ResourceGroupName,Location
storage1,storageRG,australiaeast
storage2,storageRG,australiaeast
You just need use Import-Csv:
$storageAccountData = Import-Csv -Path .\storage-accounts.csv
foreach ($obj in $storageAccountData) {
# rest of your code
}

Related

Setup and deploy Azure function using PowerShell

I try to setup and deploy Azure Function by using PowerShell script based on this topic: Setup Azure Function from PowerShell
My script looks like this:
#=============Defining All Variables=========
$location = 'Central US'
$resourceGroupName = 'MyResourceGroup'
$subscriptionId = 'MysubscriptionId'
$functionAppName = 'MyfunctionAppName'
$appServicePlanName = 'ASP-test-8b50'
$tier = 'Dynamic'
$archivePath = 'd:\TestAzureFunc.zip'
Connect-AzAccount
#========Creating Azure Resource Group========
$resourceGroup = Get-AzResourceGroup | Where-Object { $_.ResourceGroupName -eq $resourceGroupName }
if ($resourceGroup -eq $null)
{
New-AzResourceGroup -Name $resourceGroupName -Location $location -force
}
#selecting default azure subscription by name
Select-AzSubscription -SubscriptionID $subscriptionId
Set-AzContext $subscriptionId
#========Creating App Service Plan============
New-AzAppServicePlan -ResourceGroupName $resourceGroupName -Name $appServicePlanName -Location $location -Tier $tier
$functionAppSettings = #{
ServerFarmId="/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Web/serverfarms/$appServicePlanName";
alwaysOn=$True;
}
#========Creating Azure Function========
$functionAppResource = Get-AzResource | Where-Object { $_.ResourceName -eq $functionAppName -And $_.ResourceType -eq "Microsoft.Web/Sites" }
if ($functionAppResource -eq $null)
{
New-AzResource -ResourceType 'Microsoft.Web/Sites' -ResourceName $functionAppName -kind 'functionapp' -Location $location -ResourceGroupName $resourceGroupName -Properties $functionAppSettings -force
}
#========Defining Azure Function Settings========
$AppSettings =#{}
$AppSettings =#{'FUNCTIONS_EXTENSION_VERSION' = '~2';
'FUNCTIONS_WORKER_RUNTIME' = 'dotnet';}
Set-AzWebApp -Name $functionAppName -ResourceGroupName $resourceGroupName -AppSettings $AppSettings
#========Deploy Azure Function from zip========
Publish-AzWebapp -ResourceGroupName $resourceGroupName -Name $functionAppName -ArchivePath $archivePath
The script works without errors. Resource group and Function App created as needed. But the list of functions of the Function App is empty.
Function details here:
My intuition tells me that I've forgotten something. But I don't know what.
Could you advise me on how to deploy my Azure function properly?
One of the workaround you can follow ,
Looking at your script we need to ensure that we are providing function app configuration as below cmdlts the link you followed:-
$AzFunctionAppSettings = #{
APPINSIGHTS_INSTRUMENTATIONKEY = $AppInsightsKey;
AzureWebJobsDashboard = $AzFunctionAppStorageAccountConnectionString;
AzureWebJobsStorage = $AzFunctionAppStorageAccountConnectionString;
FUNCTIONS_EXTENSION_VERSION = "~4";
FUNCTIONS_WORKER_RUNTIME = "dotnet";
}
And also make sure that the storage account connection string you provided in the function is same as here providing.
And then you can navigate to Kudu API to check the wwwroot folder is exist or not.
For more information please refer the below links:-
SO THREAD|Powershell command Publish-AzWebApp not publishing apllication
BLOG|How to Deploy Azure Function Apps With Powershell.

Deploying multiple scripts with CustomScriptExtension on an Azure Windows VM

I'm trying to deploy multiple PowerShell scripts to an Azure Windows VM by using the CustomScriptExtension.
The scripts are independent from each other so the order of their deployment doesn't matter. Also the scripts are in same blob container.
I have already a working template as below for installing one script at the moment:
$resourceGroup = "myResourceGroup"
$vmName = "myVM"
$location = "easteurope"
$storageAcctName = "myStorageAcct"
$storageKey = $env:ARM_ACCESS_KEY
$fileUri = #("https://xxxxx.blob.core.windows.net/xxxx/01-installTools.ps1")
$protectedSettings = #{"storageAccountName" = $storageAcctName; "storageAccountKey" = $storageKey};
$settings = #{"fileUris" = $fileUri;"commandToExecute" ="powershell -ExecutionPolicy Unrestricted -File 01-installTools.ps1"};
#run command
Set-AzVMExtension -ResourceGroupName $resourceGroup `
-Location $location `
-ExtensionName "IIS" `
-VMName $vmName `
-Publisher "Microsoft.Compute" `
-ExtensionType "CustomScriptExtension" `
-TypeHandlerVersion "1.8" `
-Settings $settings `
-ProtectedSettings $protectedSettings;
Also is it possible to use 2 CustomScriptExtensions?
I get a TypeHandlerVersion error if i try to do that.

Custome Linux VM Extension on Azure

Ttrying to run .sh script via custome script extension via set-azvmextension but nither its througing an error nor output gettting generated on linux vm.
$resourceGroupName = "abc-RG"
$storageAccountName = "abcdiag"
$containerName = "public"
$location = "Central India"
$vmName = "abclinux2"
$extensionName = "vm_rwq"
$deploymentScript = "dd.sh"
$destintionPath = "/tmp/"
$storageAccountKeys = (Get-AzStorageAccountKey -ResourceGroupName $resourceGroupName -Name $storageAccountName).Value
$storageAccountKey = $storageAccountKeys[0]
$Settings = #{"fileUris" = "[https://abcdiag.blob.core.windows.net/public/dd.sh]"; "commandToExecute" = "sh dd.sh"};
$ProtectedSettings = #{"storageAccountName" = $storageAccountName; "storageAccountKey" = $storageAccountKey};
Set-AzVMExtension -ResourceGroupName $resourceGroupName -Location $location -VMName $vmName >>
If you want to use Azure Custom Script Extension Version 1 with Linux virtual machines, the publisher should be Microsoft.OSTCExtensions and the type should be CustomScriptForLinux. For more details, please refer to the document
For example
$resourceGroupName = ""
$storageAccountName = ""
$location = ""
$vmName = ""
$extensionName = "vm_rwq"
$fileUri = #("https://jimtestperfdiag516.blob.core.windows.net/test/config-music.sh")
$storageAccountKeys = (Get-AzStorageAccountKey -ResourceGroupName "test" -Name $storageAccountName).Value
$storageAccountKey = $storageAccountKeys[0]
$Settings = #{'fileUris' =$fileUri; "commandToExecute" = "./config-music.sh"};
$ProtectedSettings = #{"storageAccountName" = $storageAccountName; "storageAccountKey" = $storageAccountKey};
Set-AzVMExtension -ResourceGroupName $resourceGroupName -Location $location -VMName $vmName -Name $extensionName -Publisher "Microsoft.OSTCExtensions" -Type "CustomScriptForLinux" -TypeHandlerVersion "1.5" -Settings $Settings -ProtectedSettings $ProtectedSettings
Update
According to my research, Azure Custom Script Extension Version 1 does not support Red Hat operating System VM. For more details, please refer to the document
So if you want to install Custom Script Extension on Red Hat VM, we should use the new version: version 2. For further information, please refer to the article. Besides, if you want to use script to install the extension on Azure Linux VM, Azure CLI is a better way.
az vm extension set \
--resource-group myResourceGroup \
--vm-name myVM \
--name customScript \
--publisher Microsoft.Azure.Extensions \
--settings ./script-config.json \
--protected-settings ./protected-config.json
But, if you still want to use PowerShell, please refer to the following script
$resourceGroupName = ""
$storageAccountName = ""
$location = ""
$vmName = ""
$extensionName = "vm_rwq"
$fileUri = #("https://jimtestperfdiag516.blob.core.windows.net/test/config-music.sh")
$storageAccountKeys = (Get-AzStorageAccountKey -ResourceGroupName "test" -Name $storageAccountName).Value
$storageAccountKey = $storageAccountKeys[0]
$Settings = #{'fileUris' =$fileUri; "commandToExecute" = "./config-music.sh"};
$ProtectedSettings = #{"storageAccountName" = $storageAccountName; "storageAccountKey" = $storageAccountKey};
Set-AzVMExtension -ResourceGroupName $resourceGroupName -Location $location -VMName $vmName -Name $extensionName `
-Publisher "Microsoft.Azure.Extensions" -Type "CustomScript" `
-TypeHandlerVersion "2.1" -Settings $Settings -ProtectedSettings $ProtectedSettings

Change password of Azure VM using PowerShell

I have tried this approach to change a password of an Azure VM:
$resgroup = "rsource1"
$vmName = "virtualmachine1"
$VM = Get-AzVM -ResourceGroupName $resgroup -Name $vmName
$Credential = Get-Credential
$VM | Set-AzureVMAccessExtension –UserName $Credential.UserName `
–Password $Credential.GetNetworkCredential().Password
$VM | Update-AzVM
But I keep getting this error:
Object reference not set to an instance of an object.
When I console.log the values of $Credential.UserName and $Credential.GetNetworkCredential().Password I got the values of username and password that I have inputted.
What am I missing here?
I've never used Set-AzureVMAccessExtension, but I've used the Az PowerShell equivalant Set-AzVMAccessExtension. It needs you to pass -Credential $Credential instead of -UserName and -Password.
You can try this script I made a while ago to to reset passwords for Azure VMs:
# Replace these values with your own
$resourceGroupName = "Servers-RG"
$vmName = "server1"
# Get the VM into an object
$vm = Get-AzVM -ResourceGroupName $resourceGroupName -Name $vmName
# Store credentials you want to change
$credential = Get-Credential -Message "Enter your username and password for $vmName"
# Store parameters in a hashtable for splatting
# Have a look at https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_splatting?view=powershell-7
$extensionParams = #{
'VMName' = $vmName
'Credential' = $credential
'ResourceGroupName' = $resourceGroupName
'Name' = 'AdminPasswordReset'
'Location' = $vm.Location
}
# Pass splatted parameters and update password
Set-AzVMAccessExtension #extensionParams
# Restart VM
# Don't need to pass any switches since they are inferred ByPropertyName
# Have a look at https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_pipelines?view=powershell-7
$vm | Restart-AzVM
I found that the password update doesn't happen until you restart the VM, so Restart-VM is required.
If anyone interested in the Linux (KISS) version (no VM restart needed):
$settings = '{}'
$protectedSettings = '{
"username": "<yourusername, prefer using Credentials object>",
"password": "<yourpassword, prefer using Credentials object>"
}'
Set-AzVMExtension `
-VMName $vmName `
-ResourceGroupName $rgName `
-Location $location `
-Name "VMAccessForLinux" `
-Publisher "Microsoft.OSTCExtensions" `
-ExtensionType "VMAccessForLinux" `
-TypeHandlerVersion "1.4" `
-Settingstring $settings `
-ProtectedSettingString $protectedSettings

How to Create App Service with a subType of api

In powershell and using the new-azwebapp to create a website in our app service plan. But it only ever seems to create a type of app
I'm trying to create it with the type of api like you can when you select from the Azure Portal UI, but I can't see a setting in the configuration to do this.
After creating I set the AppSettings and then try to update the Type, but it doesn't seem to matter.
Hoping that I'm missing something simple.
$siteName = "namegoeshere"
$sitePlan = "myplanname"
$siteLocation = "Australia East"
$siteResourceGroup = "resourcegroupname"
$createdSite = new-azWebApp -Name $siteName -ResourceGroupName $siteResourceGroup -AppServicePlan $sitePlan -Location $siteLocation
$newAppSettings = #{ "name"="value"}
Set-AzWebApp -Name $siteName -ResourceGroupName $siteResourceGroup -AppSettings $newAppSettings -AppServicePlan Grower #-PhpVersion 0
$p = #{ 'type' = "api" }
$r = Set-AzResource -Name $siteName -ResourceGroupName $siteResourceGroup -ResourceType Microsoft.Web/sites -PropertyObject $p -ApiVersion 2016-03-01 -Kind "app"
echo $r.Properties
The type api is not set with type, in the New-AzureRmResource parameters there is a parameter to set it, it's [-Kind <String>]. You could check it here.
Here is an example.
# CREATE "just-an-api" API App
$ResourceLocation = "West US"
$ResourceName = "just-an-api"
$ResourceGroupName = "demo"
$PropertiesObject = #{
# serverFarmId points to the App Service Plan resource id
serverFarmId = "/subscriptions/SUBSCRIPTION-GUID/resourceGroups/demo/providers/Microsoft.Web/serverfarms/plan1"
}
New-AzureRmResource -Location $ResourceLocation `
-PropertyObject $PropertiesObject `
-ResourceGroupName $ResourceGroupName `
-ResourceType Microsoft.Web/sites `
-ResourceName "just-an-api/$ResourceName" `
-Kind 'api' `
-ApiVersion 2016-08-01 -Force

Resources