Cannot wire up Azure Scaleset to Automation DSC using powershell cmdlets - azure

I'm trying to wire up Scaleset VMs to the Azure Automation DSC server using the DSC extension. This is not exposed via the Portal, but from this documentation it seems that it should be possible though templates and powershell cmd line.
I have the boiled things down to the following snippet (with sensitive vars masked):
$settings = #{
configurationArguments = #{
registrationUrl = "https://ne-agentservice-prod-1.azure-automation.net/accounts/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx"
}
}
$protectedSettings = #{
configurationArguments = #{
registrationKey = #{
userName = "NOT_USED"
password = "/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=="
}
}
}
Get-AzureRmVmss -ResourceGroupName $resourceGroupName -VMScaleSetName $VmSsName |
Add-AzureRmVmssExtension -Name "DSC" -Publisher "Microsoft.Powershell" -Type "DSC" -TypeHandlerVersion "2.24" -Setting $settings -ProtectedSetting $protectedSettings |
Update-AzureRmVmss
In the portal, the extension is listed. However nothing is happening: I neither see any VMs listed in the Automation DSC "Nodes" list, nor do I see an DSC activity on the scaleset VMs - the event viewer for DSC is empty; the "c:\WindowsAzure\Logs" folder has nothing related to DSC.
I'm at wits-end as I feel tantalizingly close to getting this working, but am getting no feedback as to what is wrong...

I've managed to get the Add-AzureRmVmssExtension as part of a New-AzureRmVmss powershell pipeline flow. I needed to make two changes:
1) to not encode the $setting and $protectedSetting hashtables as Json - my original snippet was using ConvertTo-Json on the hashtable to get string json. In my defence, the documentation for those params indicates: "Specifies private configuration for the extension, as a string.". I will file a documentation bug.
2) (and this I think is the main reason), I updated the TypeHandlerVersion to 2.76 which is the current latest version - copy-paste from an Internet example gave me 2.24. I'm gonna see if I can get away with not specifying the version at all - I would always want the latest.

Related

Azure apply multiple tags to all resources under a specific Resource Group

I am trying to find out if its possible to apply multiple tags to all of the resources under a specific Resource Group in Azure. I don't know if this is possible because right now I am doing it manually via the Azure Portal but since our resources exploded I can't do it manually any more.
One of the workaround is that you can add multiple tags to all the resources in you Resource Group through Powershell using New-AzTag. Below is the command that worked for me.
$tags = #{"<Tag1Name>"="<Value1>"; "<Tag2Name>"="<Value2>"}
$rs = get-azresource -ResourceGroup <Your_Resource_Group>
foreach($r in $rs){
New-AzTag -ResourceId $r.ResourceId -Tag $tags
}
In case if you are updating the Tag you can follow the answer suggested by Stanley Gong - Update Azure resource tags for multiple resources - Stack Overflow
$rs = get-azresource -TagName Environment
foreach($r in $rs){
if($r.Tags.Environment -eq 'Non-Prodd'){
$r.Tags.Environment = "Non-Prod"
Set-AzResource -ResourceId $r.ResourceId -Tag $r.Tags -Force
}
}
This can be also done in Azure CLI using az tag create apart from using Azure portal and powershell.
REFERENCES: Tag resources - Microsoft Docs

How do I change a Platform Setting in an Azure Function App using a Powershell runbook

Specifically, I am looking to write an automation runbook for changing a Function App's HTTP Version from it's 1.1 default to 2.0. I know there is a simple way to do this via CLI commands, but I'm trying to get a working solution using a powershell runbook.
So far, I've been able to find the setting by doing...
$FA = Get-AzFunctionApp -Name <foo> -ResourceGroupName <bar>
$FA.Config.Http20Enabled
False
I've attempted to alter $FA and then pipe it through Update-AzFunctionApp...
$FA.Config.Http20Enabled = $True
$FA | Update-AzFunctionApp
with no success.
Not sure if I'm close to the right solution but I can't seem to find any Azure functionality that changes platform settings in this way. Any insight would be much appreciated!
I was able to find a solution to my original question. Instead of using the AzFunctionApp cmdlets, I used AzResource.
$FA = Get-AzResource -ResourceGroupName <foo> -Name <bar> -ResourceType Microsoft.Web/sites/config -ApiVersion 2021-02-01
$FA.Properties.http20Enabled = $True
Set-AzResource -ResourceId $FA.ResourceId -Properties $FA.Properties
I presume other config settings can be changed along with the property I needed.
I found (as well as the Azure CLI) you can use the PowerShell cmdlets for Web Apps. These work on Azure Functions too!
For simple examples, perhaps to just toggle a feature you can call Set-AzWebApp in one line. Here are two examples:
(1) to enable HTTPS only:
Set-AzWebApp -Name $functionName -ResourceGroupName $rg -HttpsOnly $true
Or (2) to disable FTP/FTPs:
Set-AzWebApp -Name $functionName -ResourceGroupName $rg -FtpsState "Disabled"
For more complex property changes, like enabling HTTP 2.0. You can do this in just a few more lines of PowerShell. See for example:
$funcAsApp = Get-AzWebApp -Name $functionName -ResourceGroupName $rg
$funcAsApp.SiteConfig.Http20Enabled = $true
$funcAsApp | Set-AzWebApp
For more information see the MSDN help here: https://learn.microsoft.com/en-us/powershell/module/az.websites/set-azwebapp?view=azps-6.6.0

How to fix this error in azure PowerShell : "Can not remove tag/tag value because it's being referenced by other resources."

