PowerShell анализирует переменные и объекты - PullRequest
2 голосов
/ 15 февраля 2020

Я обнаружил, что я много .GetType() и | Get-Member, и иногда я забываю, что это .GetType, и я пытаюсь .Get-Type Дух! ошибка!) , поэтому я пишу функцию для быстрого сбора этой информации. Это оказалось весьма полезным при работе с консолью (я ставлю команду core перед каждым выводом, чтобы никогда не забывать о подключении к реальным командам, поэтому больше подробного описания, чтобы поддерживать связь с языком).

Мне любопытно, есть ли дополнительные составные команды для извлечения полезной обобщенной c информации, которую мы могли бы использовать, чтобы сообщить о структуре данного объекта (вещи, которые мы можем быстро получить в очень компактном формате резюме) даже если для некоторой полезной информации о заданных объектах требуются более сложные команды)?

$a = @(1,2,"x") ; obj $a. Это возвращает 71 тип методов (System.String и System.Int32), поэтому я удалил дубликаты до 50 (хорошо, чтобы быстро увидеть, что можно использовать, но, возможно, хорошо, чтобы как-то также упомянуть различные типы, содержащиеся в этом массиве?) .

• Некоторый ввод, конечно, нарушит функцию, но даже такой пример ScriptBlock также отлично работает obj {$a; $x}. Вы даже можете сделать что-то вроде obj "".GetType(), чтобы увидеть там методы и свойства.

• Использование .Module в GetType() может быть избыточным, так как обычно выводит CommonLanguageRuntimeLibrary, но может быть другим полезным информация от этих членов ( все , конечно, полезно в разное время, но мне любопытно обобщенный вывод c)?

• В целом, любые улучшения или другие составные команды, которые Вы используете или могли бы быть полезны для взлома открытой информации об объекте в быстром кратком представлении, было бы здорово узнать? : -)

Обновлен с -Force, который @Clint предложил:

function obj ($cmd) {
    if ($cmd -eq $null) { Write-Host "Object is `$null" ; return } 
    Write-Host "Contents:" -F Cyan
    $cmd
    ""
    Write-Host "(`$object).GetType()" -F Cyan -NoNewline ; Write-Host " :: [BaseType|Name|IsPublic|IsSerial|Module]"
    ($cmd).GetType() | % { "$($_.BaseType), $($_.Name), $($_.IsPublic), $($_.IsSerializable), $($_.Module)" }
    ""
    Write-Host "`$object | Get-Member -Force" -F Cyan
    $m = "" ; $p = "" ; $pp = "" ; $np = "" ; $sp = ""
    $msum = 0 ; $psum = 0 ; $ppsum = 0 ; $npsum = 0 ; $spsum = 0
    $($cmd | Get-Member -Force) | % {
        if ($_.MemberType -eq "Method") { if(!($m -like "*$($_.Name),*")) { $m += "$($_.Name), " ; $msum++ } }
        if ($_.MemberType -eq "Property") { if(!($p -like "*$($_.Name),*")) { $p += "$($_.Name), " ; $psum++ } }
        if ($_.MemberType -eq "ParameterizedProperty") { if(!($pp -like "*$($_.Name),*")) { $pp += "$($_.Name), " ; $ppsum++} }
        if ($_.MemberType -eq "NoteProperty") { if(!($np -like "*$($_.Name),*")) { $np += "$($_.Name), " ; $npsum++ } }
        if ($_.MemberType -eq "ScriptProperty") { if(!($sp -like "*$($_.Name),*")) { $sp += "$($_.Name), " ; $npsum++ } }
    }
    if($msum -ne 0) { Write-Host ":: Method [$msum] => $($m.TrimEnd(", "))" }
    if($psum -ne 0) { Write-Host ":: Property [$psum] => $($p.TrimEnd(", "))" }
    if($ppsum -ne 0) { Write-Host ":: ParameterizedProperty [$ppsum] => $($pp.TrimEnd(", "))" }
    if($npsum -ne 0) { Write-Host ":: NoteProperty [$npsum] => $($np.TrimEnd(", "))" }
    if($spsum -ne 0) { Write-Host ":: ScriptProperty [$spsum] => $($sp.TrimEnd(", "))" }
    ""
}

