在 SQL 服务器上获取动态数据库参数
Getting a dynamic database parameter on a SQL server
我正在创建一个带有 2 个参数的 PS 函数:$server 和 $database。我需要自动填充 $database 参数(动态验证集),具体取决于第一个参数($server)
我从 here
获得了大部分代码
但是它不起作用。我在这里做错了什么?非常感谢任何见解。谢谢你。
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
}
}
如果您在 DynamicParam ValidateSet 属性中有 Invoke-SqlCmd
,您的 Tab 完成将执行整个 Invoke-SqlCmd
验证,这是非常昂贵的 w.r.t 性能。
您可以在不使用 Tab 补全的情况下为 -DataBase 提供一些 xyz
值,您会看到它正在验证输入,但会花费很少的时间,因为它将执行 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'
我正在创建一个带有 2 个参数的 PS 函数:$server 和 $database。我需要自动填充 $database 参数(动态验证集),具体取决于第一个参数($server)
我从 here
获得了大部分代码但是它不起作用。我在这里做错了什么?非常感谢任何见解。谢谢你。
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
}
}
如果您在 DynamicParam ValidateSet 属性中有 Invoke-SqlCmd
,您的 Tab 完成将执行整个 Invoke-SqlCmd
验证,这是非常昂贵的 w.r.t 性能。
您可以在不使用 Tab 补全的情况下为 -DataBase 提供一些 xyz
值,您会看到它正在验证输入,但会花费很少的时间,因为它将执行 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'