Azure: Get resource for azure automation - azure

I have runbook in Azure that i want to use in different RG,
My code
$vms = Get-AzVM -ResourceGroupName RG-TEST
foreach($vm in $vms)
{
$statuscheck = Get-AzVM -ResourceGroupName RG-TEST -Name $vm.Name -Status
if($statuscheck.Statuses.DisplayStatus[1] -eq "VM running")
{
Write-Output "Stopping virtual machine...$($vm.Name)"
Stop-AzVM -ResourceGroupName $vm.ResourceGroupName -Name $vm.Name -Force
}
else
{
Write-output "Virtual machine $($vm.Name) is already in stopped state"
}
}
How can I update the code that the script will get the name of the RG where it's located,
So that the RG is not hard coded
Dont know how to do it

Do something like this
$rgs = $(Get-AzVM)
# Get Distinct RG Names
$rgs = $rgs | Select-Object -Property ResourceGroupName | Sort-Object -Unique
foreach($rg in $rgs){
$vms = Get-AzVM -ResourceGroupName $rg.ResourceGroupName
foreach($vm in $vms)
{
$statuscheck = Get-AzVM -ResourceGroupName $rg.ResourceGroupName -Name $vm.Name -Status
if($statuscheck.Statuses.DisplayStatus[1] -eq "VM running")
{
Write-Output "Stopping virtual machine...$($vm.Name)"
Stop-AzVM -ResourceGroupName $rg.ResourceGroupName -Name $vm.Name -Force
}
else
{
Write-output "Virtual machine $($vm.Name) is already in stopped state"
}
}
}

Related

Powershell script to get list of Running VM's and stop them

Am using this script, but its gathering all the vms and stopping it one by one even when the VM is already in stopped state
$vm = Get-Azvm
foreach($vms in $vm)
{
$resource = Get-Azvm | where {$_.Statuses -eq "Running"}
if($resource -ne $null)
{
Write-Output "Stopping virtual machine..." + $vms
Stop-AzVM -ResourceGroupName $resource.ResourceGroupName -Name $vms -Force
}
else
{
Write-output "Virtual machine not found:" + $vms
}
}
Based on the above shared requirement , we have modified the PowerShell script to check the virtual machines status ( whether it is running or not ), if virtual Machine is running you need to stop it using stop-Azvm cmdlet.
Checked the below script(while testing we passed resource group flag to the Get-Azvm ) in our local environment which is working fine.
$vm = Get-Azvm -Status
foreach($vms in $vm)
{
$statuscheck = Get-AzVM -ResourceGroupName $vms.ResourceGroupName -Name $vms.Name -Status
if($statuscheck.Statuses.DisplayStatus[1] -eq "VM running")
{
Write-Output "Stopping virtual machine...$($vms.Name)"
Stop-AzVM -ResourceGroupName $vms.ResourceGroupName -Name $vms.Name -Force
}
else
{
Write-output "Virtual machine $($vms.Name) is already in stopped state"
}
}
Here is the sample output for reference:

Lock azure resource with PowerShell

