How to connect multiple Azure VMs to log analytics workspace using ARM template? - azure

I can able to connect the Azure VM to the log analytics workspace using the ARM template(https://learn.microsoft.com/en-us/azure/azure-monitor/agents/resource-manager-agent) but I want to connect the multiple VMs at a time in one subscription and different resource groups to the log analytics workspace.
Is there any way to work around this?

If you want to add a bunch of VMs in a subscription to a log analytics workspace in Azure, we can use PowerShell command Set-AzVMExtension to implement it.
For example
# all windows VMs in the subscription (which you set via Set-AzContext)
$PublicSettings = #{ "workspaceId" = "" }
$ProtectedSettings = #{ "workspaceKey" = "" }
# Using -Status switch to get the status too
Get-AzVM -Status | Where-Object{ $_.Powerstate -eq "VM running" -and $_.StorageProfile.OsDisk.OsType -eq "Windows" } | ForEach-Object {
$VMName = $_.Name
$ResourceGroupName = $_.ResourceGroupName
$Location = $_.Location
Write-Host "Processing $VMName"
Set-AzVMExtension -ExtensionName "MicrosoftMonitoringAgent" `
-ResourceGroupName "$ResourceGroupName" `
-VMName "$VMName" `
-Publisher "Microsoft.EnterpriseCloud.Monitoring" `
-ExtensionType "MicrosoftMonitoringAgent" `
-TypeHandlerVersion 1.0 `
-Settings $PublicSettings `
-ProtectedSettings $ProtectedSettings `
-Location "$Location"
}
For more details, please refer to here and here.

Related

How delete VM Azure using tags using powershell?

How do I delete a VM using tags? Let's say there is a VM with the tags "Name:Surname". How can I delete this VM without using the VM name or ID. Namely deletion using tags.
I try to use:
get-azvm -ResourceGroupName "ResourceGroup" | Where-Object {$_.Tags -like "[Name, blabla], [Surname, blabla]"}
but it didn't find that VM
I have reproduced in my environment. Firstly, you need to find the Virtual Machine using the below command:
xx- Name of the resource group
hello- tag name
get-azvm -ResourceGroupName "xx" | Where-Object {$_.Tags['hello']}
After getting the VM name you can use the below command to delete the VM:
xx- Name of the resource group
yy- Name of the vm.
Remove-AzVM -ResourceGroupName "xx" -Name "yy"
Then type Y(yes) to delete the VM as below:
References taken from:
https://learn.microsoft.com/en-us/powershell/module/az.compute/remove-azvm?view=azps-8.2.0#example-1-remove-a-virtual-machine
https://learn.microsoft.com/en-us/powershell/module/az.compute/get-azvm?view=azps-8.2.0
Based on this,
You could do something like this:
$Surname= 'Test'
$VMs = Get-AzVM -ResourceGroupName 'myRG'
foreach ($VM in $VMs)
{
[Hashtable]$VMTag = (Get-AzVM -ResourceGroupName $VM.ResourceGroupName -Name $VM.Name).Tags
foreach ($h in $VMTag.GetEnumerator()) {
if (($h.Name -eq "Name") -and ($h.value -eq $Surname))
{
Write-host "Removing VM" $VM.Name
Remove-AzVM -ResourceGroupName $VM.ResourceGroupName -Name $VM.Name -Force -Confirm:$false
}
}
}

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.

Azure Automation Runbook missing mandatory parameters

I'm trying to set a Tag on all virtual machines in my subscription but I keep getting errors when running the Runbook.
The error is the following:
Get-AzureRmVM : Cannot process command because of one or more missing mandatory parameters: ResourceGroupName. At line:30
Here is my Runbook:
$azureConnection = Get-AutomationConnection -Name 'AzureRunAsConnection'
#Authenticate
try {
Clear-Variable -Name params -Force -ErrorAction Ignore
$params = #{
ServicePrincipal = $true
Tenant = $azureConnection.TenantID
ApplicationId = $azureConnection.ApplicationID
CertificateThumbprint = $azureConnection.CertificateThumbprint
}
$null = Add-AzureRmAccount #params
}
catch {
$errorMessage = $_
Throw "Unable to authenticate with error: $errorMessage"
}
# Discovery of all Azure VM's in the current subscription.
$azurevms = Get-AzureRmVM | Select-Object -ExpandProperty Name
Write-Host "Discovering Azure VM's in the following subscription $SubscriptionID Please hold...."
Write-Host "The following VM's have been discovered in subscription $SubscriptionID"
$azurevms
foreach ($azurevm in $azurevms) {
Write-Host "Checking for tag $vmtagname on $azurevm"
$tagRGname = Get-AzureRmVM -Name $azurevm | Select-Object -ExpandProperty ResourceGroupName
$tags = (Get-AzureRmResource -ResourceGroupName $tagRGname -Name $azurevm).Tags
If ($tags.UpdateWindow){
Write-Host "$azurevm already has the tag $vmtagname."
}
else
{
Write-Host "Creating Tag $vmtagname and Value $tagvalue for $azurevm"
$tags.Add($vmtagname,$tagvalue)
Set-AzureRmResource -ResourceGroupName $tagRGname -ResourceName $azurevm -ResourceType Microsoft.Compute/virtualMachines -Tag $tags -Force `
}
}
Write-Host "All tagging is done"
I tried importing the right modules but this doesn't seem to affect the outcome.
Running the same commands in Cloud Shell does work correctly.
I can reproduce your issue, the error was caused by this part Get-AzureRmVM -Name $azurevm, when running this command, the -ResourceGroupName is needed.
You need to use the Az command Get-AzVM -Name $azurevm, it will work.
Running the same commands in Cloud Shell does work correctly.
In Cloud shell, azure essentially uses the new Az module to run your command, you can understand it runs the Enable-AzureRmAlias before the command, you could check that via debug mode.
Get-AzureRmVM -Name joyWindowsVM -debug
To solve your issue completely, I recommend you to use the new Az module, because the AzureRM module was deprecated and will not be updated.
Please follow the steps below.
1.Navigate to your automation account in the portal -> Modules, check if you have imported the modules Az.Accounts, Az.Compute, Az.Resources, if not, go to Browse Gallery -> search and import them.
2.After import successfully, change your script to the one like below, then it should work fine.
$azureConnection = Get-AutomationConnection -Name 'AzureRunAsConnection'
#Authenticate
try {
Clear-Variable -Name params -Force -ErrorAction Ignore
$params = #{
ServicePrincipal = $true
Tenant = $azureConnection.TenantID
ApplicationId = $azureConnection.ApplicationID
CertificateThumbprint = $azureConnection.CertificateThumbprint
}
$null = Connect-AzAccount #params
}
catch {
$errorMessage = $_
Throw "Unable to authenticate with error: $errorMessage"
}
# Discovery of all Azure VM's in the current subscription.
$azurevms = Get-AzVM | Select-Object -ExpandProperty Name
Write-Host "Discovering Azure VM's in the following subscription $SubscriptionID Please hold...."
Write-Host "The following VM's have been discovered in subscription $SubscriptionID"
$azurevms
foreach ($azurevm in $azurevms) {
Write-Host "Checking for tag $vmtagname on $azurevm"
$tagRGname = Get-AzVM -Name $azurevm | Select-Object -ExpandProperty ResourceGroupName
$tags = (Get-AzResource -ResourceGroupName $tagRGname -Name $azurevm).Tags
If ($tags.UpdateWindow){
Write-Host "$azurevm already has the tag $vmtagname."
}
else
{
Write-Host "Creating Tag $vmtagname and Value $tagvalue for $azurevm"
$tags.Add($vmtagname,$tagvalue)
Set-AzResource -ResourceGroupName $tagRGname -ResourceName $azurevm -ResourceType Microsoft.Compute/virtualMachines -Tag $tags -Force `
}
}
Write-Host "All tagging is done"

