Search code examples
powershellpowershell-3.0smo

Why doesn't powershell keep native types?


Consider the following code in a powershell script called NewDB.ps1:

param ($i, $d)

Function New-Database 
{
    param ($instance, $name)
    $db = New-Object Microsoft.SqlServer.Management.Smo.Database ($instance, $name) 
    try { $db.Create() }
    catch [Exception] { $_.Exception | Format-list | Out-String ; exit }
    $db.CreateDate.DateTime
    $db.DatabaseOptions.RecoveryModel
    return $db
}

[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | Out-Null
$sqlServer = new-Object Microsoft.SqlServer.Management.Smo.Server($i)
[Microsoft.SqlServer.Management.Smo.Database]$myDB = New-Database $sqlServer $d

I get a type conversion error:

PS C:\Users\moomin\Documents> .\NewDB.ps1 "(local)" "testDB"
Cannot convert the "System.Object[]" value of type "System.Object[]" to type
"Microsoft.SqlServer.Management.Smo.Database".
At C:\Users\moomin\Documents\NewDB.ps1:21 char:1
+ [Microsoft.SqlServer.Management.Smo.Database]$myDB = New-Database $sqlServer $d
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : ConvertToFinalInvalidCastException

How can I return the object back from my function as a Microsoft.SqlServer.Management.Smo.Database object? I need to do more things with it outside the function.

UPDATE Of course, thanks @mjolinor, this works exactly as I want now. BTW it also works fine with New-Database in a separate module (how I have actually implemented it).

param ($i, $d)

Function New-Database 
{
    param ($instance, $name)
    $db = New-Object Microsoft.SqlServer.Management.Smo.Database ($instance, $name) 
    try { $db.Create() }
    catch [Exception] { $_.Exception | Format-list | Out-String ; exit }
    $db
}

[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | Out-Null
$sqlServer = new-Object Microsoft.SqlServer.Management.Smo.Server($i)
$myDB = New-Database $sqlServer $d
$myDB.CreateDate.DateTime
$myDB.DatabaseOptions.RecoveryModel

Solution

  • A function should return only one type of object, and anything it outputs is part of the return, not just what follows the Return keyword, so your return is going to be an array of these 3 objects (this is why it's saying your return type is Object[])

     $db.CreateDate.DateTime
     $db.DatabaseOptions.RecoveryModel
     $db
    

    If you just want $db, only return $db.