试图弄清楚为什么我声明的变量没有被使用。我想知道是否有一些我不知道的行为,并希望有些人可以启发我。在我的脚本开头,我基本上创建了一个函数,要求用户输入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\
答案 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 }}