PowerShell 创建对象的时候,对象的属性可以是单一属性,也可以在这个属性里面包括多个对象,也就是嵌套的对象属性。


怎么实现嵌套的对象呢,下面看个简单的例子。


首先我写了两个function,分别是获取磁盘信息和服务。

FunctionGet-DiskInfo{[cmdletbinding()]Param([parameter(Mandatory=$true,ValueFromPipeline=$true)][string[]]$computername,[int]$MinimumFreePercent=10,[string]$errorfile="c:\errors.txt")$disks=Get-WmiObject-ClassWin32_Logicaldisk-Filter"Drivetype=3"-ComputerName$computername-ErrorActionSilentlyContinue-ErrorVariableerr$result=foreach($diskin$disks){$perFree=($disk.FreeSpace/$disk.Size)*100;if($perFree-ge$MinimumFreePercent){$OK=$True}else{$OK=$False};$disk|Select@{n="Computer";e={$disk.pscomputername}},DeviceID,VolumeName,`@{n="Size";e={"{0:N2}"-f($_.Size/1GB)}},`@{n="FreeSpace";e={"{0:N2}"-f($_.Freespace/1GB)}},`@{Name="OK";Expression={$OK}}}$resultif($err-ne$null){Write-verbose"Therearesomeerrors,pleasecheckdetailsfromthelogfiles"$err|Out-File$Errorfile}else{Write-Verbose"CompleteSuccessfully"}}functionGet-ComputerService{param([string[]]$computername="localhost")get-wmiobject-ComputerName$computername-Classwin32_service-Filter"Statelike'Running'"|select@{n="ComputerName";e={$_.pscomputername}},`name,displayname,Processid,`@{n="VirtualMemory";e={get-process-id$_.processid|select-ExpandPropertyvirtualMemorysize}},`@{n="PeakPagefileUsage(M)";e={get-process-id$_.processid|select@{n="PeakPagedMemorySize(M)";e={"{0:N2}"-f($_.PeakPagedMemorySize/1MB)}}|select-ExpandProperty"PeakPagedMemorySize(M)"}},`@{n="Threadscount";e={(get-process-id$_.processid|select-expandthreads).count}}|ft}


执行看看


然后我再创建一个新的function,在这个function里面自定义了一个对象,这个对象的disksinfo属性由Get-DiskInfo 创建多个对象;Services属性由Get-computerservice获取多个对象。


functionGet-DetailedInfo{[cmdletbinding()]param([string[]]$ComputerNames)foreach($computernamein$computernames){$disks=get-diskinfo-computername$ComputerName$service=Get-ComputerService-computername$ComputerName$props=@{'ComputerName'=$computerName;'disksInfo'=$disks;'Services'=$service}$obj=New-Object-TypeNamepsobject-Property$props$obj}}


然后我们看看结果, 可以看见对应的属性本身就包括了多个对象。

这样的话,创建嵌套的对象是成功了,但是看起来很不方便。如果我想查看对应的disksinfo怎么办,一般可以通过以下几种方式查看。


1. select -expand 这个可以把整个数组对象的内容扩展开来,同时还能自动转换成字符串类型

Get-DetailedInfo-ComputerNamessydwsus|select-ExpandPropertydisksinfo



2.Format-custom 这个会展示整个对象的结构

Get-DetailedInfo-ComputerNamessydwsus|Format-Custom*

3. 手动的循环展开也是可以的

Get-DetailedInfo-ComputerNamessydwsus|foreach{$_.disksInfo}

4. PowerShell3 以后的版本也可以直接当做数组处理~

(Get-DetailedInfo-ComputerNamessydwsus).disksinfo



现在可以查看了,如何把整个结果保存下来呢?


传统的很多习惯是保存为csv格式,我们来试试

Get-DetailedInfo-ComputerNamesydwsus|Export-Csvc:\temp\info.csv


打开确认一下 额 这是怎么回事?

CSV文件这种平面的结构是无法显示多重深度的对象的,因此他只能显示个对象类型,意思就是这个类型有多个对象需要显示,但是我没法在CSV里面显示出来。


那应该怎么处理呢?这里适合使用xml文件。


比如说

Get-DetailedInfo-ComputerNamesydwsus|Export-Clixmlc:\temp\info.xml


这样就可以保存了。