的ConvertTo-PSON
function ConvertTo-PSON
{
<#
.SYNOPSIS
creates a powershell object-notation script that generates the same object data
.DESCRIPTION
This produces 'PSON', the powerShell-equivalent of JSON from any object you pass to it. It isn't suitable for the huge objects produced by some of the cmdlets such as Get-Process, but fine for simple objects
.EXAMPLE
[email protected]()
$array+=Get-Process wi* | Select-Object Handles,NPM,PM,WS,VM,CPU,Id,ProcessName
ConvertTo-PSON $array
.PARAMETER Object
the object that you want scripted out
.PARAMETER Depth
The depth that you want your object scripted to
.PARAMETER Nesting Level
internal use only. required for formatting
#>
[CmdletBinding()]
param (
[parameter(Position = 0, Mandatory = $true, ValueFromPipeline = $true)][AllowNull()] $inputObject,
[parameter(Position = 1, Mandatory = $false, ValueFromPipeline = $false)] [int] $depth = 16,
[parameter(Position = 2, Mandatory = $false, ValueFromPipeline = $false)] [int] $NestingLevel = 1,
[parameter(Position = 3, Mandatory = $false, ValueFromPipeline = $false)] [int] $XMLAsInnerXML = 0
)
BEGIN { }
PROCESS
{
If ($inputObject -eq $Null) { $p += '$Null'; return $p } # if it is null return null
$padding = [string]' ' * $NestingLevel # lets just create our left-padding for the block
$ArrayEnd=0; #until proven false
try
{
$Type = $inputObject.GetType().Name # we start by getting the object's type
if ($Type -ieq 'Object[]') { $Type = "$($inputObject.GetType().BaseType.Name)" } # see what it really is
if ($depth -ilt $NestingLevel) { $Type = 'OutOfDepth' } #report the leaves in terms of object type
elseif ($Type -ieq 'XmlDocument' -or $Type -ieq 'XmlElement')
{
if ($XMLAsInnerXML -ne 0) { $Type = 'InnerXML' }
else
{ $Type = 'XML' }
} # convert to PS Alias
# prevent these values being identified as an object
if (@('boolean', 'byte', 'char', 'datetime', 'decimal', 'double', 'float', 'single', 'guid', 'int', 'int32',
'int16', 'long', 'int64', 'OutOfDepth', 'RuntimeType', 'PSNoteProperty', 'regex', 'sbyte', 'string',
'timespan', 'uint16', 'uint32', 'uint64', 'uri', 'version', 'void', 'xml', 'datatable', 'List`1',
'SqlDataReader', 'datarow', 'ScriptBlock', 'type') -notcontains $type)
{
if ($Type -ieq 'OrderedDictionary') { $Type = 'HashTable' }
elseif ($Type -ieq 'PSCustomObject') { $Type = 'PSObject' } #
elseif ($inputObject -is "Array") { $Type = 'Array' } # whatever it thinks it is called
elseif ($inputObject -is "HashTable") { $Type = 'HashTable' } # for our purposes it is a hashtable
elseif (($inputObject | gm -membertype Properties | Select name | Where name -like 'Keys') -ne $null) { $Type = 'generic' } #use dot notation
elseif (($inputObject | gm -membertype Properties | Select name).count -gt 1) { $Type = 'Object' }
}
write-verbose "$($padding)Type:='$Type', Object type:=$($inputObject.GetType().Name), BaseName:=$($inputObject.GetType().BaseType.Name) $NestingLevel "
switch ($Type)
{
'ScriptBlock'{ "[$type] {$($inputObject.ToString())}" }
'InnerXML' { "[$type]@'`r`n" + ($inputObject.OuterXMl) + "`r`n'@`r`n" } # just use a 'here' string
'DateTime' { "[datetime]'$($inputObject.ToString('s'))'" } # s=SortableDateTimePattern (based on ISO 8601) local time
'Boolean' {
"[bool] $(&{
if ($inputObject -eq $true) { "`$True" }
Else { "`$False" }
})"
}
'string' {
if ($inputObject -match '[\r\n]') { "@'`r`n$inputObject`r`n'@" }
else { "'$($inputObject -replace '''', '''''')'" }
}
'Char' { [int]$inputObject }
{ @('byte', 'decimal', 'double', 'float', 'single', 'int', 'int32', 'int16', 'long', 'int64', 'sbyte', 'uint16', 'uint32', 'uint64') -contains $_ }
{ "$inputObject" } # rendered as is without single quotes
'PSNoteProperty' { "$(ConvertTo-PSON -inputObject $inputObject.Value -depth $depth -NestingLevel ($NestingLevel))" }
'Array' { "`r`[email protected](" + ("$($inputObject | ForEach {$ArrayEnd=1; ",$(ConvertTo-PSON -inputObject $_ -depth $depth -NestingLevel ($NestingLevel + 1))" })".Substring($ArrayEnd)) + "`r`n$padding)" }
'HashTable' { "`r`[email protected]{" + ("$($inputObject.GetEnumerator() | ForEach {$ArrayEnd=1; "; '$($_.Name)' = " + (ConvertTo-PSON -inputObject $_.Value -depth $depth -NestingLevel ($NestingLevel + 1)) })".Substring($ArrayEnd) + "`r`n$padding}") }
'PSObject' { "`r`n$padding[pscustomobject]@{" + ("$($inputObject.PSObject.Properties | ForEach {$ArrayEnd=1; "; '$($_.Name)' = " + (ConvertTo-PSON -inputObject $_ -depth $depth -NestingLevel ($NestingLevel + 1)) })".Substring($ArrayEnd) + "`r`n$padding}") }
'Dictionary' { "`r`[email protected]{" + ($inputObject.item | ForEach {$ArrayEnd=1; '; ' + "'$_'" + " = " + (ConvertTo-PSON -inputObject $inputObject.Value[$_] -depth $depth -NestingLevel $NestingLevel+1) }) + '}' }
'Generic' { "`r`[email protected]{" + ("$($inputObject.Keys | ForEach {$ArrayEnd=1; "; $_ = $(ConvertTo-PSON -inputObject $inputObject.$_ -depth $depth -NestingLevel ($NestingLevel + 1))" })".Substring($ArrayEnd) + "`r`n$padding}") }
'Object' { "`r`[email protected]{" + ("$($inputObject | Get-Member -membertype properties | Select-Object name | ForEach {$ArrayEnd=1; "; $($_.name) = $(ConvertTo-PSON -inputObject $inputObject.$($_.name) -depth $NestingLevel -NestingLevel ($NestingLevel + 1))" })".Substring($ArrayEnd) + "`r`n$padding}") }
'XML' { "`r`[email protected]{" + ("$($inputObject | Get-Member -membertype properties | where name -ne 'schema' | Select-Object name | ForEach {$ArrayEnd=1; "; $($_.name) = $(ConvertTo-PSON -inputObject $inputObject.$($_.name) -depth $depth -NestingLevel ($NestingLevel + 1))" })".Substring($ArrayEnd) + "`r`n$padding}") }
'Datatable' { "`r`[email protected]{" + ("$($inputObject.TableName)=`r`n$padding @(" + "$($inputObject | ForEach {$ArrayEnd=1; ",$(ConvertTo-PSON -inputObject $_ -depth $depth -NestingLevel ($NestingLevel + 1))" })".Substring($ArrayEnd) + "`r`n$padding )`r`n$padding}") }
'DataRow' { "`r`[email protected]{" + ("$($inputObject | Get-Member -membertype properties | Select-Object name | ForEach {$ArrayEnd=1; "; $($_.name)= $(ConvertTo-PSON -inputObject $inputObject.$($_.name) -depth $depth -NestingLevel ($NestingLevel + 1))" })".Substring($ArrayEnd) + "}") }
default { "'$inputObject'" }
}
}
catch
{
write-error "Error'$($_)' in script $($_.InvocationInfo.ScriptName) $($_.InvocationInfo.Line.Trim()) (line $($_.InvocationInfo.ScriptLineNumber)) char $($_.InvocationInfo.OffsetInLine) executing $($_.InvocationInfo.MyCommand) on $type object '$($inputObject.Name)' Class: $($inputObject.GetType().Name) BaseClass: $($inputObject.GetType().BaseType.Name) "
}
finally { }
}
END { }
}
的ConvertTo-YAML
function ConvertTo-YAML
{
<#
.SYNOPSIS
creates a YAML description of the data in the object
.DESCRIPTION
This produces YAML from any object you pass to it. It isn't suitable for the huge objects produced by some of the cmdlets such as Get-Process, but fine for simple objects
.EXAMPLE
[email protected]()
$array+=Get-Process wi* | Select-Object Handles,NPM,PM,WS,VM,CPU,Id,ProcessName
ConvertTo-YAML $array
.PARAMETER Object
the object that you want scripted out
.PARAMETER Depth
The depth that you want your object scripted to
.PARAMETER Nesting Level
internal use only. required for formatting
#>
[CmdletBinding()]
param (
[parameter(Position = 0, Mandatory = $true, ValueFromPipeline = $true)][AllowNull()] $inputObject,
[parameter(Position = 1, Mandatory = $false, ValueFromPipeline = $false)] [int] $depth = 16,
[parameter(Position = 2, Mandatory = $false, ValueFromPipeline = $false)] [int] $NestingLevel = 0,
[parameter(Position = 3, Mandatory = $false, ValueFromPipeline = $false)] [int] $XMLAsInnerXML = 0
)
BEGIN { }
PROCESS
{
If ($inputObject -eq $Null) { $p += 'null'; return $p } # if it is null return null
if ($NestingLevel -eq 0) { '---' }
$padding = [string]' ' * $NestingLevel # lets just create our left-padding for the block
try
{
$Type = $inputObject.GetType().Name # we start by getting the object's type
if ($Type -ieq 'Object[]') { $Type = "$($inputObject.GetType().BaseType.Name)" } #what it really is
if ($depth -ilt $NestingLevel) { $Type = 'OutOfDepth' } #report the leaves in terms of object type
elseif ($Type -ieq 'XmlDocument' -or $Type -ieq 'XmlElement')
{
if ($XMLAsInnerXML -ne 0) { $Type = 'InnerXML' }
else
{ $Type = 'XML' }
} # convert to PS Alias
# prevent these values being identified as an object
if (@('boolean', 'byte', 'char', 'datetime', 'decimal', 'double', 'float', 'single', 'guid', 'int', 'int32',
'int16', 'long', 'int64', 'OutOfDepth', 'RuntimeType', 'PSNoteProperty', 'regex', 'sbyte', 'string',
'timespan', 'uint16', 'uint32', 'uint64', 'uri', 'version', 'void', 'xml', 'datatable', 'List`1',
'SqlDataReader', 'datarow', 'ScriptBlock', 'type') -notcontains $type)
{
if ($Type -ieq 'OrderedDictionary') { $Type = 'HashTable' }
elseif ($Type -ieq 'PSCustomObject') { $Type = 'PSObject' } #
elseif ($inputObject -is "Array") { $Type = 'Array' } # whatever it thinks it is called
elseif ($inputObject -is "HashTable") { $Type = 'HashTable' } # for our purposes it is a hashtable
elseif (($inputObject | gm -membertype Properties |
Select name | Where name -like 'Keys') -ne $null) { $Type = 'generic' } #use dot notation
elseif (($inputObject | gm -membertype Properties | Select name).count -gt 1) { $Type = 'Object' }
}
write-verbose "$($padding)Type:='$Type', Object type:=$($inputObject.GetType().Name), BaseName:=$($inputObject.GetType().BaseType.Name) "
switch ($Type)
{
'ScriptBlock'{ "{$($inputObject.ToString())}" }
'InnerXML' { "|`r`n" + ($inputObject.OuterXMl.Split("`r`n") | foreach{ "$padding$_`r`n" }) }
'DateTime' { $inputObject.ToString('s') } # s=SortableDateTimePattern (based on ISO 8601) using local time
'Boolean' {
"$(&{
if ($inputObject -eq $true) { '`true' }
Else { '`false' }
})"
}
'string' {
$String = "$inputObject"
if ($string -match '[\r\n]' -or $string.Length -gt 80)
{
# right, we have to format it to YAML spec.
">`r`n" # signal that we are going to use the readable 'newlines-folded' format
$string.Split("`n") | foreach {
$bits = @(); $length = $_.Length; $IndexIntoString = 0; $wrap = 80
while ($length -gt $IndexIntoString + $Wrap)
{
$earliest = $_.Substring($IndexIntoString, $wrap).LastIndexOf(' ')
$latest = $_.Substring($IndexIntoString + $wrap).IndexOf(' ')
$BreakPoint = &{
if ($earliest -gt ($wrap + $latest)) { $earliest }
else { $wrap + $latest }
}
if ($earliest -lt (($BreakPoint * 10)/100)) { $BreakPoint = $wrap } # in case it is a string without spaces
$padding + $_.Substring($IndexIntoString, $BreakPoint).Trim() + "`r`n"
$IndexIntoString += $BreakPoint
}
if ($IndexIntoString -lt $length) { $padding + $_.Substring($IndexIntoString).Trim() + "`r`n" }
else { "`r`n" }
}
}
else { "'$($string -replace '''', '''''')'" }
}
'Char' { "([int]$inputObject)" }
{
@('byte', 'decimal', 'double', 'float', 'single', 'int', 'int32', 'int16', `
'long', 'int64', 'sbyte', 'uint16', 'uint32', 'uint64') -contains $_
}
{ "$inputObject" } # rendered as is without single quotes
'PSNoteProperty' { "$(ConvertTo-YAML -inputObject $inputObject.Value -depth $depth -NestingLevel ($NestingLevel + 1))" }
'Array' { "$($inputObject | ForEach { "`r`n$padding- $(ConvertTo-YAML -inputObject $_ -depth $depth -NestingLevel ($NestingLevel + 1))" })" }
'HashTable'{
("$($inputObject.GetEnumerator() | ForEach {
"`r`n$padding $($_.Name): " +
(ConvertTo-YAML -inputObject $_.Value -depth $depth -NestingLevel ($NestingLevel + 1))
})")
}
'PSObject' { ("$($inputObject.PSObject.Properties | ForEach { "`r`n$padding $($_.Name): " + (ConvertTo-YAML -inputObject $_ -depth $depth -NestingLevel ($NestingLevel + 1)) })") }
'generic' { "$($inputObject.Keys | ForEach { "`r`n$padding $($_): $(ConvertTo-YAML -inputObject $inputObject.$_ -depth $depth -NestingLevel ($NestingLevel + 1))" })" }
'Object' { ("$($inputObject | Get-Member -membertype properties | Select-Object name | ForEach { "`r`n$padding $($_.name): $(ConvertTo-YAML -inputObject $inputObject.$($_.name) -depth $NestingLevel -NestingLevel ($NestingLevel + 1))" })") }
'XML' { ("$($inputObject | Get-Member -membertype properties | where-object { @('xml', 'schema') -notcontains $_.name } | Select-Object name | ForEach { "`r`n$padding $($_.name): $(ConvertTo-YAML -inputObject $inputObject.$($_.name) -depth $depth -NestingLevel ($NestingLevel + 1))" })") }
'DataRow' { ("$($inputObject | Get-Member -membertype properties | Select-Object name | ForEach { "`r`n$padding $($_.name): $(ConvertTo-YAML -inputObject $inputObject.$($_.name) -depth $depth -NestingLevel ($NestingLevel + 1))" })") }
# 'SqlDataReader'{$all = $inputObject.FieldCount; while ($inputObject.Read()) {for ($i = 0; $i -lt $all; $i++) {"`r`n$padding $($Reader.GetName($i)): $(ConvertTo-YAML -inputObject $($Reader.GetValue($i)) -depth $depth -NestingLevel ($NestingLevel+1))"}}
default { "'$inputObject'" }
}
}
catch
{
write-error "Error'$($_)' in script $($_.InvocationInfo.ScriptName) $($_.InvocationInfo.Line.Trim()) (line $($_.InvocationInfo.ScriptLineNumber)) char $($_.InvocationInfo.OffsetInLine) executing $($_.InvocationInfo.MyCommand) on $type object '$($inputObject)' Class: $($inputObject.GetType().Name) BaseClass: $($inputObject.GetType().BaseType.Name) "
}
finally { }
}
END { }
}
'stdout'不会成为它的对象的格式化版本。转换为JSON可能会为您提供更有用的JavaScript格式(我假设您可以解析它)。你这样做'Get-Process -Name WmiPrvSE | ConvertTo-Json -Depth 2'。所以你只能得到JSON,当你调用'powershell.exe','-NoLogo'时,你需要添加下面的开关。尽量保持深度尽可能浅。过程对象具有许多丰富的属性。如果您将其中的很多事件序列化为事件深度2,则需要一些时间。 – TravisEz13
听起来不错,它回答了问题的一部分。我如何解析它在Javascript中获取对象并在HTML中设置它们的格式?我试过'JSON.parse(child)',但是这给了我一个错误。 – 30000MONKEYS