我想开发一种模式,可以轻松切换视图'执行连接到数据库的PowerShell函数时的数据。
根据这篇文章Quick Hits: Set the Default Property Display in PowerShell on Custom Objects,我创建了:
<#
.NOTES
Assumes a table named `Person` with columns `FirstName`,`LastName`,`Gender`,`BirthDate`,`City`,`Region`,`Telephone`
#>
function Get-CustomObject {
param(
[Parameter(Position=0)]
[ValidateSet('Demographics','Contact','All')]
[alias('v')]
[System.String]$View='All'
)
Remove-TypeData -TypeName User.Information -ErrorAction SilentlyContinue
Switch ($View) {
'Demographics' { Update-TypeData -TypeName User.Information -DefaultDisplayPropertySet FirstName,LastName,Gender }
'Contact' { Update-TypeData -TypeName User.Information -DefaultDisplayPropertySet City,Region,Telephone }
}
Invoke-SqlCmd -ServerInstance ServerName -Database DatabaseName -Query 'SELECT * FROM Person' |
ForEach {
# assign typename
$_.PSTypeNames.Insert(0,'User.Information')
# return object
$_
} # / ForEach
}
如果未指定-View
参数,则使用All
设置:
PS> Get-CustomObject
Id : 20
FirstName : DCD65A17
LastName : 05016468
City : 4DF12729
Region : MN
Telephone : 6125551212
Gender : F
Occupation : abcdefghij
Birthdate : 1/1/1900 12:00:00 AM
指定-View
参数时,将修改默认视图:
PS> Get-CustomObject Contact
City Region Telephone
---- ------ ---------
A78D794C MN 6125551212
FDB79B27 MN 6125551212
49D073FE MN 6125551212
0716DF7E MN 6125551212
29FF9D4E MN 6125551212
问题:
PSTypeNames
,而不必将其分配给每一行(因此无需Foreach
)吗?PS> Get-CustomObject d
将使用Demographics
视图。 答案 0 :(得分:2)
有更好的方法吗?
据我所知。如果Invoke-SQLCMD
的输出是pscustomobject
或其他“通用”类型,例如DataRow
等,那么您需要修改类型名称,因为视图链接到类型名称。
是否可以为整个查询设置PSTypeNames
,而不必将其分配给每一行(从而无需Foreach
)? < / p>
如果cmdlet不支持,则不行。
powershell中的视图是根据第一个返回的对象选择的,因为管道的工作原理(不知道有多少对象会出现),所以如果你能负担得起在输出中包含一个虚拟对象,你可以从在管道中抛出一个带有正确typename的虚拟对象,以获得正确的视图。这样你就不需要修改其他对象了。
请注意,其他对象的类型名称仍然是pscustomobject
,DataRow
等,所以这只是让视图生效的黑客。
例如:
<#
.NOTES
Assumes a table named `Person` with columns `FirstName`,`LastName`,`Gender`,`BirthDate`,`City`,`Region`,`Telephone`
#>
function Get-CustomObject {
param(
[Parameter(Position=0)]
[ValidateSet('Demographics','Contact','All')]
[alias('v')]
[System.String]$View='All'
)
Remove-TypeData -TypeName User.Information -ErrorAction SilentlyContinue
Switch ($View) {
'Demographics' { Update-TypeData -TypeName User.Information -DefaultDisplayPropertySet FirstName,LastName,Gender }
'Contact' { Update-TypeData -TypeName User.Information -DefaultDisplayPropertySet City,Region,Telephone }
}
#Output dummy-object (you can remove every property except pstypename and ONE random property,
#but to avoid "null value expcetion" later I would include the properties you know about
New-Object psobject @{
pstypename = "User.Information"
FirstName = "N/A"
LastName = "N/A"
Gender = "N/A"
BirthDate = "N/A"
City = "N/A"
Region = "N/A"
Telephone = "N/A"
}
#Real data
Invoke-SqlCmd -ServerInstance ServerName -Database DatabaseName -Query 'SELECT * FROM Person'
}
是否可以为验证集中的每个项目分配别名?例如,PS> Get-CustomObject d
会使用Demographics
视图。
不使用ValidateSet
AFAIK,因为它验证了确切的值。如果您有PowerShell 5,则可以使用enum
替换它。
样品:
enum GetCustomObjectViews {
Demographics
Contact
All
}
function Get-CustomObject {
param(
[Parameter(Position=0)]
[alias('v')]
[GetCustomObjectViews]$View='All'
)
#....
}
Get-CustomObject -View d