I've been trying to run a script to create a lock on azure resource to prevent resources being deleted inadvertently.
I get an error message and I can't figure out why it's showing me this error message.
Script:
#Sign in to Azure account
Login-AzAccount
#Select the subscription you want to work on
Select-AzSubscription -Subscription "test.subscription"
#Get All Resources in a resource group
$Resources = Get-AzResource -ResourceGroupName dummy_rg | Format-Table
# Create lock "delete" on each Resource if it doesn't exist
foreach($Resource in $Resources) {
$ResourceName = $Resource.Name
$lck = Get-AzResourceLock -ResourceGroupName $Resource.ResourceGroupName -ResourceName $ResourceName -ResourceType $Resource.ResourceType
if ($null -eq $lck)
{
Write-Host "$ResourceName has no lock"
New-AzResourceLock -resourceGroupName $rg -ResourceName $ResourceName -ResourceType $Resource.ResourceType -LockName "$ResourceName-lck" -LockLevel CanNotDelete -Force
Write-Host "$ResourceName has been locked"
}
else
{
Write-host "$ResourceName already locked"
}
}
Error message:
Gaurav request result:
#Start logging
Start-Transcript -Path "C:\Windows\Logs\Lock - $(((get-date).ToUniversalTime()).ToString("yyyy-MM-dd_hh-mm-ss")).log" -Force
#Connect to Azure account
Login-AzAccount
#Select Azure subscription
Set-AzContext -Subscription "subscription_id_numbers"
#Deny rule on Azure Data Factory and Azure Machine Learning
$Resources = Get-AzResource | Where-Object {$_.Name -NotLike '*adf*' -and $_.Name -NotLike '*aml*'}
# Create lock "delete" on each Resource if it doesn't exist
foreach($Resource in $Resources) {
$ResourceName = $Resource.Name
$lck = Get-AzResourceLock -ResourceGroupName $Resource.ResourceGroupName -ResourceName $ResourceName -ResourceType $Resource.ResourceType
if ($lck -eq $null)
{
Write-Host "$ResourceName has no lock"
Set-AzResourceLock -ResourceGroupName $Resource.ResourceGroupName -ResourceName $ResourceName -ResourceType $Resource.ResourceType -LockName "$ResourceName-lck" -LockLevel CanNotDelete -Force
Write-Host "$ResourceName has been locked"
}
else
{
Write-host "$ResourceName already locked"
}
}
#Stop Logging
Stop-Transcript
This will loop on every ressources except azure data factory in the tenant and create a "delete" type lock to make sure resources aren't deleted inadvertently.
Read comments in each section to understand the code.

How to get specifi list of Virtual Machine Status from Azure using powershell from Excel sheet

I am pretty much new to PowerShell and we have customer requirement that they will share Azure VM details in Excel sheet with below columns.
we have to get VM Status details from all the subscriptions & ResourceGroup using the Powershell script.
Outuput:
I am able to perform for single RSG and VM values by using the below code
$SubscriptionName = Get-AzSubscription -SubscriptionId $subscriptionId
$RG = "rgp-use2-prd-bioportalbiopeople1"
$RSGName = Get-AzResourceGroup -Name $RG
$VMs = Get-AzVM -Name "vmbppapiv1prd02"
$VMState = (Get-AzVM -Name $VM -ResourceGroupName $RG -Status).Statuses
$vmOutput = $VMs | ForEach-Object {
[PSCustomObject]#{
"Resource Group Name" = $RSGName.ResourceGroupName
"Subscription Name" = $SubscriptionName.Name
"VM Name" = $_.Name
"VM Type" = $_.StorageProfile.osDisk.osType
"VM Statss" = ($VMState | where code -Like 'PowerState/*')[0].DisplayStatus
}
}
$vmOutput | Format-Table -AutoSize
$vmOutput | export-csv C:\Projects\data.csv
I can't test this myself, but you will have to create nested loops to get the details for all subscriptions and resourcegroups.
Something like this:
$subscriptions = Get-AzSubscription -TenantId "aaaa-aaaa-aaaa-aaaa" # enter the tenant ID here
$VMs = Get-AzVM -Name "vmbppapiv1prd02"
$vmOutput = foreach ($vm in $VMs) {
foreach ($subscription in $subscriptions) {
Set-AzContext -SubscriptionId $subscription.Id
(Get-AzResourceGroup).ResourceGroupName | ForEach-Object {
$vmState = (Get-AzVM -Name $vm.Name -ResourceGroupName $_ -Status).Statuses
[PSCustomObject]#{
"Resource Group Name" = $_
"Subscription Name" = $Subscription.Name
"VM Name" = $vm.Name
"VM Type" = $vm.StorageProfile.osDisk.osType
"VM Status" = ($vmState | where code -Like 'PowerState/*')[0].DisplayStatus
}
}
}
}
$vmOutput | Format-Table -AutoSize
$vmOutput | Export-Csv -Path 'C:\Projects\data.csv' -NoTypeInformation

Problem with PSCustomObject data collection

