Query Azure RBAC assignments using Azure powershell - azure

Azure: Extend Psh command with two columns resource type & name
I am trying to write a Azure Psh command with two columns resource type & name and query the RBAC assignments for a user.
I have these two tables, is there a way to merge the following two tables?
Following is my current progress with the command:
Get-AzRoleAssignment -SignInName A12345#abc.com | Select-Object -Property RoleDefinitionName, {Get-AzResource -ResourceId $_.RoleAssignmentID | Select-Object -Property Name,ResourceType} | Format-Table;
Get-AzRoleAssignment -SignInName A12345#abc.com | Select-Object -Property RoleDefinitionName, {Get-AzResource -ResourceId $_.Scope | Select-Object -Property Name, ResourceType} | Format-Table

You can use the below command to directly get the two information in one line :
Get-AzRoleAssignment -SignInName ansuman#xyz.com | Select-Object -Property RoleDefinitionName, {Get-AzResource -ResourceId $_.RoleAssignmentID | Select-Object -Property Name,ResourceType} , {Get-AzResource -ResourceId $_.Scope | Select-Object -Property Name, ResourceType} | Format-Table
Update:
To prettify the Headers you can use this :
Get-AzRoleAssignment -SignInName ans#xyz.com | Select-Object -Property RoleDefinitionName, #{N='RoleDetails';E={Get-AzResource -ResourceId $_.RoleAssignmentID | Select-Object -Property Name,ResourceType}} , #{L='ScopeDetails';E={Get-AzResource -ResourceId $_.Scope | Select-Object -Property Name, ResourceType}}
Output:

Related

How to retrieve only authorization.action via PS

Trying to retrieve the value of Authorization.action from Get-AzActivityLog | select-Object but I am having difficulty filtering my results down to what I need.
When running the below, I get results but when I pipe to Select-Object to only return the specified values, I get values for all except Autorization.action. Fairly new so not sure how to accomplish this and not finding documentation that clarifies to me online. Obviously Authorization.action is not correct but I can't seem to find a solution.
Get-AzActivityLog -ResourceId $sa.Id `
-StartTime ((Get-Date).AddDays($timeframe)) `
-Status Succeeded `
| where {$_.Authorization.action -like "Microsoft.Storage/storageAccounts/regenerateKey/action"} `
| Select-Object Authorization.action, EventTimestamp, ResourceGroupName, ResourceId
Output
Thanks for any insight in to this.
You could do it in Multiple ways :
Get-AzActivityLog -ResourceId $sa.Id `
-StartTime ((Get-Date).AddDays($timeframe)) `
-Status Succeeded `
| where {$_.Authorization.action -like "Microsoft.Storage/storageAccounts/regenerateKey/action"} `
| Select-Object {$_.Authorization.action}, EventTimestamp, ResourceGroupName, ResourceId
Or
Like Mathias Mentioned :
Get-AzActivityLog -ResourceId $sa.Id `
-StartTime ((Get-Date).AddDays($timeframe)) `
-Status Succeeded `
| where {$_.Authorization.action -like "Microsoft.Storage/storageAccounts/regenerateKey/action"} `
| Select-Object #{Name='AuthorizationAction';Expression={$_.Authorization.action}}, EventTimestamp, ResourceGroupName, ResourceId
The Reason Being Select-Object chooses the immediate property of the object. However, in your case the Authorization.Action is one level down being a complex property. So you will have to evaluate the expression.
Also you could use the -ExpandProperty parameter to expand a complex property.
Select-Object Authorization -ExpandProperty Authorization | Select-Object Action

Get Azure resource using filters

i'm trying to use Powershell to query my Storage Accounts by using name filter
I have tried these commands (and their variants) but have not still managed to get this working.
Get-AzStorageAccount | where -FilterScript {($_.ResourceType -eq "storageAccounts") -and ($_.StorageAccountName -contains "Prod") }
Get-AzResource -ResourceType Microsoft.Storage/storageAccounts | Get-AzResource -Name Prod* | ft
Any tips because I'm a bit lost. My goal would be that command / script would print out e.g all Storage Accounts which contains Prod in their name.
You can use Where-Object and -match to filter here:
Get-AzStorageAccount | Where-Object {$_.StorageAccountName -match 'prod'}
Or using -like:
Get-AzStorageAccount | Where-Object {$_.StorageAccountName -like '*prod*'}
If you really want to use Get-AzResource, then you need to filter by the Microsoft.Storage/storageAccounts resource type:
Get-AzResource -ResourceType "Microsoft.Storage/storageAccounts" | Where-Object {$_.Name -match 'prod'}
You can have a look at Matching Operators from about_comparison_operators for more information.

Azure PowerShell - get VM usage from across all subscriptions

