存储的变量未被传递

时间:2015-07-29 18:28:16

标签: variables powershell active-directory

试图弄清楚为什么我声明的变量没有被使用。我想知道是否有一些我不知道的行为,并希望有些人可以启发我。在我的脚本开头,我基本上创建了一个函数,要求用户输入AD用户ID并将其存储为变量。然后我使用该变量来检查它是否在AD中。它会循环,直到输入有效的用户ID。然后它获取userid变量并检查指定目录中是否存在具有userid变量名称的文件夹。

代码似乎按预期执行,但userid变量未被传递到脚本底部。为了验证它,我写出了脚本看到的变量。下面是脚本和输出。有什么想法吗?

#Function to obtain userid and check if id exists in Active Directory
Function IDCHECK {
  $error.clear()
  $useid = Read-Host 'Enter the User ID to set the permission'
  Try {Get-ADUser $useid > $null}
  Catch {"UserID does not exist.  Check the UserID and try again."}
  IF (!$error) {
    Write-Host $useid "exists in AD...proceeding" -foregroundcolor Green
  }
}

Do {IDCHECK}
While ($error.count -gt 0)

#Test if folder with name of userid exists
IF (Test-Path C:\Temp\$useid) {
  $homefolder="C:\Temp\$useid"
  Write-Host "Folder exists...proceeding to apply permission" -foregroundcolor Green
  Write-Host "Processing User:" $useid
  Write-Host "Current Directory to act upon:" $homefolder
}

这是输出:

~~~~~~~~ Folder Permission Application Script ~~~~~~~
Enter the User ID to set the permission: tdr
tdr exists in AD...proceeding
Folder exists...proceeding to apply permission
Processing User: 
Current Directory to act upon: C:\Temp\

3 个答案:

答案 0 :(得分:3)

快速测试似乎表明在do {}块中调用你的函数在非当前作用域中运行它(也许它将它视为一个脚本并赋予它自己的作用域?)。

因此,这意味着您在函数中对$useid的赋值未在全局范围内完成,因此无法从函数/ do块外部看到。

这使得此问题的解决方案明确地分配给函数中的全局变量。

$global:useid = Read-Host 'Enter the User ID to set the permission'

答案 1 :(得分:0)

为变量赋值时,还必须考虑变量的范围。

如果你想在函数范围之外保存变量$ useid,你可以在变量名前加脚本或全局。

因此保存用户ID的代码将是。

$global:useid = Read-Host 'Enter the User ID to set the permission'

如果您想了解有关该主题的更多信息,请阅读以下有关powershell中变量范围的article

查看以下示例脚本,了解如何在函数内部使用本地作用域,因此在离开函数时实际上会破坏该变量。

function testVariableScope
{
    $var1 = "setup in testVariableScope function"
    return $var1
}
$var1 = $null
echo "`$var1=$var1"
echo "running function" 
testVariableScope > $null
echo "`$var1=$var1"
echo "running again, and assign var1 to return value"
$var1 = testVariableScope
echo "`$var1=$var1"

输出:

$var1=
running function
$var1=
running again, and assign var1 to return value
$var1=setup in testVariableScope function

答案 2 :(得分:0)

正如其他人已经指出的那样,您的问题是由不同范围内的同名变量引起的,可以通过使用全局变量来缓解。但是,对于various reasons,我建议反对实际执行此操作。例如,很难跟踪代码中任何给定点的全局变量的值,因为它们可以在代码中的任何位置进行更改,这会使您的代码更难理解,更难以测试。它们还可能在代码的其他不相关部分之间引入不需要/不需要的依赖关系,这使得维护或模块化代码变得更加困难。

从编码角度来看,更好的方法是让函数返回经过验证的用户ID,并在返回值不是$null时退出循环:

function Get-ValidatedId {
  $id = Read-Host 'Enter the User ID to set the permission'
  if (Get-ADUser -Filter "SamAccountName -eq '$id'") {
    $id
  } else {
    Write-Host "UserID '$id' does not exist. Check the UserID and try again."
  }
}

do {
  $userID = Get-ValidatedId
} until ($userID -ne $null)

你甚至可以将循环重构为函数:

function Get-ValidatedId {
  do {
    $id = Read-Host 'Enter the User ID to set the permission'
    if (-not (Get-ADUser -Filter "SamAccountName -eq '$id'")) {
      Write-Host "UserID '$id' does not exist. Check the UserID and try again."
      $id = $null
    }
  } until ($id -ne $null)
  $id
}

$userID = Get-ValidatedId

上面的代码示例使用Get-ADUser的过滤器表达式来避免在不存在的帐户名称时出错,并使用approved verb以使函数名称符合PowerShell {{3 }}