Get a list of all xml attributes - powershell

I'm making an API call that returns the value in System.Xml.XmlElement,
but it looks like this:
id : 5847538497
ipAddress : 192.168.110.1
status : RUNNING
upgradeStatus : UPGRADED
upgradeAvailable : false
Saving this in a local variable myData. How can I print all the attributes of this returned XML?
It works if I type:
> Write-Host myData.id
> Write-Host myData.status
but I don't know all the attributes as api call is dynamic and returns different attributes.

Take a look at the Attributes property on the XmlElement object in question:
$myData.Attributes |ForEach-Object {
'Name: {0}; Value: {1}' -f $_.LocalName,$_.Value
}

Take a look at the Format-List and the Get-Member cmdlet:
myData | Format-List * -force
myData | Get-Member

Related

How to access properties of Get-Child Registry output

Using the below code, I get Name & LastLogon populated, but not ProfilePath.
Add-RegKeyMember is https://gallery.technet.microsoft.com/scriptcenter/Get-Last-Write-Time-and-06dcf3fb .
I have tried to access ProfileImagePath with $Profile.Properties.ProfileImagePath, $Profile.Name.ProfileImagePath, and others, but they all return blank (could be null). How on earth is this seemingly object making these properties available?
$Profiles = get-childitem "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" | Add-RegKeyMember
foreach($Profile in $Profiles)
{
$ThisProfileInfo = #{Name=$Profile.Name;
LastLogon=$Profile.LastWriteTime;
ProfilePath=$Profile.ProfileImagePath}
$Profile
}
Name Property
---- --------
S-1-5-18 Flags : 12
ProfileImagePath : C:\WINDOWS\system32\config\systemprofile
RefCount : 1
Sid : {1, 1, 0, 0...}
State : 0
This is because [Microsoft.Win32.RegistryKey] object returns properties as string array. You should simply retrieve the value ProfileImagePath from the object itself :
ProfilePath=$Profile.GetValue("ProfileImagePath")
Please see the below adjustments to your script.
You can pull the sub values of property by using the method GetValue.
I have also adjusted how you are storing each iteration and outputting the value post the foreach loop as the example above will just output each $profile as it was before the loop.
I have not tested with Add-RegKeyMember and therefore I am unable to confirm if this will pull the LastWriteTime property, but I can confirm that this will pull the profileimagepath property.
$Profiles = get-childitem "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" | Add-RegKeyMember
$ProfileData = #()
foreach($Profile in $Profiles){
$ThisProfileInfo = $null
$ThisProfileInfo = #{Name=$Profile.Name;
LastLogon=$Profile.GetValue("LastWriteTime");
ProfilePath=$Profile.GetValue("ProfileImagePath")}
$ProfileData += $ThisProfileInfo
}
$ProfileData

Powershell export nested object arrays into CSV

