Search code examples
powershellsmo

Powershell Function Restrict Data Type


Trying to create a function like the following:

Function Get-SqlErrorLogPrevious24 {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory=$True,Position=1)]
        [Microsoft.SqlServer.Management.Smo.Server]$Server
    )

    ($Server.ReadErrorLog()).where{$_.logdate -ge ((Get-Date).AddHours(-24))}
}

What I've noticed though, is that I can pass in just a string and not a Server object.

Is there a way in Powershell to strongly enforce the data type being passed in or will it always implicitly convert a string to an SMO object?


Solution

  • No. PowerShell has several "strategies" that it uses to make sure what you receive in a function is the correct type. If it can use one of them to transform the value passed (in this case a string) to the required type (an SMO object) it will do that.

    Here is a great post which lists 10 different strategies.

    1. Direct assignment. If your input is directly assignable, simply cast your input to that type.
    2. Language-based conversion. These language-based conversions are done when the target type is void, Boolean, String, Array, Hashtable, PSReference (i.e.: [ref]), XmlDocument (i.e.: [xml]). Delegate (to support ScriptBlock to Delegate conversions), and Enum.
    3. Parse conversion. If the target type defines a Parse() method that takes that input, use that.
    4. Static Create conversion. If the target type defines a static ::Create() method that takes that input, use that.
    5. Constructor conversion. If the target type defines a constructor that takes your input, use that.
    6. Cast conversion. If the target type defines a implicit or explicit cast operator from the source type, use that. If the source type defines an implicit or explicit cast operator to the target type, use that.
    7. IConvertible conversion. If the source type defines an IConvertible implementation that knows how to convert to the target type, use that.
    8. IDictionary conversion. If the source type is an IDictionary (i.e.: Hashtable), try to create an instance of the destination type using its default constructor, and then use the names and values in the IDictionary to set properties on the source object.
    9. PSObject property conversion. If the source type is a PSObject, try to create an instance of the destination type using its default constructor, and then use the property names and values in the PSObject to set properties on the source object. . If a name maps to a method instead of a property, invoke that method with the value as its argument.
    10. TypeConverter conversion. If there is a registered TypeConverter or PSTypeConverter that can handle the conversion, do that. You can register a TypeConverter through a types.ps1xml file (see: $pshome\Types.ps1xml), or through Update-TypeData.