Accessing values in an object resulting of a parsed JSON - object

Have a look to the following JSON (too big to fit here), I'am not able to get value using
[System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions")
$ser = New-Object System.Web.Script.Serialization.JavaScriptSerializer
$jsonObj = $ser.DeserializeObject($json)
$jsonObj.servers | Where-Object {$_.name -EQ 'Tendaji'} | `
select-object { $_.ipv4addr }
I receive
$_.ipv4Address
--------------
113.55.212.113
How would I get it to only just return 113.55.212.113?

Have a look to :
$_.ipv4Address | get-member
Get-Member -InputObject $_.ipv4Address
You may have an array
$_.ipv4Address[0]
Be carreful you've got an error inside your JSON :
"name": "Aboubacar""ipv4addr": "143.179.56.126"
should be :
"name": "Aboubacar",
"ipv4addr": "143.179.56.126"
Then
$jsonObj.servers[0].ipv4addr
gives
113.55.212.113
So in your code your can use :
($jsonObj.servers | Where-Object {$_.name -EQ 'Tendaji'}).ipv4addr

Related

Change output results in PowerShell

I want to get all user ID's with a specific token assigned.
It looks like this now when I run my script..
Get-ADUser -Filter * -Properties * | Select-Object vasco-LinkUserToDPToken, displayname
#Output#
vasco-LinkUserToDPToken Displayname
{CN=VES0423061,OU=br... User X
{} User X
{} User X
{CN=0067511310,OU=br... User X
{CN=0067077717,OU=br... User X
Example of a full vasco-LinkUserToDPToken :
{CN=VES0976944,OU=Internal Users,DC=mgm,DC=agf,DC=be}
the thing is I only want to filter VES + it should be shown like this (not containing empty strings or tokens that are not starting with VES):
VES0423061 User X
It looks like your property 'vasco-LinkUserToDPToken' is a multivalued property type (string array) of which you need to extract the DN inside.
You could try:
Get-ADUser -Filter "vasco-LinkUserToDPToken -like 'CN=VES*'" -Properties 'vasco-LinkUserToDPToken', DisplayName |
Select-Object #{Name = 'vasco-LinkUserToDPToken'; Expression = {
($_.'vasco-LinkUserToDPToken' | Where-Object {$_ -match '^CN=VES.*'}) -replace '.*(VES[^,]+).*', '$1'}
}, DisplayName
P.S. It is always a bad idea to use -Properties * is what you are after is just two properties. Using * forces to pull down ALL properties which is a waste of time
If the -Filter doesn't work on this custom property, you can always use a Where-Object clause afterwards like:
Get-ADUser -Filter * -Properties 'vasco-LinkUserToDPToken', DisplayName |
Where-Object { $_.'vasco-LinkUserToDPToken' -like 'CN=VES*' } |
Select-Object #{Name = 'vasco-LinkUserToDPToken'; Expression = {
($_.'vasco-LinkUserToDPToken' | Where-Object {$_ -match '^CN=VES.*'}) -replace '.*(VES[^,]+).*', '$1'}
}, DisplayName

Powershell excel header sorting by alphabet

I have the following code to get the headers in an excel
$inputTable = Import-Excel -Path $inputFile
$sourceTable = $inputTable | Get-Member -MemberType NoteProperty | %{"$($_.Name)"}
However it is sorting by alphabet. I want the headers in the same sequence as in the excel. How should I do it?
try this :
$inputTable | get-Member -force | where Name -eq "psextended" | %{
$_.Definition.replace('psextended', '').replace('{', '').replace('}', '').Trim() -split ',' | %{$_.trim()}
}

Powershell odd behaviour when outputting to csv

I'm having a problem when outputting my foreach loop to a csv file.
My Groups are set like this:
$Groups = "Group1", "Group2", "Group3"
My code is:
$results = ForEach ($Group in $Groups) {
$memberof = get-adgroup $Group | select -expandproperty distinguishedname
Write-Output $Group
Get-ADObject -Filter 'memberof -eq $memberof -and (ObjectClass -eq "user" -or ObjectClass -eq "contact")' -properties * | select name, Objectclass, mail
Write-Output ""
Write-Output ""
}
$results | Export-csv Contacts.csv -NoTypeInformation
The problem seems to be coming from the Write-Output lines but I have no clue why. When I run my code without writing to a csv file, I get the expected result, something like:
NameOfGroup1
name Objectclass mail
---- ----------- ----
User1 user User1#mail.com
User2 user User2#mail.com
#Spaces caused by write-output ""
NameOfGroup2
User1 user User1#mail.com
Contact1 contact Contact1#externalmail.com
Then again when I run my code to write to csv file and have the write-output $Group commented out I get a similar result.
But if I run my full code from the top of this page including the write-output $Group, it comes out like this:
I've figured out what these results represent but I haven't got clue why they do print out like this.
Eseentially the numbers refer to the length of the group name, so the first 17 would be a 17 character group name, and then the number of lines below is equal to the number of contacts and users that are inside that group. The 2 zeros at the end of each group are the length of the write-output "" lines.
What is causing this behavior?
The following code will closely output what you are attempting.
$results = ForEach ($Group in $Groups) {
$memberof = get-adgroup $Group | select -expandproperty distinguishedname
Get-ADUser -Filter "memberof -eq '$memberof' -and (ObjectClass -eq 'user' -or ObjectClass -eq 'contact')" -properties name,ObjectClass,Mail | Select-Object #{n='Group';e={$Group}},name, Objectclass, mail
[pscustomobject]"" | Select-Object Group,Name,ObjectClass,Mail
[pscustomobject]"" | Select-Object Group,Name,ObjectClass,Mail
}
$results | Export-csv Contacts.csv -NoTypeInformation
Explanation:
Export-Csv converts an object or array of objects with properties into a CSV file. You can see the same result in the console with ConvertTo-Csv. Properties are converted into columns and property values are placed under their associated columns. When you output a string as in Write-Output $Group, it has a property of Length. To fix this, you need to add $Group as a calculated property in your Select-Object. If you want to do blank lines in your CSV, then you should output another object with all of the property values as ''.
When you mix objects in your PowerShell outputs, you can see unexpected results. Your Get-ADObject outputs a custom object. Your Write-Output lines output a string. Those two object types do not share properties. So you only see the properties for the first object in your array, which is a string. If you put all of the Write-Output statements at the end of your loop, you will see more properties in your CSV. See below for an example that just by reversing the order of processed objects, you get a different result.
$str = "string"
$obj = [pscustomobject]#{property1 = "value1"; property2 = "value2"}
$str,$obj | convertto-csv -notype
"Length"
"6"
$obj,$str | convertto-csv -notype
"property1","property2"
"value1","value2"
,
Notice the properties available to the custom object $obj and the string $str.
$obj | get-member -Type Properties
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
property1 NoteProperty string property1=value1
property2 NoteProperty string property2=value2
$str | get-member -Type Properties
TypeName: System.String
Name MemberType Definition
---- ---------- ----------
Length Property int Length {get;}

String manipulation on each noteproperty value

tried many different methods of trying to get this working. The is the closest non-working example i can come up with.
I want to get rid of NoteProperty items with a null value, if i also want to get rid of $ and ; characters from any NoteProperty value in an object while leaving the rest of the value behind could someone please advise me what is wrong with the following code example?
$JournalObject | Get-Member -MemberType NoteProperty | ForEach-Object {
if ($JournalObject.$_.Value -like ';')
{
$JournalObject.$_.Value.Replace(';', '')
}
if ($JournalObject.$_.Value -like '$')
{
$JournalObject.$_.Value.Replace('$', '')
}
if ($JournalObject.$_.Value -eq $null)
{
$JournalObject.PSObject.Properties.Remove($_)
}
}
Kindest regards !!
hoping for your help :)
Something to also note; if you are running a replace that's getting it's object from Get-Member, you aren't touching the original object to begin with.
You can see this for yourself by running another Get-Member where your ForEach-Object is to see what's being passed through the pipeline (spoiler, it's Microsoft.PowerShell.Commands.MemberDefinition)
You can also see this a little better by running it against a string with 1 Get-Member piped then comparing it with a second Get-Member piped:
"asfdasf" | Get-Member (this will return the expected String type)
VS
"asfdasf" | Get-Member | Get-Member (this will comeback as a MemberDefinition object, since you're literally getting the members of the Get-Member result)
Working on a better approach, will update this answer shortly.
This is what I came up with. First you need to prune out the the properties you aren't returning so that you aren't loop in on members that will no longer exist, by finding those members then excluding with select-object.
Then you can loop through and fix the values.
$members = $JournalObject | Get-Member -MemberType NoteProperty | select -expandproperty name
$removelist = $JournalObject | % {
foreach ($member in $members) {
if ($_.$member -eq $null) {
$member
}
}
}
$uremovelist = $removelist | select -unique
$prunedJournalObject = $JournalObject | select * -ExcludeProperty $uremovelist
$members = $prunedJournalObject | Get-Member -MemberType NoteProperty | select -expandproperty
$prunedJournalObject | % {
foreach ($member in $members) {
if ($_.$member -match ';') {
$_.$member = $_.$member.Replace(';', '')
}
if ($_.$member -match '$') {
$_.$member = $_.$member.Replace('$', '')
}
}
$_
}

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