Azure webhook get VM status

I'm trying to do a runbook/webhook that return a status of machine. What I finally notices is that
Get-AzureRmVM
is only returning 2 resource groups. Where
Get-AzureRmResource
Does return many more but not all of them again!
I'm sure about my Resource Group Name but still it says resource group 'groupName' could not be found. when I try to run with specific name
Get-AzureRmVM -ResourceGroupName groupName
While my other start and stop runbook works just fine, so i'm confused I can't see the difference between the groups.
PS: I'm using Azure Run As Connection
param
(
[Parameter (Mandatory = $false)]
[object] $WebhookData
)
if ($WebhookData) {
$vms = (ConvertFrom-Json -InputObject $WebhookData.RequestBody)
Write-Output "Authenticating to Azure with service principal and certificate"
$ConnectionAssetName = "AzureRunAsConnection"
Write-Output "Get connection asset: $ConnectionAssetName"
$Conn = Get-AutomationConnection -Name $ConnectionAssetName
if ($Conn -eq $null)
{
throw "Could not retrieve connection asset: $ConnectionAssetName. Check that this asset exists in the Automation account."
}
Write-Output "Authenticating to Azure with service principal."
Add-AzureRmAccount -ServicePrincipal -Tenant $Conn.TenantID -ApplicationId $Conn.ApplicationID -CertificateThumbprint $Conn.CertificateThumbprint | Write-Output
# Start each virtual machine
foreach ($vm in $vms)
{
$vmName = $vm.Name
Write-Output "Checking $vmName"
$vmstatus = Get-AzureRmVM -Name $vm.Name -ResourceGroupName $vm.ResourceGroup -Status# | Select-Object -ExpandProperty StatusesText | ConvertFrom-Json
#select code index and convert to $vmpowerstate
$vmPowerState = $vmstatus#[1].Code
#Write-Output "Resource Group: $vmResourceGroupName", ("VM Name: " + $VM.Name), "Status: $VMStatusDetail" `n
Write-Output ("VM Name: " + $vmName), "Status: $vmPowerState" `n
}
}
else {
write-Error "This is webhook only."
}
Because your resource groups are in the different subscriptions.
As #et3rnal mentioned,
I have 2 subscriptions and Get-AzureRmVM returning 2 vms only because the rest are classics. The automation account I created this runbook at is the other one and I can see that in the overview? its the same one I use to start/stop machines in the other subscription!
Update:
If you want to get the PowerState of the VM, you could try the command below, in your case, just put it in the loop, the $PowerState is the PowerState.
$status = Get-AzureRmVM -Name <VM Name> -ResourceGroupName <Resource Group Name> -Status
$PowerState = ($status.Statuses | Where-Object {$_.Code -like "PowerState/*"}).DisplayStatus
Update2:
1.For the classic VM, we need to use azure ASM powershell module command, you could try Get-AzureVM, may be the Example 3: Display a table of virtual machine statuses in that link will help.
2.Another option is to migrate the classic VM(ASM) to ARM, then use the ARM command Get-AzureRmVM.
References:
Platform-supported migration of IaaS resources from classic to Azure Resource Manager
Migrate IaaS resources from classic to Azure Resource Manager by using Azure PowerShell

Change Azure website web hosting plan mode using Powershell

I've been reading the following article that describes how to change the web hosting plan for your site.
http://azure.microsoft.com/en-us/documentation/articles/azure-web-sites-web-hosting-plans-in-depth-overview/
That seems to work fine but if I use the same command to change the web hosting mode (using property: "sku": "Free" to "sku": "Standard") it doesn't give any error feedback and just returns with the unchanged (previous) stored configuration.
Command executed:
$standardServer=#{"sku" = "Standard"; }
Set-AzureResource -Name 'tmtest2' -ResourceGroupName 'Default-Web-JapanWest' -ResourceType Microsoft.Web/sites -ApiVersion 2014-04-01 -PropertyObject $standardServer
Anyone had any luck changing the web hosting mode using Powershell?
Edit:
I also tried this link that exactly describes what I'm trying to achieve. However it did not work.
http://msdn.microsoft.com/en-us/library/dn654578.aspx
I figured this out. You need to create a hosting plan (with 'Standard' mode) first as a resource under a default resource group. Then you need to assign the website to the hostingplan.
Here's the full script:
Switch-AzureMode AzureResourceManager
Add-AzureAccount
$locations = #('East Asia', 'Southeast Asia', 'East US', 'East US 2', 'West US', 'North Central US', 'South Central US', 'Central US', 'North Europe', 'West Europe', 'Japan East', 'Japan West', 'Brazil South')
$websiteName = Read-Host 'What is the name of your website (without azurewebsites.net)' #tmtest2
$location = Read-Host 'What is the region location of the website'
if (-Not($locations -contains $location)) {
throw "location is incorrect, try one of these values: " + (($locations | select -expand $_) -join ", ")
}
$resourceGroupName = 'Default-Web-' + $location.Replace(' ', '');
#create a new web hosting plan - Small Standard machine
$hostingPlanName = $websiteName + 'HostingPlan';
$p=#{"name"= $hostingPlanName;"sku"= "Standard";"workerSize"= "0";"numberOfWorkers"= 1}
New-AzureResource -ApiVersion 2014-04-01 -Name $hostingPlanName -ResourceGroupName $resourceGroupName -ResourceType Microsoft.Web/serverFarms -Location $location -PropertyObject $p -Verbose -Force
$r = Get-AzureResource -Name $websiteName -ResourceGroupName $resourceGroupName -ResourceType Microsoft.Web/sites -ApiVersion 2014-04-01
echo $r
$p = $null;
$p = #{ 'serverFarm' = $hostingPlanName }
$r = Set-AzureResource -Name $websiteName -ResourceGroupName $resourceGroupName -ResourceType Microsoft.Web/sites -ApiVersion 2014-04-01 -PropertyObject $p
#echo $r.Properties
if (-Not($r.Properties['sku'] -eq 'Standard')) {
throw 'script executed but sku has not been changed'
}
Start your Azure Resource Manager.
Add-AzureAccount
Switch-AzureMode AzureResourceManager
Get your Azure PowerShell API Version (This link shows how)
$DebugPreference='Continue'
Get-AzureResourceGroup
$DebugPreference='SilentlyContinue'
Get the Name, ResourceGroupName, and ResourceType of your Website Resources
Get-AzureResource | `
Where-Object { $_.ResourceType -like '*site*' } | `
Format-Table Name, ResourceGroupName, ResourceType
Change the Azure Website Hosting Plan for your target Website
Set-AzureResource
-Name the-website-name
-ResourceGroupName 'the-resource-group-name'
-ResourceType 'Microsoft.Web/sites'
-ApiVersion '2014-04-01-preview'
-PropertyObject #{ 'ServerFarm' = 'the-target-server-farm-name' }
Notes:
You can also run Get-AzureResource in a similar way.
To change the hosting plan with Set-AzureResource, you only need the ServerFarm property.

Resources