Powershell 从PSObject转换为Datatable

Powershell 从PSObject转换为Datatable,powershell,Powershell,所以本质上我是在解析来自http://www.webcal.fi/en-GB/other_file_formats.php 通过调用WebRequest,并通过ConvertFrom-JSON cmdlet将其从JSON转换为PSObject 现在我需要将这些数据转换成SQL,我能想到的最有效的方法是将这个PSObject转换成一个Datatable,这样就可以重用已经存在的函数 在保持通用性的同时,我似乎想不出任何简单的方法来实现这一点,我不想将列名硬编码到我的Datatable中,而是从对象

所以本质上我是在解析来自http://www.webcal.fi/en-GB/other_file_formats.php 通过调用WebRequest,并通过ConvertFrom-JSON cmdlet将其从JSON转换为PSObject

现在我需要将这些数据转换成SQL,我能想到的最有效的方法是将这个PSObject转换成一个Datatable,这样就可以重用已经存在的函数

在保持通用性的同时,我似乎想不出任何简单的方法来实现这一点,我不想将列名硬编码到我的Datatable中,而是从对象本身提取它们。有什么想法吗

编辑

我不知道[数据表]是什么,因为我以前从未使用过它。似乎是ADO.NET的一部分

但是您可以通过编程方式获取[PSObject]的属性,使用hidden.PSObject属性,然后解析其.properties属性

另外,稍微挑剔一下,您可以对URI使用Invoke RestMethod,它会自动从JSON传输结果,因此您不需要Invoke WebRequest。

我不知道[datatable]是什么,因为我以前从未使用过它。似乎是ADO.NET的一部分

但是您可以通过编程方式获取[PSObject]的属性,使用hidden.PSObject属性,然后解析其.properties属性


另外,稍微挑剔一下,您可以对URI使用Invoke RestMethod,它会自动从JSON传输结果,因此您不需要Invoke WebRequest。

与PowerShell对象列表的主要区别在于,对于DataTable,所有项属性,包括项类型,对于每个“列”都是相同的,而PowerShell对象的列表具有使用每个特定项定义的所有属性。这意味着PowerShell对象列表可以在同一列中包含DataTime对象和Int16,这在DataTable中是不可能的

在这个已知的事实中,internet上大多数当前可用的ConvertTo-DataTable类cmdlet也存在陷阱,因为它们仅在第一个对象行上假定DataTable的列类型。因此,如下所示的简单自定义对象会导致错误或值被错误地解析为字符串:

@(
    New-Object PSCustomObject -Property @{Name = "a"; Value = 123}
    New-Object PSCustomObject -Property @{Name = "b"; Value = 123456789012}
) | ConvertTo-DataTable
当第一个对象包含$Null的项时,会出现类似的问题,其中整个列通常被假定为字符串类型,但应该是例如DateTime类型:

@(
    New-Object PSCustomObject -Property @{Name = "a"; Date = $Null}
    New-Object PSCustomObject -Property @{Name = "b"; Date = Get-Date}
) | ConvertTo-DataTable
解决方案是在一列中找到所有对象中最合适的最小公共类型,这需要时间,而且定义起来并不总是那么简单。例如,以UInt16和Int16这两种类型为例,您不能采用这两种类型中的任何一种,因为一种类型不完全包含另一种类型。UInt16的最小值为0,而Int16的最小值为-32768,UInt16的最大值为65535,而Int16的最大值为32767。也就是说,在这种情况下,最合适的最小通用类型不是原始类型,而是:UInt32或Int32*

cmdlet将自动解析最适合的最小公共类型,并将其用于列类型

*此处使用的cmdlet将采用先找到带类型的带签名与未签名的首选项

见:

语法 定义列类型:

$DataTable = $MyObject | ConvertTo-DataTable -ColumnType @{Name = [String]; Value = [Int64]; Date = [DateTime]}
转换PowerShell进程对象

转换用户语言列表


与PowerShell对象列表之间的主要区别在于,对于DataTable,所有项属性(包括项类型)对于每个“列”都是相同的,而PowerShell对象列表具有使用每个特定项定义的所有属性。这意味着PowerShell对象列表可以在同一列中包含DataTime对象和Int16,这在DataTable中是不可能的

在这个已知的事实中,internet上大多数当前可用的ConvertTo-DataTable类cmdlet也存在陷阱,因为它们仅在第一个对象行上假定DataTable的列类型。因此,如下所示的简单自定义对象会导致错误或值被错误地解析为字符串:

@(
    New-Object PSCustomObject -Property @{Name = "a"; Value = 123}
    New-Object PSCustomObject -Property @{Name = "b"; Value = 123456789012}
) | ConvertTo-DataTable
当第一个对象包含$Null的项时,会出现类似的问题,其中整个列通常被假定为字符串类型,但应该是例如DateTime类型:

@(
    New-Object PSCustomObject -Property @{Name = "a"; Date = $Null}
    New-Object PSCustomObject -Property @{Name = "b"; Date = Get-Date}
) | ConvertTo-DataTable
解决方案是在一列中找到所有对象中最合适的最小公共类型,这需要时间,而且定义起来并不总是那么简单。例如,以UInt16和Int16这两种类型为例,您不能采用这两种类型中的任何一种,因为一种类型不完全包含另一种类型。UInt16的最小值为0,而Int16的最小值为-32768,UInt16的最大值为65535,而Int16的最大值为32767。也就是说,在这种情况下,最合适的最小通用类型不是原始类型,而是:UInt32或Int32*

cmdlet将自动解析最适合的最小公共类型,并将其用于列类型

* 此处使用的cmdlet将采用先找到带类型的带签名与未签名的首选项

见:

语法 定义列类型:

$DataTable = $MyObject | ConvertTo-DataTable -ColumnType @{Name = [String]; Value = [Int64]; Date = [DateTime]}
转换PowerShell进程对象

转换用户语言列表


请参见编辑-它只返回一个包含JSON信息的属性。@PnP这根本不是JSON,它是关于属性的信息,并且info对象有一个.Value属性,看起来有点像JSON,但它也不是JSON。但这并不重要,因为您真正想要的是使用列的.Name。但是从你的帖子中,我会说你有一个嵌套对象,在尝试创建属性之前还不够深入。在这种情况下,我如何获得列名…这似乎是可行的:$content | gm-MemberType NoteProperty.NameSee edit-它只返回一个包含JSON信息的属性。@PnP这根本不是JSON,它是关于属性的信息,info对象有一个.Value属性,看起来有点像JSON,但它也不是JSON。但这并不重要,因为您真正想要的是使用列的.Name。但是从你的帖子中可以看出,你有一个嵌套对象,在尝试创建属性之前没有深入到足够的深度。在这种情况下,我如何获取列名…这似乎是可行的:$content | gm-MemberType NoteProperty.name两个问题:1这在严格模式下失败,由于$Types可能没有计数属性,因此2不处理DateTimeOffset。修复了版本中的两个问题:1在严格模式下失败,因为$Types可能没有Count属性2不处理DateTimeOffset。固定版本在
$DataTable = Get-Process 'PowerShell' | ConvertTo-DataTable
$DataTable = Get-WinUserLanguageList | ConvertTo-DataTable