When i look into my object arra and type a $obj[2] (as exam) I'm getting
Name : audit_event
UUID : c6479a6f-f1bd-4759-9881-fcb493821aff
Timestamp : 17-06-20 13:30:48 +00:00
Fields : {[audit_schema_version, 1], [event_time, 17-06-20 13:30:48 +00:00], [sequence_number, 1], [action_id, 541934402]...}
Actions : {}
I would like to get all fields into a single csv file.
So first I started to find at least the fields, but dispite some solutions I saw i'm not getting it OK.
foreach ($UUID in $logsOBJECT[2].UUID) {
echo $UUID
foreach ($field in $logsOBJECT.$UUID.Keys) {
echo $field
}
}
This doesn't work.
I'm not a Powershell developer so quite novice.
I have to use Powershell because Synaps Analytics doesn't give a better option to read and process its logfiles.
Kind regards, Harry
Given an object that looks like this in JSON:
[{
"Name": "audit_event",
"UUID": "c6479a6f-f1bd-4759-9881-fcb493821aff",
"Timestamp": "17-06-20 13:30:48 +00:00",
"Fields": [["audit_schema_version", 1], ["event_time", "17-06-20 13:30:48 +00:00"], ["sequence_number", 1], ["action_id", 541934402]],
"Actions": {}
}]
(You can generate that by using $obj | ConvertTo-Json so it's easier for others to reproduce)
First we loop through the $obj list by passing it to ForEach-Object, or % for short. For each element we create a $result object that contains all the data, except the Fields property.
Then we loop through the fields property on the object. Each field is itself a list, where the first (0) element is the name, and the second (1) is the value. For each field, we add a property to the $result object with the name and value of the field.
When this is done we return the $result object to the pipeline, and that gets passed to Export-Csv which writes it to a file.
$obj | % {
$result = $_ | Select-Object * -ExcludeProperty Fields
$_.Fields | % {
$result | Add-Member -Name $_[0] -Value $_[1] -MemberType NoteProperty
}
return $result
} | Export-Csv -Path C:\test.csv -Encoding UTF8 -NoTypeInformation
I don't have your exact PS module of SynapsAnalystics...
But it seems to be a problem accessing nested arrays in Powershell.
Here I have an example with Windows services:
PS C:\WINDOWS\system32> $servic[20] | fl
Name : BrokerInfrastructure
DisplayName : Background Tasks Infrastructure Service
Status : Running
DependentServices : {workfolderssvc, WMPNetworkSvc, WSearch, embeddedmode}
ServicesDependedOn : {DcomLaunch, RpcSs, RpcEptMapper}
CanPauseAndContinue : False
CanShutdown : False
CanStop : False
ServiceType : Win32ShareProcess
Here, if I want the output of $servic.DependentServices I need to know the Keys\Propertys of $servic.DependentServices. ie,
You can get that by :
PS C:\WINDOWS\system32> $servic[20].DependentServices
Status Name DisplayName
------ ---- -----------
Stopped workfolderssvc Work Folders
Running WMPNetworkSvc Windows Media Player Network Sharin...
Running WSearch Windows Search
Stopped embeddedmode Embedded Mode
So the Propertys here are
Status Name DisplayName etc...
$servic[20].DependentServices would be similar to $obj[2].Fields in your case.
Try and see the Keys or Property's within $obj[2].Fields then decide which Property you want to loop through.
you can get that with
$obj[2].Fields | get-Module (this will give all parameters)
Then you can loop through the required Properties, like in my case:
foreach ($echserv in $servic[0-2])
{
write-host "*****************Service******************"
echo $echserv.Name
Write-Host "####DependentServices####"
foreach ($echDependServic in $servic.DependentServices.DisplayName)
{
echo $echDependServic
}
}
which would give output:
*****************Service******************
XboxGipSvc
####DependentServices####
Smartlocker Filter Driver
Agent Activation Runtime_ea2d3
Agent Activation Runtime
Windows Audio
Agent Activation Runtime_ea2d3
Agent Activation Runtime
Xbox Live Networking Service
.
.
.
Hope this helps with your problem.
PS: There are better ways to display your output using hashtables in Powershell. This can later be used to export to CSV etc..

In PowerShell, How I do I filter for an object by its nested property key/value object?

An object returned from a get-log command can look like
Date: <date>
Properties:
statusCode : OK
serviceRequestId: 97168d7a-4c92-4d65-b509-65785b14ef42
Name: <name>
Details: <details>
I want to do something that returns that the one object by doing something like
get-log | where-object { $_.Properties.serviceRequestId -eq '97168d7a-4c92-4d65-b509-65785b14ef42' }
Of course, this does not work, but I want something that works like this.
My goal is to see the "Details" property.
The filtering sample you provided works as is:
get-log | where-object { $_.Properties.serviceRequestId -eq '97168d7a-4c92-4d65-b509-65785b14ef42' }
That will return the object(s) you want (the full object, not just inner properties).
So you can use the result of that to get at any other property, like Details:
$result = get-log | where-object { $_.Properties.serviceRequestId -eq '97168d7a-4c92-4d65-b509-65785b14ef42' }
$result.Details
Or you can do it all in one line by continuing the pipeline and using Select-Object:
get-log |
where-object {
$_.Properties.serviceRequestId -eq '97168d7a-4c92-4d65-b509-65785b14ef42'
} |
Select-Object -ExpandProperty Details
(did it on multiple lines for better readability)

PowerShell: ConvertFrom-Json to export multiple objects to csv

As you probably understand from the title, I'm new to PowerShell, having a hard time even trying to describe my question. So please forgive my terminology.
Scenario
I am using PowerShell to query the audit log of Office 365. The cmdlet Search-UnifiedAuditLog returns "multiple sets of objects"(?), one of which has an array of other objects(?). The output is JSON if I got this right.
Here is an example of what is returned (I will call it one "Set of Objects"):
RunspaceId : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
RecordType : AzureActiveDirectoryStsLogon
CreationDate : 21/02/2017 12:05:23
UserIds : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Operations : UserLoggedIn
AuditData : {"CreationTime":"2017-02-21T12:05:23","Id":"{"ID":"00000000000000000","Type":3}],"ActorContextId":"xxxxxxxxxxxxxxxxxxxxxxxxx","ActorIpAddress":"xxxxxxxxxxxxx","InterSystemsId":"xxxxxxxxxxxxxxxxx","IntraSystemId":"000000000000-000000-000","Target":[{"ID":"00-0000-0000-c000-000000000000","Type":0}],"TargetContextId":"xxxxxxxxxxxxxxxxxx","ApplicationId":"xxxxxxxxxxxxxxxxxxxxxxxxxx"}
ResultIndex : 1
ResultCount : 16
Identity : xxxxxxxxxxxxxxxxxxxxxxxxxxx
IsValid : True
ObjectState : Unchanged
Now, I want some of the content of the AuditData line exported to a csv (normally containing much more data than copied here). This works fine for one "set of objects" (like the one above). To do this I use:
$LogOutput = Search-UnifiedAuditLog -StartDate 2/20/2017 -EndDate 2/23/2017 -ResultSize 1
$ConvertedOutput = ConvertFrom-Json -InputObject $LogOutput.AuditData
$ConvertedOutput | Select-Object CreationTime,UserId,ClientIP | Export-Csv -Path "C:\users\some.user\desktop\users.csv
ResultSize returns 1 instead of multiple "sets of objects". The ConvertFrom-Json does not work if I remove ResultSize.
So the question is:
Can I loop through all the "set of objects" and convert from json and have this exported line-by-line on a csv? Resulting in something like this:
UserId,Activity,UserIP
this#user.com, loggedIn, 10.10.10.10
that#user.org, accessedFile, 11.11.11.11
A pedagogic answer would be very, very much appreciated. Many thanks!
Instead of -ResultSize, try using Search-UnifiedAuditLog <args> | Select-Object -ExpandProperty AuditData | ConvertFrom-Json
This will make only the AuditData property get forwarded into ConvertFrom-Json and ignore the rest of the object from Search-UnifiedAuditLog

How do I retrieve the key value pairs from Get-AzureRmResourceGroup Tags

I have a resource group that is scheduled using a tag that has the key value pair: "IncludeInSchedule":"true"
When I do Get-AzureRmResourceGroup -Name MyResourceGroup I see:
ResourceGroupName : MyResourceGroup
Location : northcentralus
ProvisioningState : Succeeded
Tags :
Name Value
================= ======
IncludeInSchedule True
ResourceId : /subscriptions/ea904806-082f-4ce5-9b66-288afd61f83e/resourceGroups/MyResourceGroup
When I attempt to read the value in the tag into a variable I'm coming unstuck. It looks like a hashtable, but Get-AzureRmResourceGroup -Name MyResourceGroup | Get-Member Tags suggests it's an Array of Hashtable, am I reading that right?
Name MemberType Definition
---- ---------- ----------
Tags Property hashtable[] Tags {get;set;}
If I pipe the output from Get-AzureRmResourceGroup into Select-Object and expand the tags property I get:
Name Value
===== =====
Value True
Name IncludeInSchedule
This is not what I expected to see, what I expected to see was:
IncludeInSchedule True
Furthermore, when I attempt to assign the tags to a variable so I can extract the IncludeInSchedule value, I'm not seeing any values.
How do I extract the value from this?
According to Microsoft's official documentation: Displaying Hash Tables
The following should work:
> (Get-AzureRmResourceGroup -Name MyResourceGroup).Tags.Value
True
You can get all tags' keys via:
> (Get-AzureRmResourceGroup -Name MyResourceGroup).Tags.Keys
Value
Name
For example, I am using this way to access uptimes for VMs like this:
> $vm = Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName
> $vm.Tags.UptimeMonday
24h
In case you have any naming collisions with Microsoft's naming, they further state:
If the key name collides with one of the property names of the HashTable type, you can use PSBase to access those properties. For example, if the key name is keys and you want to return the collection of Keys, use this syntax
$hashtable.PSBase.Keys
Yes, Tags is an array of hashtables as defined by hashtable[] (notice square brackets).
Each object in the array is an hashtable like:
$t = #{ Name = "IncludeInSchedule"; Value = "True" }
$t
Name Value
---- -----
Value True
Name IncludeInSchedule
To access this from your objects, use:
$IncludeInSchedule = ((Get-AzureRmResourceGroup -Name MyResourceGroup).Tags | Where-Object { $_.Name -eq 'IncludeInSchedule'}).Value
#Or
$IncludeInSchedule = (Get-AzureRmResourceGroup -Name MyResourceGroup).Tags | Where-Object { $_.Name -eq 'IncludeInSchedule'} | ForEach-Object { $_.Value }
Output:
PS C:\Users\frode> $IncludeInSchedule
True