I'm preparing a table with information about VM name and provision date of OS disk. I can easily retrieve that information from $VM.disks.statuses.time[0] command, if individual VM is assigned to $VM, but I when i try to collect data into table, I got an error:
Cannot index into a null array.
At line:4 char:1
+ [PSCustomObject]#{
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
This is my code:
$VMs = Get-AzVM -status
$vmOutput = $VMs | ForEach-Object {
[PSCustomObject]#{
"VM Name" = $_.Name
"Provision Date" = $_.disks.statuses.time[0].ToString()
}
}
I can reproduce your issue, the issue was caused by the outputs of Get-AzVM -status and Get-AzVM -ResourceGroupName <ResourceGroupName> -Name <Name> -Status are different.
The output of Get-AzVM -status will not has the disks property, but when you get individual VM status via Get-AzVM -ResourceGroupName <ResourceGroupName> -Name <Name> -Status, it will have the property, so you got the error.
Get-AzVM -status:
Get-AzVM -ResourceGroupName <ResourceGroupName> -Name <Name> -Status:
Solution:
To fix the issue, just to use Get-AzVM -ResourceGroupName <ResourceGroupName> -Name <Name> -Status in your script.
$VMs = Get-AzVM -status
$vmOutput = $VMs | ForEach-Object {
$VMstatus = Get-AzVM -ResourceGroupName $_.ResourceGroupName -Name $_.Name -Status
[PSCustomObject]#{
"VM Name" = $VMstatus.Name
"Provision Date" = $VMstatus.disks.statuses.time[0].ToString()
}
}
You can use the Get-AzDisk command to retrieve disk creation information.
$disks = Get-AzDisk | Where-Object { $_.Managedby }
$vmOutput = foreach ($disk in $disks) {
[pscustomobject]#{"VM Name" = ($disk.ManagedBy -split "/")[-1]
"Provisioned Date" = $disk.TimeCreated
}
}
The error says:
Cannot index into a null array.
So my guess is that something here $_.disks.statuses.time[0].ToString() is $null. Therefore you should add some $nullchecks:
$VMs = Get-AzVM -status
$vmOutput = $VMs | ForEach-Object {
if ($_.disks -and $_.disks.statuses -and $_.disks.statuses.time -and ($_.disks.statuses.time.Count -gt 0)){
[PSCustomObject]#{
"VM Name" = $_.Name
"Provision Date" = $_.disks.statuses.time[0].ToString()
}
}
}
Hope that helps.

How to use PowerShell parameter in Jenkins

I am using PowerShell to automate VM start/stop in Azure. However, when I set the $OPTION parameter it doesn't do anything. I have if/elseif/else statements.
See code below:
Add-AzureRmAccount -Credential $psCred -TenantId <removed> -ServicePrincipal
Get-AzureRmSubscription -SubscriptionName "<removed>"
#Get VMs using Tags
$vms = (Find-AzureRmResource | Where-Object {($_.tags.Project -eq "DevOps") -And ($_.tags.Test -eq "ernest")} | Select Name, ResourceGroupName)
$vms
Write-Output "Number of Virtual Machines: $($vms.Name.Count)"
foreach($VM in $vms)
{
if ($OPTION -eq "start" -And $VM.ResourceType -eq "Microsoft.Compute/virtualMachines")
{
Write-Output "Starting :- $VM.Name in $VM.ResourceGroupName"
Start-AzureRmVM -ResourceGroupName $VM.ResourceGroupName -Name $VM.Name -Verbose
Write-Output $VM.Name "has started successfully"
Write-Output "Writing output to workspace"
Get-AzureRmVM -Status | Where-Object {($_.tags.Project -eq "DevOps") -And ($_.tags.Test -eq "ernest")} | Select Name, ResourceGroupName, PowerState > VM_Start_Info-$(get-date -f yyyy-MM-dd).tsv
}
elseif ($OPTION -eq "stop" -And $VM.ResourceType -eq "Microsoft.Compute/virtualMachines")
{
Write-Output "Deallocating :- $VM.Name in $VM.ResourceGroupName"
Stop-AzureRmVM -ResourceGroupName $VM.ResourceGroupName -Name $VM.Name -Force -Verbose
Write-Output $VM.Name "has been deallocated successfully"
Write-Output "Writing output to workspace"
Get-AzureRmVM -Status | Where-Object {($_.tags.Project -eq "DevOps") -And ($_.tags.Test -eq "ernest")} | Select Name, ResourceGroupName, PowerState > VM_Stopped_Info-$(get-date -f yyyy-MM-dd).tsv
}
else
{
Write-Output "No option selected, select an option"
}
}
Write-Output "Script complete"
I had to add the $env:OPTION parameter to the Execute Powershell window. It works now

Resources