powershell - Powershell Add-Member to Object(如果存在),否则为 New-Object
问题描述
我正在尝试更好地了解 PowerShell 以便更好地工作,并且在我的一个小项目中遇到了问题。我想遍历一组性能计数器并获取cookedvalue(例如:\memory\available mbytes 的cooked 值为4096,以显示4GB 可用内存)。
我希望我的输出采用 JSON 格式,其结构如下:
PERFORMANCE
MEMORY
PAGE_FAULTS/SEC = 673
%_COMMITED_MEMORY_IN_USE = 12
AVAILABLE_MBYTES = 4096
COMMITTED_BYTES = 3243
PROCESS(*)
%_PROCESSOR_TIME = 54
LOGICALDISK(C:)
DISK_READS/SEC = 462
这是下面我的脚本的当前状态。我正在努力掌握对象管理,并且真的可以朝着正确的方向轻推。该脚本工作正常(它使用 Get-Counter 获取cookedvalues,我可以打印结果)它只是以我遇到问题的逻辑方式将数据添加到对象。
$CounterPathList = "\Memory\Page Faults/sec", "\Memory\% Committed Bytes In Use", "\Memory\Available MBytes", "\Memory\Committed Bytes", "\Process(*)\% Processor Time", "\LogicalDisk(C:)\Disk Reads/sec"
$Performance = New-Object –TypeName PSObject
ForEach($CounterPath in $CounterPathList){
$PathRoot = ($CounterPath.split('\')[1]).ToUpper()
$Name = (($CounterPath -replace '.*\\') -replace " ","_").ToUpper()
$Value=((Get-Counter($CounterPath)).countersamples | select -property cookedvalue).cookedvalue
if(!($Performance | Where-Object -Property Name -eq $PathRoot)){
Add-Member -InputObject $Performance -MemberType NoteProperty –Name $PathRoot –Value "" -force
}else{
Add-Member -InputObject $Performance.$PathRoot -MemberType NoteProperty –Name $Name –Value $Value -force
}
}
$Performance | ConvertTo-JSON
上面的脚本当前输出:
$Performance | ConvertTo-JSON
{
"MEMORY": "",
"PROCESS(*)": "",
"LOGICALDISK(C:)": ""
}
解决方案
恕我直言,PowerShell JSON cmdlet ( -lt 5.1
) 过于不灵活 - 通常它们与 s 一起工作得更好PSCustomObject
。(一个例子见这篇文章的结尾,另一个例子是 V6ConvertFrom-Json
添加了一个-AsHashtable
开关)这是一种使用简单的方法来获得你想要的东西Hashtable
:
$counters = Get-Counter $wanted | select -ExpandProperty CounterSamples;
$toJson = @{ 'PERFORMANCE' = @{}};
foreach ($c in $counters) {
$computerName, $key, $subKey = $c.Path.Replace('\\', '') -split '\\';
$key = $key.ToUpper();
$subKey = ($subKey -replace '\s+', '_').ToUpper();
# each process has unique name => group by the common prefix
if ($key -match '^process\(') {
$subKey = $key;
$key = 'PROCESS(*)';
}
if (!$toJson.'PERFORMANCE'.ContainsKey($key)) {
$toJson.'PERFORMANCE'.$key = @{};
}
$toJson.'PERFORMANCE'.$key.$subKey = $c.CookedValue;
}
$serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer;
$serializer.Serialize($toJson) | Out-File $outfile;
# ConvertTo-JSON @($toJson) -Depth 10 | Out-File $outfile;
请注意,代码片段中的最后一行已被注释掉。虽然文档说明声明ConvertTo-Json
是通过使用JavaScriptSerializer 类实现的,但当我运行 cmdlet 时,JSON 嵌套Hashtable
在array
. 如果您关心空格/格式,潜在的缺点是JavaScriptSerializer.Serialize()
将所有内容转储到单行字符串中。
推荐阅读
- angular - Angular 子组件中的 ngIf
- javascript - Javascript 中的 Base64 图像编码
- ios - 如何在堆栈导航器中从子级到另一个子级 v5 进行嵌套导航?
- typescript - 在 TypeScript 中使用类和泛型 - 使用 new()?
- android - 如何打开应用程序的源代码并在android studio中运行?
- ios - 如何保存数据然后与 React Native 共享?
- html - 如果子菜单处于活动状态,如何打开下拉菜单?
- c# - RavenDB 4.x 替代 EscapeQueryOptions.RawQuery?
- jquery - Hibernate Search:如何查询父类中的字段?
- routes - 使用常规路由时没有大张旗鼓的操作