JSON Array in PowerShell - arrays

Am trying to generate the below JSON string in PowerShell:
[
{
"FirstName": "Test",
"LastName": "Account2"
}
]
The code I have at the moment in PowerShell is:
$Body = #{
#{
FirstName='Test'
LastName='Account2'
}
}
The error I get with this is: Missing '=' operator after key in hash literal.

The outer [] is a list in JSON and you're trying to use #{}, which is a hashtable in PowerShell. Use #() which is an array (list) in PowerShell:
$Body = #(
#{
FirstName='Test'
LastName='Account2'
}
)
ConvertTo-Json -InputObject $Body
(and I use -InputObject instead of piping, because PowerShell is obsessed with flattering lists, and drops the list otherwise).

I had some problems adding new items to the Powershell list. I tried to add an item using the .add() function. This returned the error "Collection was of a fixed size."
Adding items to the list is just simple by using the += symbol.
$Body += #{FirstName='Test2'; LastName='Account3'}
That simple.

Related

Powershell Register WPF events

I'm trying to build a WPF gui where i have two radiobutton listboxes.
A button loads the radio buttons:
function mybuttonclick {
$List = get-content "list.txt"
foreach ($item in $list) {
$tmpradio = New-Object System.Windows.Controls.RadioButton
$tmpradio.content = "$item"
$tmpradio.groupname = "MyList"
Register-ObjectEvent -InputObject $tmpradio -EventName Checked -Action { write-host "test"}
$MyListbox.AddChild($tmpradio)
}
}
However i'm getting nothing back, is it a scope issue where the object gets deleted after exiting from the function?
Is there a solution to make so i can pick an action or another wheter the groupname is "MyList" or for example "MyOtherList"
Looks like i will once more answer my own question..
It honestly is as simple as i tought it would...
Jim Moyle explained it, i adapted to my situation..
function mybuttonclick {
$List = get-content "list.txt"
foreach ($item in $list) {
$tmpradio = New-Object System.Windows.Controls.RadioButton
$tmpradio.content = "$item"
$tmpradio.groupname = "MyList"
[System.Windows.RoutedEventHandler]$checkhandler = {write-host 'Test'}
$tmpradio.AddHandler([System.Windows.Controls.RadioButton]::CheckedEvent, $checkhandler)
$MyListbox.AddChild($tmpradio)
}
}
To make it simple i just create my radio button as usual,
then i create a handler scriptblock, which is just code executed on x event triggered.
At last i add that handler to my radiobutton on the CheckedEvent.
I could find the event name by opening up a debugger, type down this:
[System.Windows.Controls.RadioButton]::
and then start tabbing for autocompletion
Source: https://www.youtube.com/watch?v=s6A9KuEM324

Exporting Multi-Valued Attributes in PowerShell to Excel - Attempting to Automate Using an Array of Hash Tables

