将a转换PSCustomObject
为a 的最简单方法是Hashtable
什么?它显示就像一个带有splat运算符,花括号和看似是键值对的那个.当我尝试将它投射到[Hashtable]
它不起作用.我也试过.toString()
,分配的变量说它是一个字符串,但没有显示任何 - 任何想法?
首先,因为这引出了我的问题,我首先要指出我在PowerShell中使用了XML,以及如何将XML文件中的数据快速地读入自定义对象数组.例如,如果我有以下XML文件:
<stuff>
<item name="Joe" age="32">
<info>something about him</info>
</item>
<item name="Sue" age="29">
<info>something about her</info>
</item>
<item name="Cat" age="12">
<info>something else</info>
</item>
</stuff>
Run Code Online (Sandbox Code Playgroud)
如果我简单地阅读它,就像这样:
[xml]$myxml = Get-Content .\my.xml
Run Code Online (Sandbox Code Playgroud)
然后我可以得到一个像我这样的项目数组:
[array]$myitems = $myxml.stuff.Item
$myitems
name age info
---- --- ----
Joe 32 something about him
Sue 29 something about her
Cat 12 something else
Run Code Online (Sandbox Code Playgroud)
那么,现在我的问题是:
如何创建自定义对象数组的类似结构,并在我的脚本中初始化它们,而无需读取文件?
我可以做很多循环和/或大量创建/初始化单个对象,然后一次添加一个数组...
但似乎应该有一种方法以更简单的方式执行此创建/初始化.请注意,这里的关键是我的自定义对象有两个以上的元素(否则,我已经使用了哈希).
我甚至考虑过创建一个大的XML字符串,并使用Select-XML,但我只是无法正确使用语法(如果这是正确的方向,那就是正确的方向).
下面的代码给了我一个PSCustomObjects数组,如何让它返回一个字符串数组?
$files = Get-ChildItem $directory -Recurse | Select-Object FullName | Where-Object {!($_.psiscontainer)}
Run Code Online (Sandbox Code Playgroud)
(作为第二个问题,什么是psiscontainer部分?我从网上的例子中复制了它)
接受后编辑:两个很好的答案,希望我可以标记它们.已经给出了原始答案.
在PowerShell v3.0 PSCustomObject
中引入了.就像PSObject
,但更好.在其他改进中(例如保留属性顺序),简化了从哈希表创建对象:
[PSCustomObject]@{one=1; two=2;}
Run Code Online (Sandbox Code Playgroud)
现在看来这句话很明显:
[System.Management.Automation.PSCustomObject]@{one=1; two=2;}
Run Code Online (Sandbox Code Playgroud)
将以相同的方式工作,因为它PSCustomObject
是完整命名空间+类名的"别名".相反,我得到一个错误:
无法将类型"System.Collections.Hashtable"的"System.Collections.Hashtable"价值型"System.Management.Automation.PSCustomObject".
我列出了两种类型对象的加速器:
[accelerators]::get.GetEnumerator() | where key -Like ps*object
Key Value
--- -----
psobject System.Management.Automation.PSObject
pscustomobject System.Management.Automation.PSObject
Run Code Online (Sandbox Code Playgroud)
并发现它们都引用了同一个PSObject
类 - 这意味着使用加速器可以做一些其他的东西,而不仅仅是缩短代码.
我对这个问题的疑问是:
powershell pscustomobject psobject powershell-5.0 type-accelerators
我正在写一个脚本Powershell
,导出所有securitygroups
和他们members
的Active Directory
.现在我想格式化输出.csv
.
代码:
$Groups = Get-ADGroup -Properties * -Filter * -SearchBase "OU=SERVICES,DC=XXXXXX,DC=XXXXX"
$Table = @()
$Record = @{
"Group Name" = ""
"Name" = ""
"Username" = ""
}
Foreach($G In $Groups)
{
$Arrayofmembers = Get-ADGroupMember -identity $G -recursive | select name,samaccountname
Foreach ($Member in $Arrayofmembers)
{
$Record."Group Name" = $G.Name
$Record."Name" = $Member.name
$Record."UserName" = $Member.samaccountname
$objRecord = New-Object PSObject -property $Record
$Table += $objrecord
}
}
$Table | …
Run Code Online (Sandbox Code Playgroud) 我已经使用PowerShell多年了,我认为我已经掌握了一些更"古怪"的行为,但我遇到了一个问题,我无法做出头脑或尾巴...
我总是使用"return"来返回函数的值,但最近我想我会把Write-Output作为替代.但是,PowerShell是PowerShell,我发现一些似乎没有意义的东西(对我来说,至少):
function Invoke-X{ write-output @{ "aaa" = "bbb" } };
function Invoke-Y{ return @{ "aaa" = "bbb" } };
$x = Invoke-X;
$y = Invoke-Y;
write-host $x.GetType().FullName
write-host $y.GetType().FullName
write-host ($x -is [hashtable])
write-host ($y -is [hashtable])
write-host ($x -is [pscustomobject])
write-host ($y -is [pscustomobject])
Run Code Online (Sandbox Code Playgroud)
输出:
System.Collections.Hashtable
System.Collections.Hashtable
True
True
True
False
Run Code Online (Sandbox Code Playgroud)
$ x和$ y(或'write-output'和'return')之间有什么区别,这意味着它们都是哈希表,但只有其中一个'-is'是一个pscustomobject?有没有一种通用的方法我可以确定与代码的区别,除了显然检查我在变量中的每个哈希表是否也是一个pscustomobject)?
我的$ PSVersionTable看起来像这样,以防此行为特定于特定版本的PowerShell:
Name Value
---- -----
PSVersion 5.1.16299.492
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.16299.492
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion …
Run Code Online (Sandbox Code Playgroud) 阅读有关自定义对象的文章:
http://technet.microsoft.com/en-us/library/ff730946.aspx
我想知道为什么我得到单个条目的结果:例如$ objAverage.Name
虽然通过$ colAverages.Name没有被撤回.虽然Get-Member都显示[System.Object] NoteProperty Name
我希望在$ colAverages中返回结果集的所有名称.
文章代码:C:\ Temp\base.txt
Name,AtBats,Hits
Ken Myer,43,13
Pilar Ackerman,28,11
Jonathan Haas,37,17
Syed Abbas,41,20
Luisa Cazzaniga,22,6
Andrew Cencini,35,11
Baris Cetinok,19,4
Run Code Online (Sandbox Code Playgroud)
电源外壳:
$colAverages = @()
$colStats =Import-Csv C:\Temp\base.txt
foreach ($objBatter in $colStats)
{
$objAverage = New-Object System.Object
$objAverage | Add-Member -type NoteProperty -name Name -value $objBatter.Name
$objAverage | Add-Member -type NoteProperty -name BattingAverage -value ("{0:N3}" -f ([int] $objBatter.Hits / $objBatter.AtBats))
$colAverages += $objAverage
}
$colAverages | Sort-Object BattingAverage -descending
Run Code Online (Sandbox Code Playgroud) 有没有一种巧妙的方法可以将 a 转换PSCustomObject
为自定义类作为 PowerShell 5.1 中的函数参数?自定义对象包含附加属性。
我希望能够做这样的事情:
class MyClass {
[ValidateNotNullOrEmpty()][string]$PropA
}
$input = [pscustomobject]@{
PropA = 'propA';
AdditionalProp = 'additionalProp';
}
function DuckTypingFtw {
[CmdletBinding()]
param(
[Parameter(Mandatory = $True, Position = 0, ValueFromPipeline)] [MyClass] $myObj
)
'Success!'
}
DuckTypingFtw $input
Run Code Online (Sandbox Code Playgroud)
不幸的是Success!
,我得到的不是:
DuckTypingFtw:无法处理参数“myObj”的参数转换。无法将值“@{PropA=propA;AdditionalProp=additionalProp}”转换为类型“MyClass”。错误:“无法转换”@{PropA=propA; “AdditionalProp=additionalProp}”
类型“System.Management.Automation.PSCustomObject”的值要键入“MyClass”。在 C:\temp\tmp.ps1:23 字符:15 + DuckTypingFtw $input + ~~~~~~ + CategoryInfo : InvalidData: (:) [DuckTypingFtw], ParameterBindingArgumentTransformationException + ExcellentQualifiedErrorId : ParameterArgumentTransformationError,DuckTypingFtw
如果我注释掉AdditionalProp
,一切正常。
基本上,我想要实现的目标是从一个函数返回一个对象并将其传递给第二个函数,同时确保第二个函数的参数具有所有预期的属性。
我试图理解为什么当我导入一个大约 16MB 的文件作为变量时 PowerShell 的内存膨胀这么多。我可以理解围绕该变量存在额外的内存结构,但我只是想了解它为什么那么高。这是我在下面所做的 - 只是任何人都可以运行的另一个脚本的精简片段。
笔记/问题
我的测试代码
Invoke-WebRequest -uri "http://s3.amazonaws.com/alexa-static/top-1m.csv.zip" -OutFile C:\top-1m.csv.zip
Expand-Archive -Path C:\top-1m.csv.zip -DestinationPath C:\top-1m.csv
$alexaTopMillion = Import-Csv -Path C:\top-1m.csv
Run Code Online (Sandbox Code Playgroud)
对任何回答这个问题的人:感谢您的时间并帮助我每天学习更多!
memory powershell memory-profiling pscustomobject import-csv
我觉得很愚蠢,我无法弄清楚这一点,但假设我有一个包含 pscustomobjects 的数组。以令人难以置信的高水平来看以下示例:
$arr = @()
$obj1 = [pscustomobject]@{prop1="bob";prop2="dude";prop3="awesome"}
$obj2 = [pscustomobject]@{prop1="bob";prop2="dude";prop3="awesome"}
$arr += $obj1
Run Code Online (Sandbox Code Playgroud)
在本例中,$obj1 和 $obj2 具有完全相同的项目/属性。如何测试 $testarr 是否包含 $obj1 的属性以避免将 $obj2 添加到其中?
请注意,上面是一个粗略的例子。pscustomobjects 是从数据集动态创建的并添加到数组中,但我想避免添加重复项。
我理解以下返回 true,但我完全期望任何给定的单个属性都有重复项。因此,我需要将整个 pscustomobject 和所有属性一起比较以获得唯一性。
$arr.Name -Contains 'Bob' #returns true
附带问题...为什么 $obj1 和 $obj2 本身不被视为相等?我认为这是因为它们在技术上是不同的对象,只是具有相同的值,但我不明白为什么会这样,但是两个不同的变量只有一个字符串测试是相同的。
$obj1 -eq $obj2 #returns false
$str1 = "test"
$str2 = "test"
$str1 -eq $str2 #returns true
Run Code Online (Sandbox Code Playgroud) powershell ×10
pscustomobject ×10
psobject ×2
arrays ×1
compare ×1
comparison ×1
csv ×1
formatting ×1
hashtable ×1
import-csv ×1
memory ×1
syntax ×1