Trying to write a Powershell query that shows all resource groups and the tag values - azure

I am trying to use Powershell to create a csv file that will provide a list of the Resource Groups and the Value of the Tags I have associated with them called "Cost Code" and "Environment"
I have tried the following commands which a mixture of the two provide the information I need I just need to join the two outputs.
(Get-AzureRmResourceGroup | Where ResourceGroupName -like rg*).Tags
(Get-AzureRmResourceGroup | Where ResourceGroupName -like rg*) | select ResourceGroupName, Tags | ft
The way I would like it to look is
ResourceGroup,Cost Code,Environment
RG1,1,Dev
RG2,2,Test
RG3,3,Prod
RG4,4,Dev
RG5,5,Test
RG6,6,Prod
RG7,7,Dev
RG8,8,Test
RG9,9,Prod

The following should output what you need:
Get-AzureRmResourceGroup | Where-Object { $_.ResourceGroupName -like "rg*"} |
Select-Object #{n='ResourceGroup';e={$_.ResourceGroupName}},
#{n='Cost Code';e={$_.Tags['Cost Code']}},
#{n='Environment';e={$_.Tags['Environment']}} |
ConvertTo-Csv -NoTypeInformation
Explanation:
Select-Object here is using calculated properties with three different hash tables. ResourceGroup is calculated only because you didn't specifically want the ResourceGroupName property provided by the standard output. Since .Tags stores a hash table, you can reference its values by named index (hashtable['tag_name']). The Select-Object results can be piped into any Object to CSV converter for the desired output. Here ConvertTo-Csv is used.

Related

Combining & matching output from Get-AzureADUser, Get-AzureADSubscribedSku , Get-AzureADUserManager