Пример вывода:

C:\> $a = @(123,"x")
C:\> def $a
Contents:
123
x

($object).GetType() :: [BaseType|Name|IsPublic|IsSerial|Module]
array, Object[], True, True, CommonLanguageRuntimeLibrary

$object | Get-Member -Force
:: Method [50] => CompareTo, Equals, GetHashCode, GetType, GetTypeCode, ToBoolean, ToByte, ToChar, ToDateTime, ToDecimal, ToDouble, ToInt16,
ToInt32, ToInt64, ToSByte, ToSingle, ToString, ToType, ToUInt16, ToUInt32, ToUInt64, Clone, Contains, CopyTo, EndsWith, GetEnumerator,
get_Chars, get_Length, IndexOf, IndexOfAny, Insert, IsNormalized, LastIndexOf, LastIndexOfAny, Normalize, PadLeft, PadRight, Remove, Replace,
Split, StartsWith, Substring, ToCharArray, ToLower, ToLowerInvariant, ToUpper, ToUpperInvariant, Trim, TrimEnd, TrimStart
:: Property [1] => Length
:: ParameterizedProperty [1] => Chars

Ответы [ 2 ]

3 голосов
/ 15 февраля 2020

Вы суммировали это довольно хорошо, как есть, вы могли бы также добавить

  • object | gm -Force # To add members that are usually hidden by default
    

    Команда Get-Member использует параметр Force для добавления внутренних членов и сгенерированные компилятором члены объектов для отображения. Get-Member получает эти члены, но по умолчанию скрывает их.

    Intrinsi c члены (PSBase, PSAdapted, PSObject, PSTypeNames)

    Генерируемые компилятором методы get_ и set_

    MSDN Do c

  • object.PSObject #Wraps the information pertaining to different members
    object.PSObject | Select-Object -ExpandProperty Properties #You can do the same for other members 
    
  • $object |gm -force -static #even with force the static members are not listed by default, so we need to explicitly mention static 
    
  • может быть, хорошо как-то также упомянуть различные типы, содержащиеся в этом массиве?).

    $object | ForEach-Object {$_.GetType().FullName}
    
  • OffTopi c, дополнительно, если вы хотите зафиксировать время, необходимое для выполнения функции

    $sw = [Diagnostics.Stopwatch]::StartNew()    
    $sw.Stop()
    Write-Host "Execution time" $sw.Elapsed.Milliseconds "ms"
    
1 голос
/ 15 февраля 2020

Знание того, что PowerShell не очень понятен при отображении объекта (например: '', $Null, @() и @{$Null), все приводят к пустой строке, или вообще ничего ), Я думаю, вам нужно начать с первого абзаца вашего вопроса и визуализировать типы и структуру ваших рассматриваемых объектов, а затем рассмотреть методы, которые могут различаться на каждом уровне в структуре объекта.

* примечание: вы также можете раскрыть типы с помощью .PSTypeNames, что не приводит к ошибке на $Null (при условии, что строгий режим не включен).

В качестве более продвинутого примера: $a = @($Null, 1, '2', @(3))

Write-Host

Командлет Write-Host (используемый вашей функцией) не работает многое говорит о типах и структуре объекта: (Кроме того, вам следует избегать Write-Host как есть Host speci c)

PS C:\> $a
1
2
3

PS C:\> Write-Host $a
 1 2 3

Чтобы лучше понять такой объект, вы можете его сериализовать. Цитата из WikiPedia:

В информатике, в контексте хранения данных, сериализация (или сериализация) - это процесс перевода структур данных или объекта состояние в формате, который может быть сохранен (например, в буфере файла или памяти) или передан (например, через канал сетевого подключения) и восстановлен позже (возможно, в другой компьютерной среде)

Это означает, что строковое представление объекта в основном содержит всю информацию для перестройки (и понимания) объекта (или, по крайней мере, до определенного уровня).

Есть несколько Сериализаторы, которые могут быть здесь под рукой:

