I need a powershell script to get a list of all unlocked resource groups.
If you run Get-AzureRmResourceLock it will show the resources that are currently locked not the ones that are unlocked
One way you can go about doing this is as follows:
Get all Resource Groups in your Subscription
$AllRGs = $(Get-AzResourceGroup | Select-Object ResourceGroupName).ResourceGroupName
Get the Resource Groups that have locks
$lockedRGs = $(Get-AzResourceLock | Where-Object {$_.ResourceType -eq "Microsoft.Authorization/locks"} | Select-Object ResourceGroupName).ResourceGroupName
Take a diff of the two
$noLockRGs = $AllRGs | Where-Object {$lockedRGs -notcontains $_}
Related
i have a lots of azure ad group with this format "AA - BB - xxx" where xxx can be anything.
i am trying to do a report on how many members in this azure ad group by display the azure ad group name and the number of its members.
i know to do 1 group is using this:
(Get-AzureADGroupMember -all 1 -ObjectId "xxxxx").count
how do i do lots of group with same group naming format to display its name and number of members?
thanks.
You need to first get all groups with such a name and then loop over the resulting list like:
$result = Get-AzureADGroup -Filter "startswith(DisplayName, 'AA - BB -')" -All $true | ForEach-Object {
[PsCustomObject]#{
Group = $_.DisplayName
MemberCount = #(Get-AzureADGroupMember -ObjectId $_.ObjectId -All $true).Count
}
}
# output on screen
$result | Format-Table -AutoSize
# save as Csv file
$result | Export-Csv -Path 'X:\PathTo\GroupMemberCount.csv' -NoTypeInformation
Apparently, the startswith() Filter on Get-AzureADGroup does not always return the wanted results (depending on the version of the OData language??).
In that case do
$result = Get-AzureADGroup | Where-Object {$_.DisplayName -like 'AA - BB -*'} | ForEach-Object {...}
I have the lovely job of getting a list of Distribution Groups and their owners from Exchange Online. So far this is working great, but I need to fine tune my output to exclude groups that don't have any owners; and groups that have multiple owners (by returning only the first).
So far this has been fairly difficult as this is sort of my first foray into PShell.
Here's my code:
$job = Get-DistributionGroup | select Name,PrimarySmtpAddress, #{n= "ManagedBy"; e={$_.ManagedBy | Select-Object -First 1 | Where-Object {$_.ManagedBy.Count -eq 0} |foreach {(Get-Mailbox $_).PrimarySMTPAddress}}}
Write-Output $job | ConvertTo-Json
Here's an example of my output:
I basically only want a single string address to be returned. So a single owner of a distro group, no nulls, and only the first address in the collections. (Right now they are blank, I'm probably nuking them with my code- but usually they return 4 or so email addresses but I just want the first person)
Thanks!
By collection you mean the ManagedBy property right? If so, try with { ($_.ManagedBy | Select-Object -First 1 | Get-Mailbox).PrimarySMTPAddress } –
Santiago Squarzon
1 hour ago
We have a large number of Azure Subscriptions which currently run into the hundreds.
I'm looking to generate a report (ideally using Azure Powershell or Azure CLI) to recursively extract a list of all tags assigned to every single resource within every resource group, for between 40-50 of the subscriptions.
Currently, I can list all tags assigned at Resource Group level, but I simply can't find a way to list the tags assigned to the individual resources within each Resource Group. The list of subscriptions and resource groups on which I'd like to extract this report, are saved in a CSV file which includes two columns displaying the Subscription name and Resource Group respectively.
Any tips on how to achieve the above would be fantastic and most appreciated.
Not detailed code but the idea here.
1.You should write a loop, in the loop, change the subscription each time by using this cmdlet:
Set-AzContext -Subscription $subscription_name.
2.Then get all the resource group in the specified subscription by using this cmdlet:
$resource_groups = Get-AzResourceGroup
3.Then write a nested loop(loop for each resource group), in this nested loop, use this cmdlet to get all azure resources within a resource group:
foreach($rg in $resource_groups){
$azure_resources = Get-AzResource -ResourceGroupName $rg.ResourceGroupName
}
4.Write another nested loop in step 3, this loop is used to go though all the azure resources within the specified resource group. Then use the code below to fetch tags for each azure resource within the resource group:
foreach($r in $azure_resources){
#the following code can get all the tags for one resource
$r.tags
}
Based on Ivan Yang's logic. I have built the PowerShell Script;
#---------DECLARE VARIABLES------------------------------------#
$bnsSubscription = Get-AzSubscription
$day = Get-Date -Format " ddMMMyyyy"
$tagPath = "C:\mytempfolder\"+"$day-Tag-Details.csv"
$tagFolderPath = "C:\mytempfolder\"
#---------DECLARE VARIABLES------------------------------------#
function Get-ResourceTag {
foreach ($subs in $bnsSubscription) {
Select-AzSubscription -SubscriptionName $subs.Name | Out-Null
Write-Host 'The selected Subscription is' ($subs).Name
New-Item -ItemType file -Path "$tagFolderPath\$($subs.Name).csv" -Force
$resource_groups = Get-AzResourceGroup
$resource_groups_details = Get-AzResourceGroup | Sort-Location ResourceGroupName | Format-Table -GroupBy Location ResourceGroupName,ProvisioningState,Tags
Write-Host 'The selected Resource Group is' ($resource_groups).Name 'and the tag information as follows'
#$resource_groups_details
$resource_groups | Select-Object ResourceGroupName,Tags | Export-CSV -Path "$tagFolderPath\$($subs.Name).csv" -Append
$OutputFile = #()
foreach($rg in $resource_groups){
$azure_resources = Get-AzResource -ResourceGroupName $rg.ResourceGroupName
$TestTags = $Resource.Tags.GetEnumerator()
foreach($r in $azure_resources){
Write-Host 'The selected resource is' ($r).Name 'and the information as follows'
$RGHT = New-Object "System.Collections.Generic.List[System.Object]"
$RGHT.Add("RGName",$r.ResourceGroupName)
$RGHT.Add("ResourceName",$r.name)
$RGHT.Add("Location",$r.Location)
$RGHT.Add("Id",$r.ResourceId)
$RGHT.Add("ResourceType",$r.ResourceType)
$RGHT.Add("ResourceTags",$r.Tags)
$OutputFile += New-Object psobject -Property $RGHT
$OutputFile | Export-Csv -Path "C:\mytempfolder\test22.csv" -append -NoClobber -NoTypeInformation -Encoding UTF8 -Force
}
}
}
}
#---------CALL FUNCTION------------------------------------#
Get-ResourceTag
Trying to run a script that will connect to each subscription, and pull the
$azureSubs = Get-AzureRMSubscription
$azureSubs | ForEach-Object {Select-AzureRMSubscription $_ | Out-Null; Get-AzureRMVM | select resourcegroupname, name, licensetype -WarningAction SilentlyContinue}
This works, BUT I'd like to add two more pieces of information: the "OSType" and "VMSize"
If I do a GET-AZURERMVM, in the table for that subscription that the command is run in, the two pieces of information I need are there: VmSize and OsType
However, when I try to add them to the query, the columns are blank.
I believe the VmSize is in the HardwareProfile, and OsType is in the OsProfile, as if I run a "Get-AzureRMVM -name (name) -resourcegroupname (RGname)", then it shows "Hardware Profile: VMSize" and "OSProfile: ComputerName, AdminUsername windowsConfiguration, Secrets"
Ultimate goal is to get the script that will, for each subscription, print results like:
ResourceGroupName | Name | License Type | VMSize | OS Type
TEST_RG | Test_VM | Windows_Server | DS3_v2 | Windows
Test_RG | Test_VM2 | | DS3_v2 | Linux
etc.
Thankful for any help; sorry for such a noob question. Have spent so much time trying to figure this out...
Something like the following would work.
What you were missing mainly was calculated properties.
This is what allow you to perform a select of custom property.
Some notes:
In your code, you used -WarningAction SilentlyContinue on the Select statement. You need to put it on the Get-AzureRMVM CmdLet instead.
This is my opinion but unless you are writing one-liners on purposes, try aerating your code more. It will make it way easier to read, debug and maintain.
This is the code you wrote, modified to include the calculated properties and with the WarningAction parameter set to Get-AzureRMVM instead of the Select statement.
$azureSubs = Get-AzureRMSubscription
$Vms = $azureSubs | ForEach-Object {Select-AzureRMSubscription $_ | Out-Null; Get-AzureRMVM -WarningAction SilentlyContinue | select resourcegroupname, name, licensetype, #{Name="VMSize";Expression={$_.HardwareProfile.VmSize}},#{Name="OsType";Expression={$_.StorageProfile.OsDisk.OsType}}}
$Vms | ft
The same thing, with some progress indication without forcing everything on one line.
$azureSubs = Get-AzureRMSubscription
$Vms = New-Object 'System.Collections.Generic.List[PSObject]'
ForEach ($sub in $azureSubs) {
Select-AzureRMSubscription $sub | Out-Null
Write-Host "Processing Subscription $($sub.Name)".PadRight(50,' ') -ForegroundColor Cyan -NoNewline
[PsObject[]]$items = Get-AzureRMVM -WarningAction SilentlyContinue |
select resourcegroupname,
name,
licensetype,
#{Name="VMSize";Expression={$_.HardwareProfile.VmSize}},
#{Name="OsType";Expression={$_.StorageProfile.OsDisk.OsType}}
Write-Host "($($items.count) retrieved)"
if ($items -ne $null) {
$vms.AddRange($items)
}
}
$vms | Format-Table
You are looking for something like this on the select side
select resourcegroupname, name, licensetype, #{Name="VMSize";Expression={$_.HardwareProfile.VmSize}}, #{Name="OsType";Expression={$_.StorageProfile.OsDisk.OsType}}
I've discovered this azure PS command Get-AzureRmConsumptionUsageDetail that as per docs is able to "get usage details of the subscription".
I performed some tests on my MSDN account with success. When tried with the Enterprise account (with many more resources) I've seen that it is always returning a max of 1000 items in all cases.
I tried to set -MaxCount to a higher than 1000 value without success.
The only workaround I see is try to identify all the resources in my subscription and query each one with the hope that no one individually has more than a thousand entries. Bad news is that I cannot do that for deleted items.
This behavior is not mentioned on the MS docs page so, any idea how this command should be properly used?
To partially solve my problem I developed a quick and dirty script that is able to ask for all the current subscription resources and then iterate through all them to get the billing details. It should be strange for a single resource to overpass the 1000 rows limit as resources are usually billed per day.
The drawbacks are the amount of api calls it has to perform and thus the time as well as that deleted resources are not included.
$resources = Get-AzureRmResource
Write-Output "Found $($resources.Count) in the subscription"
$consumption = #()
$i = $resources.Count
foreach($resource in $resources) {
$consumption += Get-AzureRmConsumptionUsageDetail -InstanceId $resource.ResourceId
$i--
Write-Output "$i - $($resource.ResourceId)"
}
$consumption | Group-Object InstanceId | %{
New-Object psobject -Property #{
ResourceGroup = ([regex]::Match($_.Name, ".*\/resource[gG]roups\/(.*?)\/.*$")).Groups[1].Value.ToUpper();
Cost = ($_.Group | Measure-Object PretaxCost -Sum).Sum
}
} | Group-Object ResourceGroup | %{
New-Object psobject -Property #{
ResourceGroup = $_.Name;
Total = ($_.Group | Measure-Object Cost -Sum).Sum
}
} | Export-Csv cost_report.csv