有没有办法将凭据传递给基于点的脚本?

时间:2019-09-18 14:54:33

标签: powershell

我是PowerShell的新手,并且一直在尝试将凭据传递给基于点的脚本。想法是有一个我可以加载的主文件,然后使用源函数,它会更干净。

这是到目前为止我尝试过的一个例子:

Functions.ps1

$credentials = Get-Credential -Message "Please enter your credentials."
. .\Unlock.ps1 -Credential $credentials

Unlock.ps1

function Unlock-Account {
  param(
    [Parameter(Mandatory = $true)]
    [string] $username,
    [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)] 
    [PSCredential] $Credential
  )
  try {
    Unlock-ADAccount -Identity $username -Credential $credentials
  }
  catch {
    Write-Output " Could not unlock $username"
  }
}

2 个答案:

答案 0 :(得分:1)

点源脚本不会自动调用源脚本中的函数。在您的情况下,通常要做的是这样:

$credentials = Get-Credential -Message "Please enter your credentials."
. .\Unlock.ps1
Unlock-Account 'somename' -Credential $credentials

如果您希望避免在每次调用该函数时都指定-Credential $credentials,则可以将凭据参数设为可选,并分配一个默认值:

Param(
    [Parameter(Mandatory=$true)]
    [string]$Username,

    [Parameter(
        Mandatory=$false,
        ValueFromPipelineByPropertyName=$true,
        ValueFromPipeline=$true
    )]
    [PSCredential]$Credential = $global:Credential
)

如果已经定义了变量$Credential,它将在全局范围内自动采用变量$Credential的值。但是请注意,如果在调用函数时未定义全局变量,则参数将为空值。


从技术上讲,您可以点源脚本并向其传递参数:

Param(
    [Parameter(Mandatory=$true)]
    [PSCredential]$Credential
)

function Unlock-Account {
    Param(
        [Parameter(Mandatory = $true)]
        [string]$Username,

        [Parameter(
            Mandatory=$false,
            ValueFromPipelineByPropertyName=$true,
            ValueFromPipeline=$true
        )]
        [PSCredential]$Credential = $script:Credential
    )
    ...
}

然后将脚本点源化并调用如下函数:

$credentials = Get-Credential -Message "Please enter your credentials."
. .\Unlock.ps1 -Credential $credentials
Unlock-Account 'somename'

但是,这种方法非常……非常规。我不建议您选择这条路线。

答案 1 :(得分:0)

获取源PS1可以有效地在会话中运行该文件的内容,就好像您已将整个内容复制并粘贴到命令行中一样。并没有真正将参数传递给点源文件的概念。

但是,有很多方法可以有效地完成您想做的事情。

一种方法是将要运行的命令添加到脚本末尾。因此,将以下内容添加到脚本文件的最后一行(在函数的大括号后):

# You could optionally add the line that gathers the credential here as well.
Unlock-Account -Credential $credentials

我个人不喜欢这种方法,因为它有时在您只希望功能可用时强迫您始终运行该功能。您可以执行此操作的另一种方法是使脚本文件像函数一样运行。本质上,您只需要删除脚本中的函数声明并保留其余部分即可。然后,您只需像调用函数一样调用脚本,而不是对其进行点源采购。

所以您的脚本内容变为:

param(
    [Parameter(Mandatory = $true)]
    [string] $username,
    [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)] 
    [PSCredential] $Credential
)
try {
    Unlock-ADAccount -Identity $username -Credential $credentials
}
catch {
    Write-Output " Could not unlock $username"
}

您这样称呼它:

.\Unlock.ps1 -Credential $credentials

此方法对于快速一次性脚本非常有用。但是,如果最终得到很多彼此相关的信息,那么creating a real PowerShell module可能会更好。

最后一个方法可能是使用最少的方法,但是如果您想保持脚本点源可用并且在点源时不实际调用任何东西,则仍然完全有效。您可以将dot source命令和函数调用组合成一个单行命令,如下所示:

. .\Unlock.ps1; Unlock-Account -Credential $credentials