ConvertTo-Json

Командлет ConvertTo-Json преобразует любой объект в строку в JavaScript Обозначение объекта (JSON ) формат а, следовательно, может быть полезен для понимания структуры, но не для типов PowerShell :

PS C:\> ConvertTo-Json $a
[
  null,
  1,
  "2",
  [
    3
  ]
]

ConvertTo-Xml

1066 * cmdle t создает основанное на XML представление объекта, которое довольно многословно:

PS C:\> ConvertTo-Xml $a -as String
<?xml version="1.0" encoding="utf-8"?>
<Objects>
  <Object Type="System.Object[]">
    <Property />
    <Property Type="System.Int32">1</Property>
    <Property Type="System.String">2</Property>
    <Property Type="System.Object[]">
      <Property Type="System.Int32">3</Property>
    </Property>
  </Object>
</Objects>**strong text**

PSSerializer

Этот (. Net) класс обеспечивает Функциональные возможности publi c для сериализации объекта PSO и внутреннего использования PowerShell:

PS C:\> [System.Management.Automation.PSSerializer]::Serialize($a)
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
  <Obj RefId="0">
    <TN RefId="0">
      <T>System.Object[]</T>
      <T>System.Array</T>
      <T>System.Object</T>
    </TN>
    <LST>
      <Nil />
      <Obj RefId="1">
        <I32>1</I32>
      </Obj>
      <S>2</S>
      <Obj RefId="2">
        <TNRef RefId="0" />
        <LST>
          <I32>3</I32>
        </LST>
      </Obj>
    </LST>
  </Obj>
</Objs>

ConvertTo-Expression

Командлет ConvertTo-Expression возник из вопроса: Сохранить таблицу ha sh в нотации объектов PowerShell (PSON) и дает представление PowerShell для объекта:

Неявное :

PS C:\> ConvertTo-Expression $a
$Null,
1,
'2',
(,3)

Явное :

PS C:\> ConvertTo-Expression $a -Strong
[array](
        $Null,
        [int]1,
        [string]'2',
        [array][int]3
)

Исследователю. Net классы, не являющиеся родными для PowerShell :
* обратите внимание, что вы можете не восстанавливать из -Explore выражений

PS C:\> Get-Service | Select -First 1 | ConvertTo-Expression -Strong -Explore
[System.ServiceProcess.ServiceController]@{
        'UserName' = [string]''
        'Description' = [string]'Runtime for activating conversational agent applications'
        'DelayedAutoStart' = [bool]$False
        'BinaryPathName' = [string]'C:\WINDOWS\system32\svchost.exe -k AarSvcGroup -p'
        'StartupType' = [Microsoft.PowerShell.Commands.ServiceStartupType]3
        'CanPauseAndContinue' = [bool]$False
        'CanShutdown' = [bool]$False
        'CanStop' = [bool]$False
        'DisplayName' = [string]'Agent Activation Runtime_131b90'
        'DependentServices' = [System.ServiceProcess.ServiceController[]]@()
        'MachineName' = [string]'.'
        'ServiceName' = [string]'AarSvc_131b90'
        'ServicesDependedOn' = [System.ServiceProcess.ServiceController[]]@()
        'StartType' = [System.ServiceProcess.ServiceStartMode]3
        'ServiceHandle' = $Null
        'Status' = [System.ServiceProcess.ServiceControllerStatus]1
        'ServiceType' = [System.ServiceProcess.ServiceType]224
        'Site' = $Null
        'Container' = $Null
}

Для детализации известных (ускоренных) типов PowerShell :

PS C:\>Get-Date | Select-Object -Property * | ConvertTo-Expression
Date        : 1963-10-07 12:00:00 AM
DateTime    : Monday, October 7, 1963 10:47:00 PM
Day         : 7
DayOfWeek   : Monday
DayOfYear   : 280
DisplayHint : DateTime
Hour        : 22
Kind        : Local
Millisecond : 0
Minute      : 22
Month       : 1
Second      : 0
Ticks       : 619388596200000000
TimeOfDay   : 22:47:00
Year        : 1963
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...