Powershell: Updating string in hash table - powershell

I have a collection of custom objects and need to do the following steps for each object:
Replace "Team1 Group" with "Team2 Group"
Save the resulting update to a hash table, which I will pass to an API
The objects look like this:
id : 1
groupId : 1
name : Customer1 Dashboard
fullName : Customer Dashboards/Team2 Group/Customer1 Group/Customer1 Dashboard
groupName : Customer1 Group
groupFullPath : Customer Dashboards/Team2 Group/Customer1 Group
widgetTokens : { #{type = owned; name = defaultResourceGroup; value = Client Teams/Team1 Group/Customers/Customer1*; inheritList = System.Object[] }, #{type = owned; name = defaultWebsiteGroup; value = Client Teams/Team1 Group/Customers/Customer1; inheritList = System.Object[]}}
This is what I have so far:
Foreach ($dashboard in $allDashboards) {
$dashboardProperties = #{ }
$dashboard.psobject.properties | ForEach-Object { $dashboardProperties[$_.Name] = $_.Value }
#($dashboardProperties.GetEnumerator()) | Where-Object { $_.Name -eq 'widgetTokens' } | Select-Object -ExpandProperty Value | Where-Object { $_.Value -match "Team1 Group" } | ForEach-Object { $dashboardProperties[$_.Key] = #($_.value.replace('Team1 Group', 'Team2 Group')) }
$dashboardProperties
#Code to interact with an API
}
Because there are two items that match the "#($dashboardProperties.GetEnumerator()) | Where-Object { $_.Name -eq 'widgetTokens' }..." line (at least, I think that's why), I am getting the following error:
Index operation failed; the array index evaluated to null.
At line:1 char:200
+ ... ch-Object { $dashboardProperties[$_.Key] = #($_.value.replace('Team1 ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
Index operation failed; the array index evaluated to null.
At line:1 char:200
+ ... ch-Object { $dashboardProperties[$_.Key] = #($_.value.replace('Team1 ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
When I run this, I see both lines, as expected:
#($dashboardProperties.GetEnumerator()) | Where-Object { $_.Name -eq 'widgetTokens' } | Select-Object -ExpandProperty Value | Where-Object { $_.Value -match "Team1 Group" }
I am not sure how to move past this, any thoughts?
Thanks

Based on feedback from Reddit, looks like this should work:
$DashboardProperties.WidgetTokens |
Where-Object { $_['Name'] -eq 'widgetTokens' -and $_['Value'] -match 'Team1 Group' } |
ForEach-Object { $_['Value'] = $_['Value'] -replace '1','2' }

Related

Get Distribution List muliple Owners in exchange

i need a power shell cmd or script which will give me the list of all the Distributions list along with the OWNERS of that like managed by.
But , if there are multiple users inside managedby attribute then I am getting System.Object[].
My question are :
1- how can we get multiple users for managedby attribute ?
2- how can we add employeeid and samaccountname for managedby users ?
3 - if there is no managed by user then it display "NO MANAGED BY USER"
4- I want to get mail groups not hidden.
script :
$DGroups=Get-DistributionGroup -resultsize unlimited
$mastertable=#()
ForEach($Group in $DGroups){
$table=[pscustomobject][ordered]#{
Name = $group.name
"Managed By" = $group.managedby.name
"DistinguishedName" = $group.DistinguishedName
}
$Mastertable += $table
}
$Mastertable | export-csv C:\tmp\managedby.csv -NoTypeInformation
My output :
"Name","Managed By","DistinguishedName"
"IT research","System.Object[]","CN=IT research,OU=TEST,DC=contoso,DC=com"
"Test Mail Group 1","User01","CN=\Test Mail Group 1,OU=Test,OU=COMPANY,DC=contoso,DC=com"
"Test Mail Group 2",,"CN=\Test Mail Group 2,OU=Test,OU=COMPANY,DC=contoso,DC=com"
My desired output :
"Name","Managed By","DistinguishedName","OWNERSAMACCOUNTNAME","OWNEREMPLOYEEID"
"IT research","User01;User02","CN=IT research,OU=TEST,DC=contoso,DC=com","tst124;tst125","242333;344232"
"Test Mail Group 1","User01","CN=\Test Mail Group 1,OU=Test,OU=COMPANY,DC=contoso,DC=com","tst124","242333"
"Test Mail Group 2","NO MANAGED BY USER","CN=\Test Mail Group 2,OU=Test,OU=COMPANY,DC=contoso,DC=com"
LAST UPDATE :
[PS] C:\Windows\system32>$group.ManagedBy
OrgHierarchyToIgnore :
IsDeleted : False
Rdn : CN=John T
Parent : contoso.com/COMPANY/IT
Depth : 5
DistinguishedName : CN=John T,OU=IT,DC=contoso,DC=com
IsRelativeDn : False
DomainId : contoso.com
PartitionGuid : 59ce2f71-eaa2-4ddf-a4fa-f25069d0b324
PartitionFQDN : contoso.com
ObjectGuid : 62d578e8-b69c-45bc-967a-e530d72792e1
Name : John T
[PS] C:\Windows\system32>$group.ManagedBy | ForEach-Object { $_ | Get-ADUser -Properties EmployeeId }
Get-ADUser : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties
do not match any of the parameters that take pipeline input.
At line:1 char:42
+ $group.ManagedBy | ForEach-Object { $_ | Get-ADUser -Properties EmployeeId }
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (contoso.com/COMPANY/IT/John T:PSObject) [Get-ADUser], ParameterBindingException
+ FullyQualifiedErrorId : InputObjectNotBound,Microsoft.ActiveDirectory.Management.Commands.GetADUser
It is my understanding the ManagedBy attribute stores the DistinguishedName(s) of one or more users (or none at all).
I haven't tested this myself, but you could try:
$DGroups = Get-DistributionGroup -ResultSize Unlimited
$mastertable = foreach($group in $DGroups) {
# initialize a PsCustomObject
$data = [PsCustomObject]#{
Name = $group.Name
DistinguishedName = $group.DistinguishedName
ManagedBy = 'NOT MANAGED'
OwnerSamAccountName = $null
OwnerEmployeeId = $null
}
if ($group.ManagedBy) {
$managedBy = $group.ManagedBy | ForEach-Object { Get-ADUser -Identity $_.DistinguishedName -Properties EmployeeId }
$data.ManagedBy = $managedBy.Name -join ';'
$data.OwnerSamAccountName = $managedBy.SamAccountName -join ';'
$data.OwnerEmployeeId = $managedBy.EmployeeId -join ';'
}
# output this data to be collected in $mastertable
$data
}
$mastertable | Export-Csv 'C:\tmp\managedby.csv' -NoTypeInformation

Is there a reason my Powershell script is now returning null-value expression errors?

As the title suggests, I have a script that I've been running daily to parse tables from a web page and export those to a csv. A few days ago though, I realized the script has been returning the following errors:
You cannot call a method on a null-valued expression. At C:\Users\Luke\DailyStats\NHLStats.ps1:16 char:1
+ $headers = $rows.item(1).children | select -ExpandProperty InnerText
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull Cannot index into a null array. At C:\Users\Luke\DailyStats\NHLStats.ps1:23 char:14
+ $headers = #($headers[0];'TEAM';$headers[1..($headers.Length-1)])
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray Cannot index into a null array. At C:\Users\Luke\DailyStats\NHLStats.ps1:23 char:33
+ $headers = #($headers[0];'TEAM';$headers[1..($headers.Length-1)])
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
I don't get why all of a sudden it randomly stopped working. Any and all help is greatly appreciated.
My script:
$url = "https://www.hockey-reference.com/leagues/NHL_2020.html"
#getting the data
$data = Invoke-WebRequest $url
#grab the third table
$table = $data.ParsedHtml.getElementsByTagName("table") | Select -skip 2 | Select -First 1
#get the rows of the Team Statistics table
$rows = $table.rows
#get table headers
$headers = $rows.item(1).children | select -ExpandProperty InnerText
#$headers = $headers | % { if ($_ -eq "GF") { "GFPG" } else { $_ }}
#count the number of rows
$NumOfRows = $rows | Measure-Object
#Manually injecting TEAM header and replace any headers you want to change
$headers = #($headers[0];'TEAM';$headers[1..($headers.Length-1)])
#enumerate the remaining rows (we need to skip the header row) and create a custom object
$allData = #{}
$out = for ($i=2;$i -lt $NumofRows.Count;$i++) {
#define an empty hashtable
$objHash=[ordered]#{}
#getting the child rows
$rowdata = $rows.item($i).children | select -ExpandProperty InnerText
for ($j=0;$j -lt $headers.count;$j++) {
#add each row of data to the hash table using the correlated table header value
$objHash[$headers[$j]] = $rowdata[$j]
}
#turn the hashtable into a custom object
[pscustomobject]$objHash
$allData.Add($i, $objHash)
}
$out | Select TEAM,AvAge,GP,W,L,OL,PTS,PTS%,GF,GA,SOW,SOL,SRS,SOS,TG/G,EVGF,EVGA,PP,PPO,PP%,PPA,PPOA,PK%,SH,SHA,PIM/G,oPIM/G,S,S%,SA,SV%,SO -SkipLast 1 | Export-Csv -Path "C:\Users\Luke\DailyStats\$((Get-Date).ToString("'NHL Stats' yyyy-MM-dd")).csv" -NoTypeInformation
Looks like your $table variable is returning null. When running that |select -skip 2 | select -first 1, it isn't returning any data to the $table variable.
This seems to be related to the -skip 2 selection.
When running just the portion of the $table = $data.ParsedHtml...
It only returns two objects.
So possibly you need to update your selection to properly retrieve the table that you want?
I am only seeing the 'standings EAS' and 'standings WES' tables being pulled.

I can't get Powershell StartsWith function to work

I'm trying to create a Powershell script that prints out only certain AD groups from the Folder Permission settings. However for some reason Powershell doesn't recognize StartsWith function.
("C:\folder" | get-acl).Access | ForEach-Object { if (($_.IdentityReference).StartsWith("sl_test")) { continue }; $_ }
When I run this I got errors similar to this for every foreach object:
Method invocation failed because [System.Security.Principal.NTAccount] does not contain a method named 'StartsWith'.
At C:\temp\test.ps1:1 char:56
+ ("C:\folder" | get-acl).Access | ForEach-Object { if (($_.IdentityReference).St ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Any suggestions on how to get this to work?
IdentityReference is a [System.Security.Principal.NTAccount]according to your error message.
But .StartWith is a method on the String type. If you call a method, Powershell does no magic for you, AFAIK.
Try ... ($_.IdentityReference) -match "^sl_test" ..., which should do the implicit string conversion.
If you want the string representation of an IdentityReference (regardless of whether it's and NTAccount object or a SID), you can reference the Value property:
$_.IdentityReference.Value.StartsWith('sl_test')
Try:
Get-Acl -Path "C:\folder" | Select-Object -ExpandProperty Access | Where-Object {$_.IdentityReference -like "sl_test*" }
You can customize the output with an additional | Select-Object -Property XY

List all azure resources with tagnames and tagvalues using PowerShell

I am trying to fetch OperatingHours tag details for all the Azure VirtualMachines and Azure SqlDatabases.
Following are the possibility for appID in a resource and the values I need to print in output correspondingly:
If OperatingHours tag itself is not present in any resource then display "Tag not present"
if OperatingHours tag is present but contains null or empty string then display "NULL/EMPTY"
if OperatingHours tag is present with any other value then display that value.
Do I need to take care of option (2) separately or is it like printing any normal value of the OperatingHours.
After long efforts I have created following script:
$ErrorOccured = $false
$resources = Get-AzureRmResource |
Where-Object {($_.ResourceType -eq "Microsoft.Compute/virtualMachines") -or ($_.ResourceType -eq "Microsoft.Sql/servers/databases")} |
foreach {
new-object psobject -Property #{
ResourceName = $_.ResourceName;
ResourceType = $_.ResourceType;
OperatingHours= try {
$ErrorActionPreference = 'SilentlyContinue';
($_ | select -expand Tags).OperatingHours; }
catch {
$ErrorOccured = $true ; }
if ($ErrorOccured)
{ "Tag not present" }
else {
($_ | select -expand Tags).OperatingHours;
$ErrorOccured = $false };}
}
$resources | Format-Table
When running this script, I am receiving following error:
At line:13 char:58
+ }
+ ~
The hash literal was incomplete.
At line:20 char:2
+ }
+ ~
Unexpected token '}' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : IncompleteHashLiteral
If I replace the OperatingHours statement with following code then the script is running with success. But in doing so, I am not able to satisfy the option (1) mentioned above.
Operating Hours = if (!($_ | select -expand Tags).OperatingHours)
{"Tag not present"}
else {($_ | select -expand Tags).OperatingHours} ;
Please advise me on how to correct this and get the required output.
Thanks
After alot of hit and trial and rigorous testing, I found what I was looking for:
OperatingHours = if ( ($_ | select -expand Tags).OperatingHours -ieq $null )
{"TAG NOT PRESENT"}
elseif ( ($_ | select -expand Tags).OperatingHours -ieq '')
{"NULL/EMPTY"}
else
{($_ | select -expand Tags).OperatingHours } ;
I replaced the OperatingHours statement in original script to above.
The solution looks easy and after finding it I was like how could I miss that earlier, but that's what learning process is all about, right ?

Find key in hash table (ContainsKey) not working

I'm loading a hash table with this:
$htA = dir | Where-Object {$_.Name -match "\.output\.[A-Z]-[0-9]\.csv"} | select name,length
When I try to search the Key column like thusly:
$htA.ContainsKey($h.name)
I get this super neat-o error:
Method invocation failed because [Selected.System.IO.FileInfo] does not contain a method named 'ContainsKey'.
At line:3 char:9
IF ($htA.ContainsKey($h.name) -eq $false) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (ContainsKey:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound**
So is this not a legit hashtable?
$htA is created as the type cast to it, in this case System.IO.FileInfo. Try this:
$htA = #{} # Initialises as an empty hash table
foreach ($file in (dir | Where-Object {$_.Name -match "\.output\.[A-Z]-[0-9]\.csv"} | select name,length))
{
$htA.Add($file.name, $file.length) # Populate hash table
}