Im want to delete the tags from large number of VM in microsoft azure.
But I get this error : Can not remove tag/tag value because it's being referenced by other resources. What I need to do and how to fix this error???
Remove-AzureRmTag -Name "sada"
This code i have used to remove sada from all my Azure Virtual Machines
this means this tag is being used by some resource in azure, you can only remove unused tags with this cmdlet. so your only option is to remove all those tags from existing resource (you can use a fairly simple powershell script for that, or just mass tagging from the portal). and then you can run this cmdlet.
something like this:
$res = Get-AzResource -ErrorAction SilentlyContinue
$res.ForEach{
if ( $_.tags.ContainsKey('sada') ) {
$_.tags.Remove('sada')
}
$_ | Set-AzResource -Tags $_.tags
}
You cannot delete a tag or value that is currently applied to a resource or resource group. Before using Remove-AzTag, use the Tag parameter of the Set-AzResourceGroup cmdlet to delete the tag or values from the resource or resource group. https://learn.microsoft.com/en-us/powershell/module/az.resources/remove-aztag?view=azps-4.8.0#description
The Solution is simple:
Update-AzTag -ResourceId $resource.id -Tag $removeTags -Operation Delete

Get private IP of VM in Azure Dev Test Lab using Powershell

Just now I started with Azure DevTest Lab. I created a VM in lab using a json template. I want to use the public IP of the VM using powershell or may be I would like to return the same using template, if I can.
The challenge here is as per DTL concept the VM is created in a new resource group other than the one where your lab exists. I can definitely see the name of resource group of lab VM on portal but I am not able to figure out how this can be done using powershell. I am working on an automation so I need to do it by powershell.
Refer to the picture. The lab seems to be in a resource group in the same where the lab exist shown in green box. But, technically the lab VM resides in dynamically created resource gruop (RG name pattern = labname + VM name + Some Random digits) shown in light yellow in screenshot.
Other solutions are helpful but not complete. I am doing in this way - I am returning the default output of template that is vmId. Refer from template link
Now we need to manipulate this vmId to get the name of resource group where the lab VM has been created.
$result = New-AzureRmResourceGroupDeployment -ResourceGroupName "aatifdtlrg207912" -TemplateFile "D:\AzureDeploy.json" -TemplateParameterObject $paramValues
$VMId = $result.outputs.Values.value
$VMComputeId = (Get-AzureRmResource -Id $VMId).Properties.ComputeId
$RGNameofVM = $VMComputeId.split("/")
$RGNameofVM = $RGNameofVM[4]
$IP = (Get-AzureRmNetworkInterface -Name $VMName -ResourceGroupName $RGNameofVM ).IpConfigurations.PrivateIpAddress
Well, generally a more elegant solution, oposed to bruteforce would be to use Get-AzureRmResource
$Resource = Get-AzureRmResource -ResourceId "/subscriptions/$sub_GUID/resourcegroups/$RG_devlab_Name/providers/microsoft.devtestlab/labs/$LabName/virtualmachines/$VMName"
$Resource.Properties.computeId -match 'resourceGroups/(.+)/providers'
$RGName = $Matches[1]
$IP = (Get-AzureRmNetworkInterface -Name $VMName-ResourceGroupName $RGName).IpConfigurations.PrivateIpAddress
Well, as we know for DevTest Labs there is no direct way for powershell. You can use the below powershell script to get the Private IP Address of the VM by just passing the Virtual machine name. We can use Find-AzureRmResource and Get-AzureRmResource by passing the ResourceId:
$vmNicdetails = Find-AzureRmResource -ResourceNameContains mytestVM | Where {$_.ResourceType -eq 'Microsoft.Network/networkInterfaces'}
$nicdetails = Get-AzureRmResource -ResourceId $vmNicdetails.ResourceId
$ipconfig = Get-AzureRmResource -ResourceId
$nicdetails.Properties.ipConfigurations.id -ApiVersion '2017-03-01'
$ipconfig.Properties.privateIPAddress

Where do I get the ResourceGroup for AzureResourceManager CmdLets?

The new and soon to supercede AzureRsourceManager cmdlets all require a -ResourceGroupName parameter. Where am I expected to get this? Not including the UI, since that'd mostly defeat the purpose of automating.
Currently, I'm calling Get-AzureResourceGroup and trying each one until I get a hit. This is extremely slow - on the order of minutes. For example, to get WebApp information, I'm running this,
$groups = Get-AzureResourceGroup
foreach ($g in $groups)
{
if ($ResourceGroup) { $ResourceGroup.Value = $g.ResourceGroupName }
$app = Get-AzureWebApp -Name $Name -ResourceGroupName $g.ResourceGroupName -ErrorAction SilentlyContinue
Write-Verbose "Checking $($g.ResourceGroupName)"
if ($app)
{
$ResourceGroups[$g.ResourceGroupName] = #($ResourceGroups[$g.ResourceGroupName]) + $Name
return $app
}
}
If you go to the portal and navigate to your web app you can easily see which resource group it's in. See the screenshot below. What resource group is, is an arbitrary name to group resources. For example below you can see that it is grouping two Web Apps and two App Service Plans.
You can use the Get-AzureRmResourceGroup PowerShell command from Azure PowerShell without any parameter to get all the resource groups in very fast response time.
Reference Link: Get-AzureRMResourceGroup description
Note: You need to update your Azure PowerShell to the latest version for this new feature. The current version is 1.0.1 (November 2015 Update)
As #theadriangreen noted in his comment, it's faster to directly query the REST API. I found that some of the RM cmdlets actually do this anyway.
I've written a set of PowerShell functions to make using the API easier and faster (uses caching), in this gist.

Resources