Thursday, July 2, 2015

Beginner's Guide - Working with lists (part 2)

In part 1 of this series, we covered string arrays and briefly touched on hash tables.  In this tutorial we'll cover how to use and define custom lists (object arrays).  All data flows in and out of cmdlets are objects.  Even plain numbers or strings are technically objects.  And most of the time, you'll be working with more than one of these objects in the form of an array of objects, which is why this topic is pretty crucial for understanding and working with Powershell effectively.

As we covered in part 1, if you think of an excel spreadsheet as a table of data or in Powershell as an array of objects.  Each column has a header which is known as Properties and a data type, while rows or records are known as Objects (or PSCustomObject).  Here are some examples of Object arrays.
PS C:\> $serverstatus = import-csv C:\ServerStatus.csv
PS C:\> $serverstatus | Format-Table -AutoSize

ServerName TimeStamp           RDPPort Results
---------- ---------           ------- -------
server1    2015-06-26T09:35:51 3389    Up
server2    2015-06-26T09:35:52 3389    Up
server3    2015-06-26T09:35:53 3389    Up
server4    2015-06-26T09:35:54 3389    Up
server5    2015-06-26T09:35:55 3389    Up


PS C:\> $serverstatus.GetType()         #[] indicates array, so this is a data type of Object Array

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array


PS C:\> $serverstatus[0]                 #from part 1 - indexing the array, 0 = the first record

ServerName TimeStamp           RDPPort Results
---------- ---------           ------- -------
server1    2015-06-26T09:35:51 3389    Up


PS C:\> $serverstatus[0].ServerName.GetType()      #The data type of the property server name is of type String

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object


PS C:\> $serverstatus[0].TimeStamp             # referencing the 
2015-06-26T09:35:51


PS C:\> $cdrive = Get-ChildItem                #dir is the alias for Get-ChildItem.
PS C:\> $cdrive | Format-Table -AutoSize


    Directory: C:\


Mode          LastWriteTime Length Name
----          ------------- ------ ----
d-----  6/30/2015   5:01 PM        HyperV
d-----  5/23/2015   6:06 AM        PerfLogs
d-r---   7/2/2015   5:23 PM        Program Files
d-r---   7/1/2015   6:54 PM        Program Files (x86)
d-r---  6/20/2015   7:05 PM        Users
d-----  6/27/2015   8:20 AM        Windows



PS C:\> $cdrive.GetType()                     #again, we can see it's an Object Array

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array



PS C:\> $cdrive | Get-Member                 #By default, get-member is only looking at the first object in the array


   TypeName: System.IO.DirectoryInfo

