Here’s an example of a PS object that has 3 properties, one is a ‘string’, one is an integer ‘unit32’, and one is a ‘double’:
$SampleObject = [PSCustomObject][Ordered]@{
ComputerName = $env:COMPUTERNAME
MemoryGB = [Math]::Round((Get-WmiObject Win32_ComputerSystem).TotalPhysicalMemory/1GB,1)
LogicalCores = (Get-WmiObject Win32_ComputerSystem -Property NumberofLogicalProcessors).NumberofLogicalProcessors
}
$SampleObject | FT -a
$SampleObject | Get-Member
ComputerName MemoryGB LogicalCores
------------ -------- ------------
MGMT-066VDI 63.9 48
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
ComputerName NoteProperty string ComputerName=MGMT-066VDI
LogicalCores NoteProperty uint32 LogicalCores=48
MemoryGB NoteProperty double MemoryGB=63.9
I’d like to create a copy of this $Sample object that has the same members with same property types but not the data (blanks/zeros)
I can list the object properties and identify their types as in:
$Properties = $SampleObject | Get-Member -MemberType NoteProperty | % {
[PSCustomObject][Ordered]@{
PropertyName = $_.Name
DataType = $_.Definition.Split(' ')[0]
}
}
$Properties | FT -a
PropertyName DataType
------------ --------
ComputerName string
LogicalCores uint32
MemoryGB double
Using Add-Member and trying to type-cast properties of a new object does not work:
$CopiedObject = New-Object -TypeName PSCustomObject
$Properties | % { $CopiedObject | Add-Member -MemberType NoteProperty -Name $_.Name -Value [$_.DataType]0 }
$CopiedObject | FT -a
This seems to fail because type-casting seems not to accept variables. The following attempts fail:
$DataType = 'String' [$DataType]0 [($DataType)]'0' [($DataType)]0 [($DataType)]'0' [$($DataType)]0 [$($DataType)]'0'
Also tried this but it copies both structure and data
$CopiedObject = $SampleObject.psobject.Copy() $CopiedObject | FT -a ComputerName MemoryGB LogicalCores ------------ -------- ------------ MGMT-066VDI 63.9 48
Copying the object and changing the property values to 0 does not work because it changes property types to int:
$CopiedObject = $SampleObject.psobject.Copy()
$CopiedObject | Get-Member -MemberType NoteProperty | % { $PropertyName = $_.Name; $CopiedObject.$PropertyName = 0 }
$CopiedObject | FT -a
$CopiedObject | Get-Member
ComputerName MemoryGB LogicalCores
------------ -------- ------------
0 0 0
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
ComputerName NoteProperty int ComputerName=0
LogicalCores NoteProperty int LogicalCores=0
MemoryGB NoteProperty int MemoryGB=0
I can do something like this:
$CopiedObject = New-Object -TypeName PSCustomObject
foreach ($Property in $Properties) {
switch ($Property.DataType) {
'String' { $CopiedObject | Add-Member -MemberType NoteProperty -Name $Property.PropertyName -Value ([String]0) }
'Uint32' { $CopiedObject | Add-Member -MemberType NoteProperty -Name $Property.PropertyName -Value ([Uint32]0) }
'Double' { $CopiedObject | Add-Member -MemberType NoteProperty -Name $Property.PropertyName -Value ([Double]0) }
}
}
$CopiedObject | FT -a
$CopiedObject | Get-Member
ComputerName LogicalCores MemoryGB
------------ ------------ --------
0 0 0
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
ComputerName NoteProperty string ComputerName=0
LogicalCores NoteProperty uint32 LogicalCores=0
MemoryGB NoteProperty double MemoryGB=0
but then I have to anticipate and list every possible datatype. There must be a better way…