Получение динамического параметра базы данных на сервере SQL

Я создаю функцию PS с 2 параметрами: $ server & $database. Мне нужно, чтобы параметр $database заполнялся автоматически (набор динамической проверки), в зависимости от первого параметра ($server)

Я получил большую часть кода отсюда

Однако это не работает. Что я здесь не так делаю? Любое понимание очень ценится. Спасибо.

function Get-databases {
    [CmdletBinding()]
    Param(
        # Any other parameters can go here              

        [Parameter(Mandatory)][string] $Server 

    )

    DynamicParam {
            # Set the dynamic parameters' name
            $ParameterName = 'Database'

            # Create the dictionary 
            $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary

            # Create the collection of attributes
            $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]

            # Create and set the parameters' attributes
            $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
            $ParameterAttribute.Mandatory = $true
            $ParameterAttribute.Position = 1

            # Add the attributes to the attributes collection
            $AttributeCollection.Add($ParameterAttribute)

            # Generate and set the ValidateSet             
            $arrSet = (Invoke-Sqlcmd -ServerInstance $server  -query 'select name from sys.databases order by 1'   -ConnectionTimeout 60 -QueryTimeout 99999).name                         
            $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet)

            # Add the ValidateSet to the attributes collection
            $AttributeCollection.Add($ValidateSetAttribute)

            # Create and return the dynamic parameter
            $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)
            $RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)
            return $RuntimeParameterDictionary
    }

    begin {
        # Bind the parameter to a friendly variable
        $db = $PsBoundParameters[$ParameterName]
    }

    process {
        # Your code goes here
        $db 

    }

}

2 ответа

Решение

Если у вас есть Invoke-SqlCmd в атрибуте DynamicParam ValidateSet, завершение вашей вкладки выполнит все Invoke-SqlCmd для проверки это очень дорого по сравнению с производительностью.

Вы можете дать некоторые xyz значение -DataBase без использования табуляции, вы увидите, что оно проверяет ввод, но займет немного времени, так как выполнит Invoke-SqlCmd для проверки.

Поэтому я бы посоветовал не использовать DynamicParams или избегать проверки в DynamicParam, вы можете иметь явную проверку в Begin блок.

Вот окончательный код:

import-module sqlps
function Get-Database {
    <# 
        .SYNOPSIS 
            Dynamic validationset of databases      

    #>  
    #Requires -Version 3.0
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory)][string]$server

    )

    DynamicParam {

        $newparams = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
        $paramattributes = New-Object System.Management.Automation.ParameterAttribute
        $paramattributes.ParameterSetName = "__AllParameterSets"
        $paramattributes.Mandatory = $false
        $systemdbs = @("master", "msdb", "model", "SSIS", "distribution")

        $srv = New-Object 'Microsoft.SqlServer.Management.SMO.Server' "$server"
        $dblist = ($srv.Databases).name | Where-Object { $systemdbs -notcontains $_ }

        $argumentlist = @()

        foreach ($db in $dblist) {
            $argumentlist += [Regex]::Escape($db)
        }

        $validationset = New-Object System.Management.Automation.ValidateSetAttribute -ArgumentList $argumentlist
        $combinedattributes = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]
        $combinedattributes.Add($paramattributes)
        $combinedattributes.Add($validationset)
        $Databases = New-Object -Type System.Management.Automation.RuntimeDefinedParameter("Databases", [String[]], $combinedattributes)        
        $newparams.Add("Databases", $Databases)     
        return $newparams

    }

    process {

        $UserDb = $psboundparameters.Databases

        Write-Host "You picked: $UserDb"
    }
}

Clear-Host 
Get-Database -server 'YourServerName' -Databases 'DynamicallyPopulatedDatabases'
Другие вопросы по тегам