I want to list all the VMs that generate costs in a specific timeframe or billing period.
I managed to create this script to get me the desired output:
$file="C:\temp\GeneratedCost-short.csv"
(az consumption usage list `
--start-date "2020-07-01" --end-date "2020-07-31" | ConvertFrom-Json)`
| Where-Object {$_.product -Match "Virtual Machines"}`
| Sort-Object -Property instanceName -Descending | Select-Object instanceName, subscriptionName`
| Get-Unique -AsString | ConvertTo-Csv -NoTypeInformation | Set-Content $file
But this will give me the output only for the current subscription.
How can I run on all the subscriptions that I have on the azure tenant?
I tried using the below version but it doesn't seem to work:
$file="C:\temp\GeneratedCost-short.csv"
$VMs = #()
$Subscriptions = Get-AzSubscription
foreach ($sub in $Subscriptions) {
Get-AzSubscription -SubscriptionName $sub.Name | az account set -s $sub.Name
$VMs += (az consumption usage list --start-date "2020-07-01" --end-date "2020-07-03" | ConvertFrom-Json)
}
#
$VMs | Where-Object {$_.product -Match "Virtual Machines"}`
| Sort-Object -Property instanceName -Descending | Select-Object instanceName, subscriptionName`
| Get-Unique -AsString | ConvertTo-Csv -NoTypeInformation | Set-Content $file
Any suggestions?
Mixing the Azure PowerShell module and Azure CLI could be causing issues with your code if the accounts haven't been retrieved between the two. Verify that az cli has the proper subscriptions
az account list -o table
If you don't see the accounts be sure to re-run az login.
Here's your code with the azure cli only
$file="C:\temp\GeneratedCost-short.csv"
$VMs = #()
az account list -o json | ConvertFrom-Json |
ForEach-Object {
Write-Host "Getting usage for account: " $_.Name
az account set -s $_.Name
$VMs += (az consumption usage list --start-date "2020-07-01" --end-date "2020-07-03" | ConvertFrom-Json)
}
$VMs | Where-Object {$_.product -Match "Virtual Machines"} |
Sort-Object -Property instanceName -Descending |
Select-Object instanceName, subscriptionName |
Get-Unique -AsString | ConvertTo-Csv -NoTypeInformation |
Set-Content $file
never do += on an array, worst pattern ever.
[System.Collections.Generic.List[PSObject]]$VMs = #()
$subs = Get-AzSubscription # | Where-Object {$_.State -eq 'Enabled'}
foreach ($s in $subs) {
Set-AzContext -SubscriptionObject $s | Out-Null
$vm = # your search here ...
$VMs.Add($vm)
}

Azure Powershell - Script to obtain VM info across subscriptions

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}}

Output Value from select-object calculated value

I've used a hash table to calculate some values for my VMWare inventory script, but now when I output the data, it records it as a key/value pair. I'd like to dump just the value. When I simply take what I'm handed that works fine, but when I get picky PS starts to stonewall me. :-)
Here is the relevant part of the script.
foreach ($machine in $vmList) {
$vmname = $machine.Name
$properties = #{
'Name'=Get-VM $vmname | Select -ExpandProperty Name
'RAM'=Get-VM $vmname | Select -ExpandProperty MemoryGB
'CpuCount'=Get-VM $vmname | Select -ExpandProperty NumCpu
'UsedDiskGB'=Get-VM $vmname | Select-Object #{n="UsedDiskGB"; e={[math]::Round( $_.UsedSpaceGB, 3 )}}
'TotalDiskGB'=Get-VM $vmname | Select-Object #{n="TotalDiskGB"; e={[math]::Round((Get-HardDisk -vm $_ | Measure-Object -Sum CapacityGB).Sum)}}
'Networks'=Get-VM $vmname | Select-Object #{n="Networks"; e={(Get-NetworkAdapter -VM $_ |Sort-Object NetworkName |Select -Unique -Expand NetworkName) -join '; '}}
'OS'=(Get-VM -Name $vmname | Get-View).summary.config.guestFullName
}
$object=New-Object -TypeName PSObject -Prop $properties
Export-Csv -Path $WorkDir\vms.csv -Append -Encoding UTF8 -InputObject $Object
Write-Output $Object
}
How do I get UsedDiskGB, Networks and TotalDiskGB to display just the value instead of something like '#{TotalDiskGB=80}'? Ram, OS, CpuCount and Name work exactly as desired already.
Also, suggestions on doing this in a faster way are welcome. I'm sure all these calls can be done better. I had it done in a single line, but then they asked for OS to be added and that changed everything.
Easy, but bad way:
In the expression pipe to |Select -ExpandProperty <property name> to get just the value. Such as:
'TotalDiskGB'=Get-VM $vmname | Select-Object #{n="TotalDiskGB"; e={[math]::Round((Get-HardDisk -vm $_ | Measure-Object -Sum CapacityGB).Sum)}}|select -expand totaldiskgb
The better way:
Structure your properties better to start with. Try this:
'TotalDiskGB'= [math]::Round((Get-HardDisk -vm (Get-VM $vmname) | Measure-Object -Sum CapacityGB).Sum)
The reason you're having issues is because you are creating a PSCustomObject with your Select, and Totaldiskgb is a property of that object. You don't want to make an object, you just want the value of that property.
Edit: Thank you to #briantist for pointing out that Get-VM $vmname should be called once, and stored as an object to be used later, rather than called for each time it is needed for a member of $Properties. For example:
foreach ($machine in $vmList) {
$vmname = $machine.Name
$vmobject = Get-VM $vmname
$properties = #{
'Name'=$vmobject | Select -ExpandProperty Name
'RAM'=$vmobject | Select -ExpandProperty MemoryGB
'CpuCount'=$vmobject | Select -ExpandProperty NumCpu
'UsedDiskGB'=[math]::Round( $vmobject.UsedSpaceGB, 3 )
'TotalDiskGB'=[math]::Round((Get-HardDisk -vm $vmobject | Measure-Object -Sum CapacityGB).Sum)
'Networks'=(Get-NetworkAdapter -VM $vmobject |Sort-Object NetworkName |Select -Unique -Expand NetworkName) -join '; '
'OS'=($vmobject | Get-View).summary.config.guestFullName
}
$object=New-Object -TypeName PSObject -Prop $properties
Export-Csv -Path $WorkDir\vms.csv -Append -Encoding UTF8 -InputObject $Object
Write-Output $Object
}

Resources