Install extension on both Classic and ARM VMs with single PowerShell command - azure

I have a script that installs OMS extensions to all ARM VMs in the subscription. The problem is that I have subscriptions that contain only ARM VMs, subscriptions that contain only Classic VMs, and subscription that have both types of VMs. How can I modify the script to work in all of the conditions? The script is:
#This script installs OMS Monitoring Agent to all VMs in the selected Subscription.
#Before running this script, the user must login to Azure account and select target subscription.
#Example:
#Login-AzureRmAccount
#Select-AzureRmSubscription 'SubscriptionName'
$WorkspaceID = 'Provide Workspace ID here'
$WorkspaceKey = 'Provide Workspace key here'
$VMs = Get-AzureRmVM
$VMs.where({$_.osprofile.windowsconfiguration}) | ForEach-Object {
"Installing Microsoft.EnterpriseCloud.Monitoring.MicrosoftMonitoringAgent Extension: {0}" -f $_.id
Set-AzureRmVMExtension -ResourceGroupName $_.ResourceGroupName -VMName $_.Name -Name omsAgent -Publisher 'Microsoft.EnterpriseCloud.Monitoring' `
-ExtensionType 'MicrosoftMonitoringAgent' -AsJob -TypeHandlerVersion '1.0' -Location $_.Location -ForceRerun 'yesh' `
-SettingString ( "{'workspaceId': '$WorkspaceID'}") `
-ProtectedSettingString "{'workspaceKey': '$WorkspaceKey'}" |
Add-Member -Name VM -Value $_.Id -MemberType NoteProperty
}

Since you got both classic and ARM VMs, you got two different deployment models, hence two different PowerShell modules you are using.
In other words, you need to log in separately for each and have separate scripts for using them.
In the classic model you need to run the following cmdlet to login and access your VMs:
Add-AzureAccount
Get-AzureVM | Set-AzureVMExtension ``
-Publisher 'Microsoft.EnterpriseCloud.Monitoring' ``
-ExtensionName 'MicrosoftMonitoringAgent' ``
-Version '1.*' ``
-PublicConfiguration "<workspace id>" ``
-PrivateConfiguration "<workspace key>" ``
While searching for information I found this script. It's a script for on-boarding VMs from single, or multiple subscriptions, using both deployment models.

Related

New automation variable by cli or ansible

After create a runbook and edit content, I want to create variable and set value for them. How can I do it by ansible or azure cli ?
Please help me
Azure Automation stores each encrypted variable securely. When you create a variable, you can specify its encryption and storage by Azure Automation as a secure asset.
You must set the value with the Set-AzAutomationVariable cmdlet or the internal Set-AutomationVariable cmdlet. You use the Set-AutomationVariable in your runbooks that are intended to run in the Azure sandbox environment, or on a Windows Hybrid Runbook Worker.
You can create variables and set value for them using PowerShell script.
$rgName = "ResourceGroup01"
$accountName = "MyAutomationAccount"
$vm = Get-AzVM -ResourceGroupName "ResourceGroup01" -Name "VM01" | Select Name, Location,Extensions
New-AzAutomationVariable -ResourceGroupName "ResourceGroup01" -AutomationAccountName "MyAutomationAccount" -Name "MyComplexVariable" -Encrypted $false -Value $vm
$vmValue = Get-AzAutomationVariable -ResourceGroupName "ResourceGroup01" -AutomationAccountName "MyAutomationAccount" -Name "MyComplexVariable"
$vmName = $vmValue.Value.Name
$vmTags = $vmValue.Value.Tags
Reference: Manage variables in Azure Automation | Microsoft Docs

Azure - Log Analytics query with powershell variable

I have prepared simple powershell script for creating Log Analytics computer group. Based on that group I want to add VMs to the Update Management solution in Azure. Command presented below. For now I can add few VMs using this structure 'Heartbeat | where (Computer == "vmA" or Computer == "vmB")'. This approach is good for few VMs, question is what can I do with a list of 50 or more VMs? Is there any way to pass variable/param to this -Query?
New-AzOperationalInsightsComputerGroup `
-ResourceGroupName "testRG" `
-WorkspaceName "Testloganalytics" `
-SavedSearchId "testID01" `
-DisplayName "GroupName" `
-Category "Updates" `
-Query 'Heartbeat | where (Computer == "vmA" or Computer == "vmB")' `
-Version 1 `
-Force
You can specify a variable which contains all the vms like this:
$myvms = '("vm1","vm2","vm3","vm4","vm5")'
then, for the -Query, you can use the in operator, the command like below:
-Query "Heartbeat | where Computer in $myvms"

How to create Azure Automation runbook that will start VM and then execute (local or Azure) script on the VM?

I wan't to create a Runbook that will start a specific (or parameter controlled) VM, and then run a script (locally or from blob storage) on the VM.
I have checked a lot of documentation, but so far without luck in getting it to work.
What I got so far under the same Resource Group:
VM created
Automation account created incl. Run As account
Azure Automation solution (OMS)
Credential (to my own account) under the automation account
Used several Runbook galleries and other code examples using functions as e.g.
Start-AzureVM ...
Invoke-Command ...
Anyone of you good people out there who can sample a guideline on what is needed depending on methods being used?
The VM start part is working, but I cannot get the login + executing of script to work!
I'm not a high skilled developer, and I have even doubts about choosing between the script languages in Azure.
Any help will be highly appreciated.
Thanks,
Tom
Invoke-Command
Invoke-AzureRmVMRunCommand
Set-AzureRmVMCustomScriptExtension
New-SSHSession + Invoke-SSHCommand
Code taken from e.g. gallary "Connect-AzureVM"
the parameter -ScriptPath of Invoke-AzureRmVMRunCommand should not point to the path in the remote computer, but should point to the local path of runbook environment.
Sample code like below(create a file named atestfile.txt in the remote vm):
$ServicePrincipalConnection = Get-AutomationConnection -Name 'AzureRunAsConnection'
Add-AzureRmAccount `
-ServicePrincipal `
-TenantId $ServicePrincipalConnection.TenantId `
-ApplicationId $ServicePrincipalConnection.ApplicationId `
-CertificateThumbprint $ServicePrincipalConnection.CertificateThumbprint
#define resource group and vm name
$resourceGroup ="xxx"
$VmName ="xxx"
#define the scripts in $scriptblock, and add the content of $scriptblock to aa.ps1 in current directory of runbook
write-output "create test file"
$scriptblock = "New-Item -path c:\test -name atestfile.txt -itemtype file -force"
Out-File -FilePath aa.ps1 -InputObject $scriptblock
#Note that the -ScriptPath should not point to the remote path(in remote vm), it should point to the local path where you execute the command Invoke-AzureRmVMRunCommand
Invoke-AzureRmVMRunCommand -ResourceGroupName $resourceGroup -Name $VmName -CommandId 'RunPowerShellScript' -ScriptPath aa.ps1
#after execution, you can remove the file
Remove-Item -Path aa.ps1
write-output "done now"
Test result:

checking the stopped VM's with different resources by Powershell script

How to check stopped virtual Machines with different resources by azure powershell script
iam tried to do that script please help me
To get status of the vm’s you can try the below script:
#login
Connect-AzureRmAccount
Select-AzureRmSubscription –SubscriptionName 'subscription-name'
Get-AzureRmVM -Status | Format-Table
If you want ResourceGroup group wise you try this script:
Connect-AzureRmAccount
Select-AzureRmSubscription –SubscriptionName 'subscription-name'
$RG = "ResourceGroupName"
$VM = "vmname"
$VMStats = (Get-AzureRmVM -Name $VM -ResourceGroupName $RG -Status).Statuses
($VMStats | Where Code -Like 'PowerState/*')[0].DisplayStatus

How to get subscription id from the VM in AZURE

Is there a way to get the subscription id from the running (LINUX)VM instance in AZURE?
Can WALinuxAgent read the subscription ID from the internal server ?
This can be achieved using the Azure Instance Metadata Service. Calling this service from your VM will return a JSON with SubscriptionId among other useful data. Sample Microsoft bash script for calling the metadata service (with updated version in the request):
sudo apt-get install curl
sudo apt-get install jq
curl -H Metadata:True "http://169.254.169.254/metadata/instance?api-version=2017-08-01&format=json" | jq .
See "Response" section in provided link for sample response, with subscriptionId.
You can use powershell to achieve this.
First of all.
What kind of VM deployment model?
ARM
In this case it very simple.
$vm = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $vmName
$vm.Id
You'll see - "/subscriptions/{subscriptionId}/..."
Classic
If you know resource group VM was deployed to, use following:
$resource = Get-AzureRmResource -ResourceGroupName $resourceGroupName -ResourceType Microsoft.ClassicCompute/virtualMachines -Name $vmName
$resource.ResourceId
Same - you"ll see "/subscriptions/{subscriptionId}/..."
Way to find resourceGroupName, if unknown (in case you write some automative script):
$vm = Get-AzureVM | Where {$_.Name -eq $vmName}
$service = Get-AzureService -ServiceName $vm.ServiceName
$service.ExtendedProperties.ResourceGroup
Hope it helps

Resources