2016-05-11 9 views
1

Ich möchte ein Muster entwickeln, um einfach zwischen "Ansichten" von Daten zu wechseln, wenn Sie eine PowerShell-Funktion ausführen, die eine Verbindung zu einer Datenbank herstellt.Verwenden PSTypeNames, um Invoke-SqlCmd Datenelemente

zu diesem Artikel Basierend Quick Hits: Set the Default Property Display in PowerShell on Custom Objects, ich erstellt:

<# 
.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 

} 

Wenn die -View Parameter nicht angegeben wird, wird die All Einstellung verwendet:

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 

Wenn die -View Parameter angegeben wird, Die Standardansicht wurde geändert:

PS> Get-CustomObject Contact 

City  Region Telephone 
----  ------ --------- 
A78D794C MN  6125551212 
FDB79B27 MN  6125551212 
49D073FE MN  6125551212 
0716DF7E MN  6125551212 
29FF9D4E MN  6125551212 

Fragen:

  • Gibt es eine effizientere Möglichkeit, dies zu tun?
  • Kann die PSTypeNames für die Abfrage als Ganzes festgelegt werden, anstatt sie jeder Zeile zuzuordnen (wodurch die Notwendigkeit für die Foreach entfällt)?
  • Kann jedem Element im Validierungssatz ein Alias ​​zugewiesen werden? Zum Beispiel würde PS> Get-CustomObject d die Ansicht Demographics verwenden.

Antwort

2

Gibt es eine effizientere Möglichkeit, dies zu tun?

Nicht so weit ich weiß. Wenn die Ausgabe von Invoke-SQLCMD eine pscustomobject oder ein anderer "universeller" Typ wie DataRow usw. ist, müssen Sie den Typnamen ändern, da Ansichten mit Typnamen verknüpft sind.

Kann die PSTypeNames für die Abfrage als Ganzes festgelegt werden, anstatt sie jeder Zeile zuzuweisen (wodurch die Notwendigkeit für die Foreach entfällt)?

Nicht, wenn das Cmdlet dies nicht unterstützt.

Ansichten in Powershell werden basierend auf dem ersten zurückgegebenen Objekt aufgrund der Funktionsweise der Pipeline ausgewählt (weiß nicht, wie viele Objekte kommen). Wenn Sie also ein Dummy-Objekt in die Ausgabe aufnehmen können, können Sie beginnen indem Sie ein Dummy-Objekt mit dem korrekten Typennamen in die Pipeline werfen, um die richtige Ansicht zu erhalten. Auf diese Weise müssten Sie die anderen Objekte nicht ändern.

Beachten Sie, dass der Typname der anderen Objekte immer noch pscustomobject, DataRow usw. wäre, so dass dies nur ein Hack ist, damit die Ansicht funktioniert.

Ex:

<# 
.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' 

} 

Kann ein Alias ​​für jedes Element in dem Validate-Set zugeordnet werden? Zum Beispiel würde PS> Get-CustomObject d die Ansicht Demographics verwenden.

Nicht mit ValidateSet AFAIK wie es die genauen Werte validiert. Wenn Sie PowerShell 5 haben, können Sie es durch eine enum ersetzen, die funktionieren würde.

Probe:

enum GetCustomObjectViews { 
    Demographics 
    Contact 
    All 
} 

function Get-CustomObject { 

    param(
     [Parameter(Position=0)] 
     [alias('v')] 
     [GetCustomObjectViews]$View='All' 
    ) 

    #....  
} 

Get-CustomObject -View d