Name                      MemberType     Definition
----                      ----------     ----------
Mode                      CodeProperty   System.String Mode{get=Mode;}
Create                    Method         void Create(), void Create(System.Security.AccessControl.DirectorySecurity ...
CreateObjRef              Method         System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)
CreateSubdirectory        Method         System.IO.DirectoryInfo CreateSubdirectory(string path), System.IO.Director...
Delete                    Method         void Delete(), void Delete(bool recursive)
EnumerateDirectories      Method         System.Collections.Generic.IEnumerable[System.IO.DirectoryInfo] EnumerateDi...
EnumerateFiles            Method         System.Collections.Generic.IEnumerable[System.IO.FileInfo] EnumerateFiles()...
EnumerateFileSystemInfos  Method         System.Collections.Generic.IEnumerable[System.IO.FileSystemInfo] EnumerateF...
Equals                    Method         bool Equals(System.Object obj)
GetAccessControl          Method         System.Security.AccessControl.DirectorySecurity GetAccessControl(), System....
GetDirectories            Method         System.IO.DirectoryInfo[] GetDirectories(), System.IO.DirectoryInfo[] GetDi...
GetFiles                  Method         System.IO.FileInfo[] GetFiles(string searchPattern), System.IO.FileInfo[] G...
GetFileSystemInfos        Method         System.IO.FileSystemInfo[] GetFileSystemInfos(string searchPattern), System...
GetHashCode               Method         int GetHashCode()
GetLifetimeService        Method         System.Object GetLifetimeService()
GetObjectData             Method         void GetObjectData(System.Runtime.Serialization.SerializationInfo info, Sys...
GetType                   Method         type GetType()
InitializeLifetimeService Method         System.Object InitializeLifetimeService()
MoveTo                    Method         void MoveTo(string destDirName)
Refresh                   Method         void Refresh()
SetAccessControl          Method         void SetAccessControl(System.Security.AccessControl.DirectorySecurity direc...
ToString                  Method         string ToString()
PSChildName               NoteProperty   string PSChildName=AMD
PSDrive                   NoteProperty   PSDriveInfo PSDrive=C
PSIsContainer             NoteProperty   bool PSIsContainer=True
PSParentPath              NoteProperty   string PSParentPath=Microsoft.PowerShell.Core\FileSystem::C:\
PSPath                    NoteProperty   string PSPath=Microsoft.PowerShell.Core\FileSystem::C:\AMD
PSProvider                NoteProperty   ProviderInfo PSProvider=Microsoft.PowerShell.Core\FileSystem
Attributes                Property       System.IO.FileAttributes Attributes {get;set;}
CreationTime              Property       datetime CreationTime {get;set;}
CreationTimeUtc           Property       datetime CreationTimeUtc {get;set;}
Exists                    Property       bool Exists {get;}
Extension                 Property       string Extension {get;}
FullName                  Property       string FullName {get;}
LastAccessTime            Property       datetime LastAccessTime {get;set;}
LastAccessTimeUtc         Property       datetime LastAccessTimeUtc {get;set;}
LastWriteTime             Property       datetime LastWriteTime {get;set;}
LastWriteTimeUtc          Property       datetime LastWriteTimeUtc {get;set;}
Name                      Property       string Name {get;}
Parent                    Property       System.IO.DirectoryInfo Parent {get;}
Root                      Property       System.IO.DirectoryInfo Root {get;}
BaseName                  ScriptProperty System.Object BaseName {get=$this.Name;}
LinkType                  ScriptProperty System.Object LinkType {get=[Microsoft.PowerShell.Commands.InternalSymbolic...
Target                    ScriptProperty System.Object Target {get=[Microsoft.PowerShell.Commands.InternalSymbolicLi...



PS C:\> $processes = Get-Process                          #Gets the current active processes
PS C:\> $processes | Format-Table -AutoSize               #there are many more properties per object, but only these 8 are being shown

Handles NPM(K)  PM(K)  WS(K)   VM(M)    CPU(s)    Id ProcessName
------- ------  -----  -----   -----    ------    -- -----------
    480     29  69460  37712 2097402      2.41  6236 ApplicationFrameHost
    275     34  90344  71268     396    275.47  3524 chrome
    206     21  28128  13200     198      1.48  3600 chrome
    206     20  27776  15156     196      1.61  3740 chrome
    208     21  29668  12836     198      1.45  3744 chrome
   4301    146 232976 253580    1291 16,956.36  5072 chrome
     94      9   4424   3572 2097235      1.45  3108 conhost
    114     11  10908  10148 2097277      7.80  6264 conhost
    114     10   4844  11348 2097246      2.09  9760 conhost
    354     14   1308   1512 2097204      2.98   540 csrss
    705     49  13956   6252 2097341    122.59   692 csrss
    238     12   2784   2460 2097253      0.39  5636 dllhost
   1064     65 203812  45616 2097693    617.16  1204 dwm
   2791    211 158364 125988 2098011    577.27  3948 explorer
     37      7    924   1300 2097209      0.17  6824 fontdrvhost
      0      0      0      4       0               0 Idle
    234     15   2800   3032      69      0.16  8136 LMS
   1759     30   8056  13904 2097205     65.52   824 lsass
   1603     68  95844  43124 2098071  2,758.66  8128 mmc
    353     35  26680   7628     592      2.41  6984 MOM
    596     67 123360  80576 2097484  1,872.06  2420 MsMpEng
    962     34  41648  22180 2097413    477.55   716 mstsc
    269     14   9744   2324 2097206    200.13  3000 NisSrv
    996     67 130260 116112 2097932     12.22  3628 powershell
   1063     82 421540 449268 2098281     62.19 11572 powershell
   1173     47  37088  52140 2097484     59.64  4048 RuntimeBroker
    112      8   1172   5684 2097186      0.00 10644 SearchFilterHost
    813     75  43600  44424 2097584     94.95  4148 SearchIndexer
    735     25   6720  20576 2097495      0.11 12072 SearchProtocolHost
    966     82  94528 103820   33439      7.97  4460 SearchUI
    291     12   4316   4884 2097189     22.48   816 services
    864     43  88108  55028     405  3,876.80  3572 ShellExperienceHost
    408     18   5588  14368 2097295      7.41  3612 sihost
     49      3    336    316 2097156      0.08   344 smss
    176     13   3288   3124 2097252      1.23  7880 splwow64
    466     31   8920   8808 2097258     22.00  1524 spoolsv
    915     53   9596  13912 2098446     12.58   436 svchost
   2388     75  28756  49576 2097395  2,164.47   812 svchost
    644     22   6808  11160 2097222     12.31   932 svchost
    703     23   6044   8404 2097238     60.58   988 svchost
    937     31  13752  16112 2097246  2,608.06  1064 svchost
    709     38   6976  10896 2097248      7.03  1076 svchost
    593     31   7184   9836 2101998    231.47  1304 svchost
    220     17   2256   3872 2097197      3.28  1316 svchost
    516     44  18376  20044 2097281     37.47  1356 svchost
    469     25  19024  25668 2097318     71.41  2284 svchost
    260     17   6612  11388 2097862     26.20  2368 svchost
    201     14   3328   2440 2097239      0.03  3620 svchost
   1647      0    448  63616     129  2,523.84     4 System
    343     30   6412   9044 2097515      2.13  3696 taskhostw
    413     27  16992  25596 2097361  1,212.61  2476 Taskmgr
    145     12   1904   3360 2097210      2.38  7740 unsecapp
    568     26  16380  18020 2097282    574.36  2376 vmms
    507     27  41316   9784 2097276  1,244.92  2244 vmwp
     84      8    904   1032 2097194      0.05   684 wininit
    213     10   1864   3444 2097213      0.47   772 winlogon
    356     18   9144  12744 2097240  2,362.16  2732 WmiPrvSE
    143     10   2480   5460 2097189      0.41  5716 WmiPrvSE
    480     23   7232  18772 2097297      0.95  4156 WSHost


PS C:\> $processes.GetType()               #Again, you can see it's an Object Array

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array


PS C:\> $processes[0] | Format-List *      #Now we get to see the full list of properties per object, similar to Get-Member

__NounName                 : Process
Name                       : ApplicationFrameHost
Handles                    : 480
VM                         : 2199285780480
WS                         : 38617088
PM                         : 71127040
NPM                        : 29232
Path                       : C:\Windows\system32\ApplicationFrameHost.exe
Company                    : Microsoft Corporation
CPU                        : 2.40625
FileVersion                : 10.0.10130.0 (fbl_impressive.150522-2224)
ProductVersion             : 10.0.10130.0
Description                : Application Frame Host
Product                    : Microsoft® Windows® Operating System
Id                         : 6236
PriorityClass              : Normal
HandleCount                : 480
WorkingSet                 : 38617088
PagedMemorySize            : 71127040
PrivateMemorySize          : 71127040
VirtualMemorySize          : 262524928
TotalProcessorTime         : 00:00:02.4062500
BasePriority               : 8
ExitCode                   :
HasExited                  : False
ExitTime                   :
Handle                     : 5628
SafeHandle                 : Microsoft.Win32.SafeHandles.SafeProcessHandle
MachineName                : .
MainWindowHandle           : 266852
MainWindowTitle            : Calculator
MainModule                 : System.Diagnostics.ProcessModule (ApplicationFrameHost.exe)
MaxWorkingSet              : 1413120
MinWorkingSet              : 204800
Modules                    : {System.Diagnostics.ProcessModule (ApplicationFrameHost.exe),
                             System.Diagnostics.ProcessModule (ntdll.dll), System.Diagnostics.ProcessModule
                             (KERNEL32.DLL), System.Diagnostics.ProcessModule (KERNELBASE.dll)...}
NonpagedSystemMemorySize   : 29232
NonpagedSystemMemorySize64 : 29232
PagedMemorySize64          : 71127040
PagedSystemMemorySize      : 456312
PagedSystemMemorySize64    : 456312
PeakPagedMemorySize        : 72245248
PeakPagedMemorySize64      : 72245248
PeakWorkingSet             : 66281472
PeakWorkingSet64           : 66281472
PeakVirtualMemorySize      : 266883072
PeakVirtualMemorySize64    : 2199290138624
PriorityBoostEnabled       : True
PrivateMemorySize64        : 71127040
PrivilegedProcessorTime    : 00:00:01.7500000
ProcessName                : ApplicationFrameHost
ProcessorAffinity          : 15
Responding                 : True
SessionId                  : 1
StartInfo                  : System.Diagnostics.ProcessStartInfo
StartTime                  : 6/30/2015 3:54:14 PM
SynchronizingObject        :
Threads                    : {7732, 6172, 3132, 7996...}
UserProcessorTime          : 00:00:00.6562500
VirtualMemorySize64        : 2199285780480
EnableRaisingEvents        : False
StandardInput              :
StandardOutput             :
StandardError              :
WorkingSet64               : 38617088
Site                       :
Container                  :


PS C:\> $processes[0].PrivilegedProcessorTime.GetType()    #the property here is of data type TimeSpan.

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     TimeSpan                                 System.ValueType


With Get-Process, the process objects themselves have many properties by default.  One way to make a custom object array is to select a subset from a larger object array.  By far, this is likely what you'll be doing in most of your scripting, so I'm going to break it down for you.


Sorting

As with simple string arrays, you can sort any custom object array in ascending or descending order, however with object arrays, you must specify which property you wish to sort on.

PS C:\> $cdrive | sort LastWriteTime    #sort by the the last time the directory was written to


    Directory: C:\


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----        5/23/2015   6:06 AM                PerfLogs
d-r---        6/20/2015   7:05 PM                Users
d-----        6/27/2015   8:20 AM                Windows
d-----        6/30/2015   5:01 PM                HyperV
d-r---         7/1/2015   6:54 PM                Program Files (x86)
d-r---         7/2/2015   5:23 PM                Program Files



PS C:\> $serverstatus | sort Servername -Descending    #sort in reverse order the servername property

ServerName TimeStamp           RDPPort Results
---------- ---------           ------- -------
server5    2015-06-26T09:35:51 3389    Up
server4    2015-06-26T09:35:55 3389    Up
server3    2015-06-26T09:35:54 3389    Up
server2    2015-06-26T09:35:53 3389    Up
server1    2015-06-26T09:35:52 3389    Up



Selecting

By far one of the most useful object array modifiers and you'll send up using it the most of these.  Selecting is a way to remove certain properties from an array, which allows you to do away with the extra columns of data you don't need.  Select is easy to use, just pipe in your object array and list which properties you want output.  We briefly touched on special parameters like -First <#>, -Skip <#>, and -Last <#> which actually work on a record level, not the properties.

PS C:\> $cdrive | select FullName,Attributes,CreationTime,LastAccessTime -Last 3   #Only returns the last 3 entries of the array

FullName                                    Attributes CreationTime         LastAccessTime
--------                                    ---------- ------------         --------------
C:\Program Files (x86) ReadOnly, Directory, Compressed 5/23/2015 4:52:28 AM 7/1/2015 6:54:47 PM
C:\Users               ReadOnly, Directory, Compressed 5/23/2015 4:52:28 AM 6/20/2015 7:05:34 PM
C:\Windows                       Directory, Compressed 5/23/2015 4:52:28 AM 6/27/2015 8:20:52 AM



PS C:\> $processes | Select Name,VirtualMemorySize64,BasePriority,Company -First 4 -Skip 1    

Name       VirtualMemorySize64 BasePriority Company
----       ------------------- ------------ -------
chrome              1354072064            8 Google Inc.
chrome               470994944            8 Google Inc.
chrome               319963136            8 Google Inc.
chrome               474648576            8 Google Inc.




PS C:\> $processes | select * -First 1    #Select * is the wildcard for all properties. This is the same as $processes[0] | Select *


__NounName                 : Process
Name                       : ApplicationFrameHost
Handles                    : 480
VM                         : 2199285780480
WS                         : 38617088
PM                         : 71127040
NPM                        : 29232
Path                       : C:\Windows\system32\ApplicationFrameHost.exe
Company                    : Microsoft Corporation
CPU                        : 2.40625
FileVersion                : 10.0.10130.0 (fbl_impressive.150522-2224)
ProductVersion             : 10.0.10130.0
Description                : Application Frame Host
Product                    : Microsoft® Windows® Operating System
Id                         : 6236
PriorityClass              : Normal
HandleCount                : 480
WorkingSet                 : 38617088
PagedMemorySize            : 71127040
PrivateMemorySize          : 71127040
VirtualMemorySize          : 262524928
TotalProcessorTime         : 00:00:02.4062500
BasePriority               : 8
ExitCode                   :
HasExited                  : False
ExitTime                   :
Handle                     : 5628
SafeHandle                 : Microsoft.Win32.SafeHandles.SafeProcessHandle
MachineName                : .
MainWindowHandle           : 266852
MainWindowTitle            : Calculator
MainModule                 : System.Diagnostics.ProcessModule (ApplicationFrameHost.exe)
MaxWorkingSet              : 1413120
MinWorkingSet              : 204800
Modules                    : {System.Diagnostics.ProcessModule (ApplicationFrameHost.exe),
                             System.Diagnostics.ProcessModule (ntdll.dll), System.Diagnostics.ProcessModule
                             (KERNEL32.DLL), System.Diagnostics.ProcessModule (KERNELBASE.dll)...}
NonpagedSystemMemorySize   : 29232
NonpagedSystemMemorySize64 : 29232
PagedMemorySize64          : 71127040
PagedSystemMemorySize      : 456312
PagedSystemMemorySize64    : 456312
PeakPagedMemorySize        : 72245248
PeakPagedMemorySize64      : 72245248
PeakWorkingSet             : 66281472
PeakWorkingSet64           : 66281472
PeakVirtualMemorySize      : 266883072
PeakVirtualMemorySize64    : 2199290138624
PriorityBoostEnabled       : True
PrivateMemorySize64        : 71127040
PrivilegedProcessorTime    : 00:00:01.7500000
ProcessName                : ApplicationFrameHost
ProcessorAffinity          : 15
Responding                 : True
SessionId                  : 1
StartInfo                  : System.Diagnostics.ProcessStartInfo
StartTime                  : 6/30/2015 3:54:14 PM
SynchronizingObject        :
Threads                    : {7732, 6172, 3132, 7996...}
UserProcessorTime          : 00:00:00.6562500
VirtualMemorySize64        : 2199285780480
EnableRaisingEvents        : False
StandardInput              :
StandardOutput             :
StandardError              :
WorkingSet64               : 38617088
Site                       :
Container                  :




Where Clause

If you are familiar with SQL, you'll recognize the Where-Object (aka "where" or "?" aliases) as a way to exclude certain records given a conditional check to each record.  If a True is produced, the record is included, if a False is calculated, the record is excluded. The parameter for Where-Object is actually a script block which is ran on each record.

PS C:\> $cdrive | Where-Object{$_.mode -like "*r*"}      #returns only records that have the read only attribute set on them (R from mode property).


    Directory: C:\


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-r---         7/2/2015   5:23 PM                Program Files
d-r---         7/1/2015   6:54 PM                Program Files (x86)
d-r---        6/20/2015   7:05 PM                Users



PS C:\> $processes | Where-Object {$_.company -notlike "*microsoft*"}   #returns only records of processes that aren't labeled as Microsoft

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
   4301     146   232976     253580  1291 ...35.02   5072 chrome
    255      38   171652     146496   449 1,789.36   8516 chrome
    253      29    60472      42340   305   239.45   8524 chrome
    285      40   119432     114596   453 1,657.22   8872 chrome
    404      72   284048     523196  1041 ...49.17   8976 chrome
    322      40    91900     101556   349 1,574.55   9076 chrome
    289      37   100332     112892   342    74.33   9628 chrome
    248      30    91844      69756   277   305.22  10400 chrome
    302      37   113524      85084   433   466.67  11176 chrome
    292      40   132888     138396   334    55.25  11636 chrome
    354      14     1308       1512 ...04     2.98    540 csrss
    705      49    13956       6252 ...41   126.80    692 csrss
      0       0        0          4     0               0 Idle
    234      15     2800       3032    69     0.16   8136 LMS
    353      35    26680       7628   592     2.44   6984 MOM
    596      67   123360      80576 ...84 1,876.20   2420 MsMpEng
    269      14     9744       2324 ...06   200.53   3000 NisSrv
    112       8     1172       5684 ...86           10644 SearchFilterHost
    735      25     6720      20576 ...95           12072 SearchProtocolHost
    966      82    94528     103820 33439     7.97   4460 SearchUI
    291      12     4316       4884 ...89    22.70    816 services
     49       3      336        316 ...56     0.08    344 smss
   1647       0      448      63616   129 2,550.19      4 System
     84       8      904       1032 ...94     0.05    684 wininit


Grouping

Grouping actually creates a nested object array (and object array inside of an object array) and is a bit more advanced and less used, so I'm only going to mention it for now. Grouping finds the matching records by the property specified and colapses the records into a new property called Group which is a nested array. Count is also generated to show how many objects are inside of the group property.

PS C:\> $serverstatus | group results         #since all of the results were up, there's only one entry in this group output.

Count Name                      Group
----- ----                      -----
    5 Up                        {@{ServerName=server1; TimeStamp=2015-06-26T09:35:51; RDPPort=3389; Results=Up}, @{Serve...



PS C:\> $processes | group ProcessName 

Count Name                      Group
----- ----                      -----
    1 ApplicationFrameHost      {System.Diagnostics.Process (ApplicationFrameHost)}
    9 chrome                    {System.Diagnostics.Process (chrome), System.Diagnostics.Process (chrome), System.Di...
    3 conhost                   {System.Diagnostics.Process (conhost), System.Diagnostics.Process (conhost), System....
    2 csrss                     {System.Diagnostics.Process (csrss), System.Diagnostics.Process (csrss)}
    1 dllhost                   {System.Diagnostics.Process (dllhost)}
    1 dwm                       {System.Diagnostics.Process (dwm)}
    1 explorer                  {System.Diagnostics.Process (explorer)}
    1 fontdrvhost               {System.Diagnostics.Process (fontdrvhost)}
    1 Idle                      {System.Diagnostics.Process (Idle)}
    1 LMS                       {System.Diagnostics.Process (LMS)}
    1 lsass                     {System.Diagnostics.Process (lsass)}
    1 mmc                       {System.Diagnostics.Process (mmc)}
    1 MOM                       {System.Diagnostics.Process (MOM)}
    1 MsMpEng                   {System.Diagnostics.Process (MsMpEng)}
    1 mstsc                     {System.Diagnostics.Process (mstsc)}
    1 NisSrv                    {System.Diagnostics.Process (NisSrv)}
    2 powershell                {System.Diagnostics.Process (powershell), System.Diagnostics.Process (powershell)}
    1 RuntimeBroker             {System.Diagnostics.Process (RuntimeBroker)}
    1 SearchFilterHost          {System.Diagnostics.Process (SearchFilterHost)}
    1 SearchIndexer             {System.Diagnostics.Process (SearchIndexer)}
    1 SearchProtocolHost        {System.Diagnostics.Process (SearchProtocolHost)}
    1 SearchUI                  {System.Diagnostics.Process (SearchUI)}
    1 services                  {System.Diagnostics.Process (services)}
    1 ShellExperienceHost       {System.Diagnostics.Process (ShellExperienceHost)}
    1 sihost                    {System.Diagnostics.Process (sihost)}
    1 smss                      {System.Diagnostics.Process (smss)}
    1 splwow64                  {System.Diagnostics.Process (splwow64)}
    1 spoolsv                   {System.Diagnostics.Process (spoolsv)}
   12 svchost                   {System.Diagnostics.Process (svchost), System.Diagnostics.Process (svchost), System....
    1 System                    {System.Diagnostics.Process (System)}
    1 taskhostw                 {System.Diagnostics.Process (taskhostw)}
    1 Taskmgr                   {System.Diagnostics.Process (Taskmgr)}
    1 unsecapp                  {System.Diagnostics.Process (unsecapp)}
    1 vmms                      {System.Diagnostics.Process (vmms)}
    1 vmwp                      {System.Diagnostics.Process (vmwp)}
    1 wininit                   {System.Diagnostics.Process (wininit)}
    1 winlogon                  {System.Diagnostics.Process (winlogon)}
    2 WmiPrvSE                  {System.Diagnostics.Process (WmiPrvSE), System.Diagnostics.Process (WmiPrvSE)}
    1 WSHost                    {System.Diagnostics.Process (WSHost)}


Converting

Once you have your array, you might need to transform it into a different format for reporting or saving it.

Converting examples
PS C:\> $serverstatus | ConvertTo-Csv -NoTypeInformation      #converts the object array into a Comma Separated Value (CSV) format

"ServerName","TimeStamp","RDPPort","Results"
"server1","2015-06-26T09:35:51","3389","Up"
"server2","2015-06-26T09:35:52","3389","Up"
"server3","2015-06-26T09:35:53","3389","Up"
"server4","2015-06-26T09:35:54","3389","Up"
"server5","2015-06-26T09:35:55","3389","Up"


PS C:\> $serverstatus | ConvertTo-Html -Title "Server Status"              #HTML - web pages



Server Status

ServerNameTimeStampRDPPortResults
server12015-06-26T09:35:513389Up
server22015-06-26T09:35:523389Up
server32015-06-26T09:35:533389Up
server42015-06-26T09:35:543389Up
server52015-06-26T09:35:553389Up
PS C:\> $serverstatus | ConvertTo-Json #The JSON format is widely used in web API and stores nested object arrays. [ { "ServerName": "server1", "TimeStamp": "2015-06-26T09:35:51", "RDPPort": "3389", "Results": "Up" }, { "ServerName": "server2", "TimeStamp": "2015-06-26T09:35:52", "RDPPort": "3389", "Results": "Up" }, { "ServerName": "server3", "TimeStamp": "2015-06-26T09:35:53", "RDPPort": "3389", "Results": "Up" }, { "ServerName": "server4", "TimeStamp": "2015-06-26T09:35:54", "RDPPort": "3389", "Results": "Up" }, { "ServerName": "server5", "TimeStamp": "2015-06-26T09:35:55", "RDPPort": "3389", "Results": "Up" } ]


Exporting

Exporting is basically the same thing as ConvertTo-____ + save it to a file. So Export-CSV .\filename.csv is the same thing as ConvertTo-CSV | Set-Content .\filename.csv

PS C:\> $serverstatus | Export-Csv myserverstatus.csv -Verbose   #You'll use CSV's a lot as they open up easily in excel

VERBOSE: Performing the operation "Export-Csv" on target "myserverstatus.csv".



PS C:\> $serverstatus | Export-Clixml myserverstatus.xml -Verbose   #Exports to XML format, supports nested object arrays

VERBOSE: Performing the operation "Export-Clixml" on target "myserverstatus.xml".


In Part 3, we'll cover building custom objects from scratch and touch more on hash tables.

No comments: