Powershell 7 - Get-AzureADUser, AssignedLicenses, Convert Class to Object - azure

When I retieve an AzureADUser while using the AzureAD module (imported with -UseWindowsPowershell), and trying to retrieve the property for AssignedLicenses, they return as a Class instead of an obect (e.g. just a string?)
class AssignedLicense {
DisabledPlans: System.Collections.Generic.List`1[System.String]
SkuId: zzzzzzzz-2c81-4ef7-yyyy-5b5392b571df}
class AssignedLicense {
DisabledPlans: System.Collections.Generic.List`1[System.String]
SkuId: zzzzzzz-fae0-4ca2-xxxx-7a907fd6c235
}
How would I convert such a thing to something I can actually use (e.g. an object?)
At first I thought it was JSON, but the ConvertFrom-JSON cmdlet gave errors on the notation, as far as I am aware there is no ConvertFrom-Class included in normal powershell :)
Did also try to just remove all the text and keep anything after SkuID, but that proves a challenge when the DisabledPlans is bigger/smaller than I expect.
Output received by running these commands:
$userList = Get-AzureADUser -filter "AccountEnabled eq true"
foreach ($u in $userList) {
$Assigned = ($u | Select-Object AssignedLicenses).AssignedLicenses
}

I tried to reproduce the scenario in my environment:
I tried the same script as yours:
$userList = Get-AzureADUser -filter "AccountEnabled eq true"
foreach ($u in $userList) {
$Assigned =($u | Select-Object AssignedLicenses ).AssignedLicenses
$Assigned
}
Getting expected result :
Alternately I tried with below commands:
$users = Get-AzureADUser -filter "AccountEnabled eq true"
$users | ForEach-Object {
foreach($user in $_.AssignedLicenses){
New-object -typename PSobject -property #{
ID = $_.Id
DisplayName = $_.DisplayName
DisabledPlans = $user.DisabledPlans
SkuId = $user.SkuId
}
}} | Sort-Object ID, DisplayName, DisabledPlans, SkuId | Export-Csv -Path C:\Assignedlicense2.csv -NoTypeInformation
I am getting the same result type for disabled plans System.Collections.Generic.List'1[System.String] as below image:
You can try the second way and check from your end or adding -join parameter to each object .
Reference: powershell - How to convert "System.Collections.Generic.List`1[System.String]" into readable format Using Get-AzureADMSConditionalAccessPolicy cmdlet - Stack Overflow
Or directly use:
$userList = Get-AzureADUser -filter "AccountEnabled eq true"
foreach ($u in $userList) {
$Assigned =$u.AssignedLicenses
$Assigned
}

Related

PowerShell: Output provider results from multiple Azure subscriptions into one .txt file - via arrayList

I am trying to get the registered providers for multiple subscriptions and output everything into one file.
For that, i am getting the subscriptions from a folder full of *.yaml files that contain information about the subscriptions, including their name.
What i cannot achieve is get the result for each subscriptions into an array and output that array into a text file. The script also allows the use of only one item from the folder in case that is the case.
Here is a sample code of a subscription and the code for it:
subscription1.yaml
name: subscription1
emailContact: email.address#domain.com
tags:
- key: "key1"
value: "Value1"
subscription2.yaml
name: subscription2
emailContact: email.address#domain.com
tags:
- key: "key1"
value: "Value1"
Folder structure where the yaml files is: ./landingZones/landingzone1/settings/dev/*.yaml
script:
param (
[Parameter(Mandatory = $false)]
[string]$Environment = 'dev',
[Parameter(Mandatory = $false)]
[string]$LandingZoneType = 'landingzone1',
[Parameter(Mandatory = $false)]
[string]$SingleSubscription
)
$scriptPath = Split-Path -parent $PSCommandPath
$subscriptionsEnvironmentDirectory = Get-ChildItem -Directory $scriptPath -Recurse -Filter "*$Environment*" | Where-Object { $_.parent.parent.Name -eq $LandingZoneType }
$subscriptions = Get-ChildItem -Path $($subscriptionsEnvironmentDirectory.FullName)
foreach ($subscription in ($subscriptions | Where-Object { ([System.String]::IsNullOrEmpty($SingleSubscription)) -or ($_.Name -replace "\.[^\.]+$", '') -eq $SingleSubscription })) {
$landingZone = Get-Content -Path $subscription.FullName | ConvertFrom-Yaml
# Set subscriptionName variable
$subscriptionName = $landingZone.name
$providers = az provider list --subscription $subscriptionName | ConvertFrom-Json
$defaultRegisteredProviders = 'Microsoft.ADHybridHealthService|Microsoft.Authorization|Microsoft.Billing|Microsoft.ClassicSubscription|Microsoft.Commerce|Microsoft.Consumption|Microsoft.CostManagement|Microsoft.Features|Microsoft.MarketplaceOrdering'
$registeredProviders = $providers | Where-Object { ($_.registrationState -eq 'Registered') -and ($_.namespace -notmatch $defaultRegisteredProviders) }
# Outputting result into txt file in the same directory where the command was executed
Write-Host ('{1}# Registered providers for subscription [{0}]' -f $subscriptionName, "`n")
$list = New-Object -TypeName 'System.Collections.ArrayList'
$sortedObjects = $registeredProviders | Sort-Object namespace | `
Format-Table `
#{l = 'Namespace'; e = { $_.namespace } }, `
#{l = "Subscription Id [$subscriptionName]"; e = { $_.id } }, `
#{l = 'Registration State'; e = { $_.registrationState } }, `
#{l = 'Registration Policy'; e = { $_.registrationPolicy } }
foreach ($i in $sortedObjects) {
$list.Add($i) | Out-Null
}
# Alternative to add into array:
# #($sortedObjects).foreach({$list.Add($_)}) | Out-Null
}
$list.Count
$list | Out-File .\registered_providers.txt -Force
The result is a file called 'registered_providers.txt' that contains only the registered providers for the first subscription in the foreach loop. I cannot get the contents of the second, third and so on in the same file, just a replaced text from the $sortedObjects
How do i create the array to contain all the info from all the subscriptions called?
Thanks
$list | Out-File Should be inside the for loop so that all the data you are fetching will be stored in the specified file.
Out-File cmdlet has -append parameter that appends the output to the existing file for every for loop happens. Otherwise, it will clean up the information/value stored in that output file.
Thanks to #jdweng for pointing the user to the right solution.
Refer to this MS Doc on Out-File -Append Parameter usage.

Trying to list Azure Virtual Network and export to CSV using Powershell

I am trying to create a script that can list all the Azure virtual networks and export it into Csv using Powershell.
$day = Get-Date -Format " MMM-yyyy"
$path = "C:\Users\admin-vishal.singh\Desktop\Test\Report\"+ "$day-Vnet-Report.csv"
foreach ($Sub in $Subs) {
Select-AzSubscription -SubscriptionName $Sub.Name | Out-Null
$resource_grps = Get-AzResourceGroup
foreach ($resource_grp in $resource_grps) {
$networks = Get-AzVirtualNetwork
foreach ($vnet in $networks)
{
$null = Get-AzVirtualNetwork |Select-Object SubscriptionName,ResourceGroupName,Name,AddressSpace,Subnets,SubnetAddressSpace,RouteTable | Export-CSV -Path $path -NoTypeInformation -Encoding ASCII -Append
}
}
}
I am not able to retrieve data in the right format & getting errors when retrieving data.
Below is snippet of data
Lots of values I am not able to retrieve like Subnet AddressSpace, Route Tables and Routes.
Building on what Jim Xu provided, you don't need to have a separate loop for each ResourceGroup. Get-AzVirtualNetwork will return all virtual networks for the entire subscription. Also, you'll need an expression for the SubscriptionName in the Select-Object, so the code would look like this:
foreach ($Sub in $Subs) {
Select-AzSubscription -SubscriptionName $Sub.Name | Out-Null
Get-AzVirtualNetwork |
Select-Object `
#{label='SubscriptionName'; expression={$Sub.Name}}, `
ResourceGroupName, `
Name, `
#{label='AddressSpace'; expression={$_.AddressSpace.AddressPrefixes}}, `
#{label='SubnetName'; expression={$_.Subnets.Name}}, `
#{label='SubnetAddressSpace'; expression={$_.Subnets.AddressPrefix}} |
Export-CSV -Path $path -NoTypeInformation -Encoding ASCII -Append
}
When we call export-csv command, the property values are converted to strings using the ToString() method. But the result of Get-AzVirtualNetwork are object, we cannot directly convert the value to string. For more details, please refer to here and here
So regarding the issue, I suggest you create a custom object with the information you need then save it into csv.
For exmaple
$vents =Get-AzVirtualNetwork|
Select-Object SubscriptionName,ResourceGroupName,Name, #{
label='AddressSpace'
expression={$_.AddressSpace.AddressPrefix}}, #{
label='SubnetName'
expression={$_.Subnets.Name}
}, #{
label='SubnetAddressSpace'
expression={$_.Subnets.AddressPrefix}
}
$vents | convertto-csv

How to output hash table query result into Out-GridView?

I wish to export a hashtable result into Out-GridView using the Powershell.
The purpose of the below script is to export the Azure VM tags to Out-GridView, it throws error like the below blank result:
Error on the console:
Out-GridView : Syntax error in PropertyPath 'Syntax error in Binding.Path '[ Product] ' ... '(Tag)'.'.
At line:46 char:19
+ $Output | Out-GridView #Export-Csv -Path c:\temp\1a.csv -appe ...
+ ~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [Out-GridView], InvalidOperationException
+ FullyQualifiedErrorId : ManagementListInvocationException,Microsoft.PowerShell.Commands.OutGridViewCommand
This is the actual script which was executed under the Global Administrator role:
<#
.AUTHOR: https://stackoverflow.com/users/13390556/lukasz-g
#>
$Subscription = Get-AzSubscription | Out-GridView -Title 'Select subscription' -OutputMode 'Multiple'
# Initialise output array
$Output = #()
if ($Subscription) {
foreach ($item in $Subscription) {
$item | Select-AzSubscription
# Collect all the resources or resource groups (comment one of below)
$Resource = Get-AzResource
#$Resource = Get-AzResourceGroup
# Obtain a unique list of tags for these groups collectively
$UniqueTags = $Resource.Tags.GetEnumerator().Keys | Get-Unique -AsString | Sort-Object | Select-Object -Unique | Where-Object { $_ -notlike "hidden-*" }
# Loop through the resource groups
foreach ($ResourceGroup in $Resource) {
# Create a new ordered hashtable and add the normal properties first.
$RGHashtable = New-Object System.Collections.Specialized.OrderedDictionary
$RGHashtable.Add("Name", $ResourceGroup.ResourceGroupName)
$RGHashtable.Add("Location", $ResourceGroup.Location)
$RGHashtable.Add("Id", $ResourceGroup.ResourceId)
$RGHashtable.Add("ResourceType", $ResourceGroup.ResourceType)
# Loop through possible tags adding the property if there is one, adding it with a hyphen as it's value if it doesn't.
if ($ResourceGroup.Tags.Count -ne 0) {
$UniqueTags | Foreach-Object {
if ($ResourceGroup.Tags[$_]) {
$RGHashtable.Add("[$_] (Tag)", $ResourceGroup.Tags[$_])
}
else {
$RGHashtable.Add("[$_] (Tag)", "-")
}
}
}
else {
$UniqueTags | Foreach-Object { $RGHashtable.Add("[$_] (Tag)", "-") }
}
# Update the output array, adding the ordered hashtable we have created for the ResourceGroup details.
$Output += New-Object psobject -Property $RGHashtable
}
# Sent the final output to CSV
$Output | Out-GridView #Export-Csv -Path c:\temp\1a.csv -append -NoClobber -NoTypeInformation -Encoding UTF8 -Force
}
}
$RGHashtable.Add("[$_] (Tag)"
In above code, You are trying to add something like below :
In the output
Removed everthing and I tested with simple statements
$Output = #()
$RGHashtable = New-Object System.Collections.Specialized.OrderedDictionary
$RGHashtable.Add("[Testing] (Name)", "Temporary")
$Output += New-Object psobject -Property $RGHashtable
$Output | Out-GridView
I was provided with the same error.
After couple of testing, understood the error only occurs when there is a combination "[SomeString](SomeString)" --- [...](....) in the string.
The Out-GridView is trying to parse the "[<SomeString>](<SomeString>)" and hence the error.
You could try any 1 of the below combination in your code :
$RGHashtable.Add("[$_] [Tag]", $ResourceGroup.Tags[$_])
OR
$RGHashtable.Add("{$_} (Tag)", $ResourceGroup.Tags[$_])
OR
$RGHashtable.Add("[$_] [Tag]", $ResourceGroup.Tags[$_])
This should resolve your issue.
you will have change in 3 instances in your code if I am not wrong.

How compare output returned from powershell cmdlet with a string

I have the following code:
$RecipientType = Get-Recipient $Name | Select-Object -Property RecipientType
if ($RecipientType.Equals("UserMailbox")) {
Write-Host "Mailbox is OnPrem"
}
I want to compare RecipientType value with string "UserMailbox", but it's not working...
For simplicity I'd use this:
if ((Get-Recipient $identity).RecipientType -eq 'usermailbox') {
Write-Host 'Mailbox is OnPrem'
}
Here instead of using Select-Object -Property, use Select-Object -ExpandProperty because Select-Object returns an object. It can be done as below:
$RecipientType = (Get-Recipient $Identity | Select-Object -ExpandProperty RecipientType)
if ($RecipientType.Equals("UserMailbox")) {
Write-Host "Mailbox is OnPrem"
}

In Azure, To get Load balancer details in to csv file using powershell script

I wrote a powershell script in Azure DevOps pipeline to get Load Balancer details like FrontendIPConfigurationsName,FrontendIPAddress in to csv file. AM getting those details but FrontendIPConfigurationsNames which starts with same name like "ers-A1,ers-B1,ers-C1,ers-D1" are coming in same row. But I want to get them in different rows.Please suggest
$excel = #()
LBlist = Get-AZLoadBalancer | Where-Oject {$_.ResourceGroupName -clike '$(grp-wildcard)'} | Select-Object
foreach ($LB in LBlist)
$Array =""| Select-Object ResourceGroupName, FrontendIPConfigurationsName,FrontendIPAddress
$Array.ResourceGroupName =$LB.ResourcegroupName
$Array.FrontendIPConfigurationsName = ($LB.FrontendIpConfigurationsName.name -join ',')
$Array.FrontendIPAddress =($LB.FrontendIpConfigurations.PrivateIpAddress -join ',')
}
$excel +=$Array
$excel |Format-Table ResourceGroupName, FrontendIPConfigurationsName,FrontendIPAddress
$excel | Export-Csv -NTI -Path "($Build.ArtifactStagingDirectory)/LBlist.csv
You can do something similar to this to get the objects on separate rows.
$LBlist = Get-AZLoadBalancer | Where-Object { $_.ResourceGroupName -clike '$(grp-wildcard)' }
$LBlist | Export-Csv -NTI -Path "$(Build.ArtifactStagingDirectory)/LBlist.csv"
Mock for Get-AZLoadBalancer (not sure if it's entirely accurate as I've never used Az Powershell)
function Get-AZLoadBalancer() {
$obj = #(
[PSCustomObject] #{
ResourceGroupName = '$(grp-wildcard)'
FrontendIPConfigurationsName = 'ers-A1'
FrontEndIPAddress = '1.2.3.4'
},
[PSCustomObject] #{
ResourceGroupName = '$(grp-wildcard)'
FrontendIPConfigurationsName = 'ers-B1'
FrontEndIPAddress = '1.2.3.5'
}
)
return $obj
}

Resources