2016-12-27 5 views
0

Powershellスクリプトを呼び出すElectronで小さなツールを作成しようとしています。PowershellオブジェクトをNode.JS/Electronに渡してHTMLタグでラップします

私はこのスレッドから私のスクリプトにPowerShellの出力を取得する方法を知っている:

https://stackoverflow.com/a/10181488/3161671

だから私はしかし、私はかなりオブジェクトのメンバを呼び出す方法

<script> 
    var spawn = require("child_process").spawn,child; 
    child = spawn("powershell.exe",["C:\\PowershellScript\\get-process.ps1"]); 
    child.stdout.on("data",function(data){ 
     console.log("Powershell Data: " + data); 
    }); 
    child.stderr.on("data",function(data){ 
     console.log("Powershell Errors: " + data); 
    }); 
    child.on("exit",function(){ 
     console.log("Powershell Script finished"); 
    }); 
    child.stdin.end(); //end input 
</script> 

を理解していないしています私のPS出力から(child.stdout.ProcessNameなど)

私は出力をループして、テーブル(これが妥当な場合):

<table> 
    <tr> 
    <th>CPU(s)</th> 
    <th>Id</th> 
    <th>ProcessName</th> 
    </tr> 
    <tr> 
    <td>0,35</td> 
    <td>1824</td> 
    <td>conhost</td> 
    </tr> 
    <tr> 
    <td>1.725</td> 
    <td>3115</td> 
    <td>firefox</td> 
    </tr> 
</table> 

これを達成する最もクリーンな方法は何ですか? PowershellスクリプトにHTMLタグを埋め込んでいる人がいましたが、Object-to-HTMLと書式設定にJavaScriptを使用する方が合理的だと思います。

+0

'stdout'はオブジェクトのフォーマットされたバージョンになることはありません。 JSONに変換すると、JavaScriptのためのより使いやすいフォーマットが得られるかもしれません(私はあなたがそれを解析できると仮定します)。あなたはこれを 'Get-Process -Name WmiPrvSE | ConvertTo-Json -Depth 2'のようになります。 JSONのみを取得するには、 'powershell.exe'、' -NoLogo'を呼び出すときに以下のスイッチを追加する必要があります。できるだけ浅く深度を保つようにしてください。プロセスオブジェクトには多くの豊富なプロパティがあります。イベント深度2でそれらの多くをシリアライズしている場合は、時間がかかります。 – TravisEz13

+0

良いと思う、質問の1つの部分に答える。そして、JavaScriptを使ってオブジェクトを取得し、HTMLでフォーマットするにはどうすればよいですか? 'JSON.parse(child)'を試しましたが、それはエラーです。 – 30000MONKEYS

答えて

0

標準出力は、表示する独自のフォーマットされた方法を持つため、この場合は機能しません。ネイティブのPowerShell変換とは別に、変換機能はほとんどありません。試してみると、出力を解析する必要があります。

ここに行く:

  • をConvertTo-JsonIfAblePSObject

使い方は理解を容易にするためのコメントセクションで言及されています。

<# 
.SYNOPSIS 
    Creates a new PSObject where all properties of the original object that are not able to be 
    properly serialized to JSON are converted to a value which can be properly converted to JSON. 

    This includes the following types: 
    * DateTime 

    This conducts a deep property search 
.Example 
    Convert an custom PSObject to have parsable dates in Json 

    $customObject = New-Object -TypeName PSobject -Property @{ Date = Get-Date; Number = 23; InnerDate = New-Object -TypeName PSObject -Property @{Date=Get-Date;} } 

    ## BAD Json 
    PS C:\dev> $customObject | ConvertTo-Json 
    { 
     "Date": { 
        "value": "\/Date(1410372629047)\/", 
        "DisplayHint": 2, 
        "DateTime": "Wednesday, September 10, 2014 2:10:29 PM" 
       }, 
     "Number": 23, 
     "InnerDate": { 
          "Date": { 
             "value": "\/Date(1410372629047)\/", 
             "DisplayHint": 2, 
             "DateTime": "Wednesday, September 10, 2014 2:10:29 PM" 
            } 
         } 
    } 

    ## Good Json 
    PS C:\dev> $customObject | ConvertTo-JsonifiablePSObject | ConvertTo-Json 
    { 
     "Date": "2014-09-10T14:10:29.0477785-04:00", 
     "Number": 23, 
     "InnerDate": { 
          "Date": "2014-09-10T14:10:29.0477785-04:00" 
         } 
    } 

#> 
function ConvertTo-JsonifiablePSObject 
{ 
    param 
    (
     [Parameter(Mandatory=$true, ValueFromPipeline=$true)] 
     [PSObject]$Object 
    ) 

    $newObjectProperties = @{} 

    foreach ($property in $Object.psobject.properties) 
    { 
     $value = $property.Value 

     if ($property.TypeNameOfValue -eq "System.Management.Automation.PSCustomObject") 
     { 
      $value = ConvertTo-JsonifiablePSObject -Object $property.Value 
     } 
     elseif ($property.TypeNameOfValue -eq "System.DateTime") 
     { 
      $value = $property.Value.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK") 
     } 

     $newObjectProperties[$property.Name] = $value 
    } 

    return New-Object -TypeName PSObject -Property $newObjectProperties 
} 

$json=$kbm | ConvertTo-Json 
  • を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 { } 
    } 
    

注: Convertto-jsonも、これらすべてから離れて試してみてください。

希望します。

+0

うわー、素敵な機能。今すぐ私のJavascriptに出力を得る方法を知る必要があります;) – 30000MONKEYS

+0

@ 30000MONKEYS:助けて幸いです.Goodluck –

+0

@ 30000MONKEYS:それがあなたを助けるならば答えを受け入れてください。 –

関連する問題