I am trying to automate the unwrapping of multi-valued attributes in PowerShell for the purpose of exporting the information to an excel sheet. The known solution for enabling multi-valued exporting to excel is to manually create a hash table for each multi-valued attribute, which works just well. Example:
Get-ADForest -Server <servername> |
Select-Object #{Name='ApplicationPartitions';Expression={$.ApplicationPartitions}},
DomainNamingMaster,
#{Name="Domains";Expression={$.Domains}},
ForestMode,
#{Name="GlobalCatalogs";Expression={$.GlobalCatalogs}},
Name,
PartitionsContainer,
RootDomain,
SchemaMaster,
#{Name="Sites";Expression={$.Sites}} |
Export-Csv $home'AD Forest Information.csv'
However, I would like to automate this for commands that have many multi-valued attributes. Here is what I have so far (I am using Get-ADForest for testing):
$Objects = #()
$Object = #{}
Get-ADForest | Get-Member | Where-Object {$_.membertype -eq 'property'} |
Select-Object Name |
ForEach-Object {$Object = #{Name=$_.Name;Expression="$" + "_" + "." + $_.Name} ; $Objects +=$Object}
Write-Output $Objects
Get-ADForest -Server <servername> | Select-Object $Objects | Export-Csv $home\'AD Forest Information.csv'
The issue is that the exported .csv has the correct column titles, but the values of the attributes are still Microsoft.ActiveDirectory.Management.ADPropertyValueCollection like they would be without unwrapping the attribute.
Please let me know if you have any questions.
Any suggestions would be awesome.
Thank you!
Austin
Try this for your example, let me know if this is what you expect as output for your csv:
cd $Home\Documents
function parseADObject{
param(
[cmdletbinding()]
[parameter(mandatory,valuefrompipeline)]
$InputObject
)
$properties=($inputObject|gm -MemberType Property).Name
$parsedObject=#{}
foreach($prop in $Properties)
{
$thisProp=$inputObject.$prop
if($thisProp -and $thisProp.GetType() -match 'Collection|\[]')
{
$val=($inputObject.$prop|out-string).Trim()
}
elseif($thisProp -and $thisProp.GetType() -match 'Int|Boolean|Double')
{
$val=$thisProp
}
elseif($thisProp)
{
$val=($thisProp.ToString()).Trim()
}
else
{
$val=$null
}
$parsedObject.$prop=$val
}
return $parsedObject|%{New-Object PSObject -Property $_}
}
Get-ADForest|parseADObject|Export-Csv test.csv -NoTypeInformation;ii test.csv
Explanation, I'm gonna use ADForest for this example:
First you get the properties of the object you want to parse:
$adforest=Get-ADForest
PS C:\> $properties=($adforest|gm -MemberType Property).Name
PS C:\> $properties
ApplicationPartitions
CrossForestReferences
DomainNamingMaster
Domains
ForestMode
GlobalCatalogs
Name
PartitionsContainer
RootDomain
SchemaMaster
Sites
SPNSuffixes
UPNSuffixes
Then you loop on the properties of your object asking for the type of object:
PS C:\> foreach($prop in $properties){$adforest.$prop.gettype()}
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False ADPropertyValueCollection System.Collections.CollectionBase
True False ADPropertyValueCollection System.Collections.CollectionBase
True True String System.Object
True False ADPropertyValueCollection System.Collections.CollectionBase
True True ADForestMode System.Enum
True False ADPropertyValueCollection System.Collections.CollectionBase
True True String System.Object
True True String System.Object
True True String System.Object
True True String System.Object
True False ADPropertyValueCollection System.Collections.CollectionBase
True False ADPropertyValueCollection System.Collections.CollectionBase
True False ADPropertyValueCollection System.Collections.CollectionBase
And then you're just asking what type of object it is:
If the type matches 'Collection or []' then you're passing the value of that property to Out-String this is useful for properties like proxyAddresses on the AD Users.
ElseIf the type matches a Boolean or Integer or Double then you're leaving the value as is without any changes.
ElseIf the the property has any Value, meaning, is not $null, I'm using the ToString() method. This is useful for properties like ObjectGUID or ObjectSID
Notice I'm using Trim() each time I use Out-String or ToString() to eliminate any empty blank spaces at the beginning or the end
The value of each property loop, stored in the $val variable is then being added to the hashTable $parsedObject and then after looping is finished the variable is being converted to a PSObject (if you don't do this the export will not show as you expect it, it will show the type of the values instead of the actual data).

How retain NESTED JSON structure in PowerShell while using the ConverFrom-JSON and ConvertTo-Json cmdlets

I have a simple JSON:
{
"config": {
"option": {
"destination": ""
}
}
}
I read this JSON in PowerShell as
$flattended = Get-Content .\aboveJson.json | ConvertFrom-Json
I need to set the value of destination element to some value and then save it back to the same JSON or another JSON while retaining the structure. However, while reading the Nested object I see, PowerShell treated the option element differently and while saving with ConvertTo-Json, I see the output as "option": "#{destination=""}"
Could anyone please help and guide to any articles as to how PowerShell treats this data structure and what should be my way to handle the scenario ?
You shouldn't see this issue with your current example. However, the symptoms you see are due to the number of nested levels in your JSON structure. By default, the ConvertTo-Json command uses a default depth of 2. You can manually set this differently.
$flattened = Get-Content .\aboveJson.json | ConvertFrom-Json
$flattened.config.option.destination = 'new destination'
$flattened | ConvertTo-Json -Depth 10

List of users to match a list of job titles in AD

I have a list of Job titles in a csv file and need to match these to whichever user has the title in AD.
CSV Contents is like this:
JobTitle1
JobTitle2
JobTitle3
The following command will work to get a list of all users with the JobTitle1 title:
Get-ADUser -Filter "Title -like 'JobTitle1'"
However I can't get this to work with the CSV file as an array, it doesnt return any output:
$Titles = Get-Content -Path "c:\jobtitles.csv"
ForEach ($Title In $Titles)
{
Get-ADUser -Filter {Title -like '$Title'}
}
In PowerShell a variable within single quotes doesn't get populated so you have to use double quotes instead - or just omit them:
$Titles = Get-Content -Path "c:\jobtitles.csv"
ForEach ($Title In $Titles)
{
Get-ADUser -Filter {Title -like $Title}
}

Trying to add an object to an array of hashtables in powershell

If the answer is out there, I am not able to find it. I am trying to work with Json in powershell, and the target system is looking for an array of hashtables. Each hashtable has the item name as value. Here is how I am creating my array:
$json = #{
update = #{
customfield_11136 = #( #{ setty = #( #{ value="testValue" })})
}
}
The actual array is quite a bit larger, but this is the part I am working on at the moment. I am trying to add an additional value to $json.update.customfield_11136.setty.
Ultimately the output should look something like:
{
"update": {
"customfield_11136": [{
"set": [{
"value": "E0"
}, {
"value": "N0"
}, {
"value": "T0"
}]
}]
}
}
But I need to be able to add the additional values after initial creation.
I have tried every combination I could think of with .add() and +=, but I am not able to get anything to work. I believe this is a punctuation issue on my part, but I am fairly new to working with hashtable arrays, and have tried everything I can think of.
Appreciate any input.
Based on your example this works for me:
$json["update"]["customfield_11136"][0]["setty"] += #{"value"="E0"}
ConvertTo-Json -Depth 5 $json

Resources