Problem & what i have now
The script
comments are in norwegian btw, if they look strange lol
Connect-AzureAD
#variabel
$Users = Get-AzureADUser -All:$true | where-object { $null -ne $_.AssignedLicenses.SkuId } | Sort-Object CompanyName, UserPrincipalName| Select-Object -Property CompanyName, DisplayName, UserPrincipalName, Department, Mobile, TelephoneNumber
#formatting
$userlistTable = $Users | Format-Table
$userlistHTML = $Users | ConvertTo-Html
#outputs
$userlistHTML > out.html # ut som HTML
$userlistTable > out.txt # ut som Tabell i .txt
$userlistTable # ut som Tabell i terminal
My output as it stands right now:
CompanyName DisplayName UserPrincipalName Department Mobile TelephoneNumber
----------- ----------- ----------------- ---------- ------ ---------------
Company inc Usser Name username#website.com Callsenter 12345678 87654321
What i would like. is a table that has all the info in the output of $Users to inclide the users "SkuPartNumber".
The field u get by running the command Get-AzureADSubscribedSku | Select -Property SkuPartNumber
I would also like to get the users "manager", that u get by running Get-AzureADUserManager.
that last command uses the users Object ID to find their manager.
And to be honest, im very lost on how to combine these commands into one table.
its not the end of the world as it is right now. i could of just have multiple tables but having to manually cross reference these takes some time.
Im really not sure why these things are split into different commands to be honest. i get that a license is via 365 and not azure. but it seems a little backwards that i cant see the licenses from the command showing me all the user information. when a user class in powershell DOES infact show the sku ID. its burried within AssignedLicenses from running the command:
Get-AzureADUser | where-object -property UserPrincipalName -eq "emailhere#domain.com" | FL
This will give you among other things, this info:
AssignedLicenses : {class AssignedLicense {
DisabledPlans: System.Collections.Generic.List`1[System.String]
SkuId: 3b555118-da6a-4418-894f-7df1e2096870
}
conclusion
I know this was a long read. and if u made it this far im sorry.
any help with this would be amazing. This might be super easy to do, but im very far from a powershell wiz. thanks again for reading, and any help.
You can add additional properties to selected objects with calculated properties like Select #{label='name';expression={foo}}
$Users = Get-AzureADUser -All:$true
$Users | Where-Object { $_.AssignedLicenses.SkuId } |
Select-Object -Property UserPrincipalName, ## other properties here...
#{l='ManagerUPN';e={($_ | Get-AzureADUserManager).UserPrincipalName}},
#{l='AssignedSKUs';e={$_.AssignedLicenses.SkuId -join ';'}}
UserPrincipalName ManagerUPN AssignedSKUs
----------------- ---------- ------------
user#domain.com manager#domain.com 00000000-0000-0000-0000-000000000000;11111111-1111-1111-1111-111111111111
It can be slow to run Get-AzureADUserManager for every user, but that's how azure stores the relationships.
When you have a lot of users, it can be slightly faster to get the manager users first, then use Get-AzureADUserDirectReport -all $true to expand all the directreports in one call. The Microsoft.Graph.Users module is also a bit more lightweight

Export-CSV showing System.Collections.Generic.Dictionary`2[System.String,System.String] for Azure Tags?

My script using Get-AzDisk https://learn.microsoft.com/en-us/powershell/module/az.compute/get-azdisk?view=azps-5.9.0 like below
Get-AzDisk -ResourceGroupName $ResourceGroupName|Where-Object{$_.ManagedBy.Length -lt 1} | Select-Object Name, OsType, DiskSizeGB, ResourceGroupName, Location, Tags, Tier, ProvisioningState, TimeCreated | ogv
Cannot export the actual Tags values like in the Out-GridView does:
This is the .CSV column for Tags:
How to modify it so it can show the same data as in the OGV?
You could use a calculated property to format the object (which is a hashtable) to the desired output. Here is an example that uses an calculated property to serialize the tags as JSON:
Get-AzDisk -ResourceGroupName $ResourceGroupName
| Where-Object { $_.ManagedBy.Length -lt 1 }
| Select-Object Name, OsType, DiskSizeGB, ResourceGroupName, Location, #{e = {$_.Tags | ConvertTo-Json | Out-String}; l='Tags'} , Tier, ProvisioningState, TimeCreated
And here the corresponding output as CSV (after I pipe it to ConvertTo-CSV cmdlet):
Tags are a Hash.
$myTags = $vm.Tags
if($myTags) {
foreach ($key in $myTags.Keys) {
$curVal = $myTags[$key]
}
}
You can grab all the Keys and Values and write them to a string in the column.
Be aware the $curVal could itself be a multi-value system.collections.generic.dictionary and might require further manipulation.

Issue with export-csv no data?

In my report when I remove the export-csv portion the data is presented correctly onscreen, when I add in the export-csv no data is exported but the file is created. Below is my script along with what the data looks like when script is running (modified) of what the data looks like.
#Get all DHCP Servers
$ServerList = (Get-Content -Path "\\termserv\DHCPServers.txt")
foreach ($server in $serverlist)
{
#Get the scopes from each serve
Get-DHCPServerv4Scope -ComputerName $server | select ScopeID |
#Get the lease information for each scope
ForEach-Object {Get-DHCPServerv4Lease -ScopeId $_.ScopeId -ComputerName
$server -AllLeases |
where {$_.AddressState -like "*Reservation"} | Select-Object
$server,ScopeId,IPAddress,HostName,ClientID,AddressState | Export-
Csv "\\termserv\d$\term\User\Reservations1.csv"
}
}
What the data looks like when exported without export-csv
NOPEDH01 :
ScopeId : 000.11.2.3
IPAddress : 111.22.3.444
HostName : NOPE00112233
ClientID : 00-11-22-33-44-55
AddressState : ActiveReservation
NOPEDH01 :
ScopeId : 000.11.2.3
IPAddress : 111.22.3.445
HostName : NOPE0011223344
ClientID : 00-11-22-33-44-56
AddressState : ActiveReservation
Update: Tried that and still nothing, when I run a modified version of the script locally on my DH servers it functions correctly, but I'm looking at almost 100 DH servers in my environment, see below
Get-DHCPServerV4Scope | ForEach {
Get-DHCPServerv4Lease -ScopeID $_.ScopeID -AllLeases | where
{$_.AddressState -like '*Reservation'}
} | Select-Object ScopeId,IPAddress,HostName,ClientID,AddressState | Export-
Csv "\\termserv\d$\term\$($env:COMPUTERNAME)-Reservations1.csv" -
NoTypeInformation
This is a representation of what you are doing:
Foreach ($Server in $ServerList)
{
Foreach ($Scope in $ScopeList)
{
$Data | Export-csv -Path FileName.csv
}
}
In doing so you are exporting data [(Total Servers) x (Total Scopes per server)] times which is a lot of I/O operations. It is just a logistics issue. You could collect the entire information into a table object before exporting. But that decision is up to you and your particular business needs.
The real issue, however, is that you are doing the export into the same file which essentially over writes whatever you have written before without telling it not to. So only the last export remains which I suspect is somehow blank.
Try using the -Append switch when you export.
$Data | Export-csv -Path FileName.csv -NoTypeInformation -Append
Also I noticed you are using $server variable in the select-object cmdlet where you should only be using the object's property names and not variable names. I do not know if that returns anything as the cmdlet would not know what to do with it, which could also be contributing to the problem.
According to your code you are using Export-Csv within a foreach-object. Generally Export-csv creates a csv file with new data. If data is already present in the csv file then it will overwrite the existing data with new one.
So instead of using
Export-Csv "\\termserv\d$\term\User\Reservations1.csv"
You cand use
Export-Csv "\\termserv\d$\term\User\Reservations1.csv" -Force -Append -NoTypeInformation
Here -Append will append the data in the csv file. Not overwrites.

Removing text in a string between two characters using Powershell

I have a powershell script that runs and collects information and puts it in a .csv file. A sample of the information looks like what is listed below, with each line starting with a unique server name followed by a random unique identifier in contained a pair of ( ).
"GDR01W01SQ004 (e785754f-eeb1)","1","4","63","NY-TER-PLN-P-5N"
"GDR01L02D001 (4b889a4d-d281)","4","12","129","CO-FDP-STE-NP-5N"
I have a second powershell script that runs and takes this .csv file and its information and formats it into a report with a header and proper spacing.
Can someone please assist me with removing the text in between the ( ) as well as the ( )?
I would like the entries for each line to look like the following:
"GDR01W01SQ004","1","4","63","NY-TER-PLN-P-5N"
Thank you very much in advance!
Here is the script I have been using.
####################PowerCLI Check####################
# Verify whether the PowerCLI module is loaded, if not load it.
if ( (Get-PSSnapin -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) -eq $null )
{
Add-PsSnapin VMware.VimAutomation.Core -ErrorAction Stop
}
################### Run Time Section ####################
#This script should be run from a server that has DNS records for all entries in vcenters.txt
$file = get-Content c:\reports\vcenter\vcenters.txt
foreach ( $server in $file) {
Connect-VIserver -Server $server
Get-VM | select Name, NumCpu, MemoryGB, ProvisionedSpaceGB, Notes | Out-Null
}
# Command for Custom Annotations.
Get-VM | select Name, NumCpu, MemoryGB, ProvisionedSpaceGB, Notes -expandproperty customfields | Export-Csv -path “c:\reports\vcenter\vcenall.csv” -NoTypeInformation
# Takes vcenall.csv and sorts only the Name and Notes columns and selects all but the custom fields. Capacity Reporting script caprep.ps1 runs against this csv.
Import-csv c:\reports\vcenter\vcenall.csv | Sort-Object Notes, Name | Select-Object Name, NumCpu, MemoryGB, ProvisionedSpaceGB, Notes |Export-csv capacity.csv -NoTypeInformation
#Used to remove domain from server name
(Get-Content capacity.csv) | ForEach-Object { $_ -replace ".domain.local", "" } | Set-Content capacity.csv
# Takes vcenall.csv and sorts only the Notes column and selects only the Name and Notes columns. Nimsoft comparison script nimcomp.ps1 runs against this csv.
Import-csv c:\reports\vcenter\vcenall.csv | Sort-Object Notes | Select-Object Name, Notes | Export-csv nimsoft.csv -NoTypeInformation
# Takes vcenall.csv and sorts only the Name columns and exports all fields. Backup/Restore comparison script bure.ps1 runs against this csv.
Import-csv c:\reports\vcenter\vcenall.csv | Sort-Object Name | Export-csv bure.csv -NoTypeInformation
I think you need to add more information but just using what you have let try this one approach
Import-Csv C:\temp\test.csv -Header server,1,2,3,4 | ForEach-Object{
$_.server = (($_.server).split("(")[0]).Trim()
$_
}
We import the csv data and assign a header. If you already have one then this parameter can be omitted.
Then we examine each row of data as an object. Change the server data by splitting it up by its spaces. If this data is for server names then it is safe to assume that that everything before the first space is the server name. This approach is dependent on the space being there. We could also use the same logic with the ( but this would be easier if the space was a guarantee.
So we update the server and then send the data back down the pipe with $_.
Sample Output
server 1 2 3 4
------ - - - -
GDR01W01SQ004 1 4 63 NY-TER-PLN-P-5N
GDR01L02D001 4 12 129 CO-FDP-STE-NP-5N
Edit based on comments
Since it is a server display name I changed the logic to split based on the "(". Also using the Split() method instead of the -split operator.

How do I add another column to a System.Object using a list in Powershell?

I am making a script to query active directory via powershell and pull all computers that contain a username in the description field, then filter that list with only computers last logged in the past 14 days.
This is what I have so far:
$queryAD = Get-ADComputer -SearchBase 'OU=West Division,DC=cable,DC=comcast,DC=com' -Properties Name, Description -Filter {(Name -like "WA*") -and (Description -like $wildCard)} | Select-Object Name, Description
$lastLogon = $queryAD | Select-Object -ExpandProperty Description | %{$_.replace(("$NTname" + ";"),"").split(";")[0]} | %{get-date $_ -format d}
I'd like to add the list generated from $lastLogon to $queryAD, right now $queryAD is returning two columns with headers Name and Description. I need a third header added called Last Logon Date and contain the list in $lastLogon. Please advise.
You could assign the values to an array of objects to make your output cleaner (if this method is providing you the data you want) like so:
$queryAD = Get-ADComputer -SearchBase 'OU=West Division,DC=cable,DC=comcast,DC=com' -Properties Name, Description -Filter {(Name -like "WA*") -and (Description -like $wildCard)} | Select-Object Name, Description
$computer_list = #()
foreach($computer in $queryAD) {
$computer_info = New-Object PSObject -Property #{
Name = $computer.Name
Description = $computer.Description
LastLogonDate = $computer | Select-Object -ExpandProperty Description | %{$_.replace(("$NTname" + ";"),"").split(";")[0]} | %{get-date $_ -format d}
}
$computer_list += $computer_info
}
in which case $computer_list will contain all of the info you're gathering in tidy objects.
...but this method seems overcomplicated. Look into this blog entry by Matt Vogt for a better way to query for old machines in AD.

Resources