I got a code collecting and deleting expired azure automation schedules
Connect-AzAccount -SubscriptionId "guidstuff"
$schedules = Get-AzAutomationSchedule -ResourceGroupName "resgrp" -AutomationAccountName "automationacc" | ?{$_.name -like "schedule1*" -and $_.expirytime -lt (get-date)}
$cache = Get-AzAutomationSchedule -ResourceGroupName "resgrp" -AutomationAccountName "automationacc" | ?{$_.name -like "schedule2*" -and $_.expirytime -lt (get-date)}
if($cache.count -ne 0){
$schedules += $cache
}
foreach($schedule in $schedules){
Remove-AzAutomationSchedule -Confirm:$false -AutomationAccountName $schedule.AutomationAccountName -ResourceGroupName $schedule.ResourceGroupName -Name $schedule.name
}
Its asking deletion-confirmation for every schedule, am I or is the CMDlet wrong ?
Its asking deletion-confirmation for every schedule, am I or is the CMDlet wrong ?
As suggested by #theo, we reproduced in our local environment by using the below cmdlet:
By default, -Confirm value is set to false only.
Remove-AzAutomationSchedule -AutomationAccountName 'tstautmation'-ResourceGroupName 'test-rg' -Name 'terer' -Confirm:$false -Force
Now, it will not ask for deletion-confirmation every time when we run the above command.
Refer this document for more information.
Related
I am trying with nested ForEach-Object -Parallel to loop through multiple azure subscriptions parallelly and get data from all VMs in one go. I am using below code:
$SubsJob = Get-AzSubscription -WarningAction SilentlyContinue | Where-Object {$_.Name -match 'abc'} | ForEach-Object -Parallel {
$Context = Set-AzContext -Tenant $_.TenantId -SubscriptionId $_.SubscriptionId
[System.String]$ScriptBlock = {Get-Process}
$VMsJob = Get-AzVM | ForEach-Object -Parallel {
$FileName = $using:Context.Subscription.Name + "_$($_.Name)_" + (Get-Random) + ".ps1"
Out-File -FilePath $FileName -InputObject $using:ScriptBlock -NoNewline
$Output = Invoke-AzVMRunCommand -Name $_.Name -ResourceGroupName $_.ResourceGroupName -CommandId 'RunPowerShellScript' -ScriptPath $FileName
$PSCustomObject = [PSCustomObject]#{Subscription = $using:Context.Subscription.Name; ServerName = $_.Name; Output = $Output}
#Remove-Item -Path $FileName -Force -ErrorAction SilentlyContinue
Write-Output $PSCustomObject
} -ThrottleLimit 200 -AsJob
Write-Output $VMsJob
} -ThrottleLimit 200 -AsJob
I am not able to get it work, not sure what is wrong. One thing I observed while debugging is that, Get-AzVM command is getting VMs list from all the subscriptions rather than specific subscription. I came to know that by looking at the Out-File -FilePath $FileName which are generated.
sub1_server1_980337551.ps1
sub2_server1_42701325.ps1
server1 is only present in sub1 but it is being picked in sub2 as well.
I am trying to use the command like so:
a = 345
name = "myVM"
Invoke-AzVMRunCommand -ResourceGroupName $RGName -Name $VMName -CommandId 'RunPowerShellScript' -ScriptPath $FileName -Parameter #{"b" = "a"; "test" = "name"}
the script in the file isn't really important I am just trying to use params inside of it with values of params from the outside. If I put "b" = 345 it works but with the outside param (a), it doesn't so I wanted to know how to do it.
it does execute the script but ignores the commands using these params.
for reference the script is something like this:
New-Item -Path "." -Name "index.html" -ItemType "file" -Value $b
New-Item -Path "." -Name $test -ItemType "file" -Value "3333333"
We use Invoke-AzVMRunCommand to Invoke a run command on the VM. And the -Parameter is used to run the command parameter.
The the type for -Parameter is Hashtable, which maps keys to values. Any non-null object can be used as a key or as a value.
Invoke command is more like a batch script, so when we want to pass a pre-defined variable we have to use the $ symbol without any double quotes (""). So you can solve your problem by following the code snippet below.
#Example
a = 345
name = "myVM"
Invoke-AzVMRunCommand -ResourceGroupName $RGName -Name $VMName -CommandId 'RunPowerShellScript' -ScriptPath $FileName -Parameter #{"b" = $a; "test" = $name}
Read this Invoke-AzVMRunCommand document and about_Hash_Tables document for more information.
Invoke-AzVMRunCommand -ResourceGroupName $RGName -Name $VMName -CommandId 'RunPowerShellScript' -ScriptPath $FileName -Parameter #{"b" = $a; "test" = $name}
It don't work. The same problem.
I have the script which create VM in azure:
$password = ConvertTo-SecureString -String "Qwerty123456" -AsPlainText
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $user, $password
$x = Get-Random 10000 -Minimum 10
$location = "East US"
$rgname = "testVM"+$x
$VMName = "vm1"
# Create Resource group
New-AzResourceGroup -name $rgname -Location $location
# Create VM, vnet, publicIP, port 3389
New-AzVM -ResourceGroupName $rgname `
-Location $location `
-Name "verdyshtest" `
-VirtualNetworkName "virtnet" `
-SubnetName 'verdyshnetwork' `
-PublicIpAddressName "verdyshpublicIP" `
-Image Win2019Datacenter `
-OpenPorts 3389 `
-Credential $cred
# Script only running after deploy
Invoke-AzVMRunCommand -ResourceGroupName $rgname -VMName $VMName -CommandId RunPowerShellScript -ScriptPath '.\2 Install app on VM.ps1'
In last count it can't to execute 'invoke-azvmruncommand', because of variable in parameters.
But in New-AzVM cmdlet variables works well.
Had a error:
error
I have a Powershell workflow runbook that automates starting and shutting down VMs in Azure, I updated the modules in an automation account (so I could use it for other things) and it has stopped the script working. I have fixed most of the broken stuff but the bit that is not now working is obtaining the power state eg: PowerState/deallocated so that it can be shutdown/started up. Here is my code:
$vmFullStatus = Get-AzureRmVM -ResourceGroupName test1 -Name test1 -Status
$vmStatusJson = $vmFullStatus | ConvertTo-Json -depth 100
$vmStatus = $vmStatusJson | ConvertFrom-Json
$vmStatusCode = $vmStatus.Statuses[1].code
Write-Output " VM Status Code: $vmStatusCode"
The Write-Output VM Status Code is now blank in the output of the runbook, but it outputs fine in standard shell. I only have limited experiences in workflow runbooks but I believe it needs to be converted to Json so the Workflow can use it.
I think the issue may lie with the statuses as when it is converted to Json it displays:
"Statuses": [
"Microsoft.Azure.Management.Compute.Models.InstanceViewStatus",
"Microsoft.Azure.Management.Compute.Models.InstanceViewStatus"
],
Which doesn't now show the PowerState. How can I get the powerstate of a vm from within a powershell workflow runbook so it can used? Thanks
I have tried an inline script and it does work if you specify a vm name:
$vmStatusCode = InlineScript {
$vmFullStatus = Get-AzureRmVM -ResourceGroupName test1 -Name test1 -Status
$vmStatusJson = $vmFullStatus | ConvertTo-Json -depth 100
$vmStatus = $vmStatusJson | ConvertFrom-Json
$vmStatus.Statuses[1].code
}
But it doesn't work when you pass variables:
$vmFullStatus = Get-AzureRmVM -ResourceGroupName $vm.ResourceGroupName -Name $vm.Name -Status
Get-AzureRmVM : Cannot validate argument on parameter 'ResourceGroupName'. The argument is null or empty. Provide an
argument that is not null or empty, and then try the command again.
it needs to be run without an inline script - any ideas?
forgot to add $using:
$vmStatusCode = InlineScript {
$vmFullStatus = Get-AzureRmVM -ResourceGroupName $using:vm.ResourceGroupName -Name $using:vm.Name -Status
$vmStatusJson = $vmFullStatus | ConvertTo-Json -depth 100
$vmStatus = $vmStatusJson | ConvertFrom-Json
$vmStatus.Statuses[1].code
}
This now works!
I have the below script which I am using in order to delete snapshot older then 10 minutes and retain the snapshot that are not older then 10minutes, I have the below script but its not working as it suppose to, can anyone tell me whats being going wrong?
foreach($snapname in $snapshotnames)
{
Get-AzureRmSnapshot -ResourceGroupName $rg -SnapshotName $snapname |?{$_.Name -Like "*-Server1*"} | ?{($_.TimeCreated).ToString('yyyyMMdd') -lt ([datetime]::Now.AddMinutes(-10).tostring('yyyymmdd'))} | remove-azurermsnapshot -force
}
You should use [datetime]::UtcNow instead of [datetime]::Now and not use .tostring('yyyymmdd').
So your command should be:
foreach($snapname in $snapshotnames)
{
Get-AzureRmSnapshot -ResourceGroupName $rg -SnapshotName $snapname | ?{$_.Name -Like "*-Server1*"} | ?{($_.TimeCreated) -lt ([datetime]::UtcNow.AddMinutes(-10))} | remove-azurermsnapshot -force
}
My specific test command:
Get-AzureRmSnapshot -ResourceGroupName "<ResourceGroupName>" -SnapshotName "<SnapshotName>" | ?{($_.TimeCreated) -lt ([datetime]::UtcNow.AddMinutes(-10))} | remove-azurermsnapshot -force
Result screenshot:
In my Azure dev/test lab (DTL), there are many resources which were not tagged. How can I get a list of all untagged resources under DTL/resource group?
Here's a simple PowerShell loop to get untagged resources.
$resources = Get-AzureRmResource
foreach($resource in $resources)
{
if ($resource.Tags -eq $null)
{
echo $resource.Name, $resource.ResourceType
}
}
Other ways to query this information and also set tags programmatically or as part of resource deployments are described here.
If you want to avoid the situation of ending up with untagged resources, you could enforce a customized policy that all resources should have a value for a particular tag.
Here is the idiomatic PowerShell to supplement #huysmania's answer which is expressed in procedural language mindset (and updated for the new PowerShell Az cmdlets):
Get-AzResource | Where-Object Tags -eq $null | Select-Object -Property Name, ResourceType
and the terse (alias) form:
Get-AzResource | ? Tags -eq $null | select Name, ResourceType
I usually just run this command to output a table of untagged resources using Get-AzResource. It filters Azure resources with tags that are $null or empty using Where-Object.
Get-AzResource `
| Where-Object {$null -eq $_.Tags -or $_.Tags.Count -eq 0} `
| Format-Table -AutoSize
If you want to list untagged resources for a specific resource group, you can just add the -ResourceGroupName switch to Get-AzResource.
$resourceGroupName = "My Resource Group"
Get-AzResource -ResourceGroupName $resourceGroupName `
| Where-Object {$null -eq $_.Tags -or $_.Tags.Count -eq 0} `
| Format-Table -AutoSize
Note: The above uses the newer Azure PowerShell Az module, which is replacement for AzureRM.
<#Bellow is PowerShell script to locate untagged resources -
you may change the script out put as per your requirement.
Hope must be helpful. Thanks!#>
Write-Host "List all resource where Tag value is not Set"
Write-Host "********************************************"
#Fetch all resource details
$resources=get-AzureRmResource
foreach ($resource in $resources) {
$tagcount=(get-AzureRmResource | where-object {$_.Name -match $resource.Name}).Tags.count
if($tagcount -eq 0) {
Write-Host "Resource Name - "$resource.Name
Write-Host "Resource Type and RG Name : " $resource.resourcetype " & " $resource.resourcegroupname "`n"
}
}
This link has the solution for this question. It beautifully explains assigning and querying tags using powershell.
$resourceGroupName = 'InternalReportingRGDev'
$azureRGInfo = Get-AzureRmResourceGroup -Name $resourceGroupName
foreach ($item in $azureRGInfo)
{
Find-AzureRmResource -ResourceGroupNameEquals $item.ResourceGroupName | ForEach-Object {Set-AzureRmResource -ResourceId $PSItem.ResourceId -Tag $item.Tags -Force }
}