【问题标题】:Powershell script - asking for user input, re-run that section until the input is correctPowershell 脚本 - 要求用户输入,重新运行该部分,直到输入正确
【发布时间】:2018-03-29 18:03:23
【问题描述】:

我有一个非常广泛的 300 多行用户添加脚本,用 PowerShell 编写,专为非管理员设计,无需管理员权限(它会自我提升)也无需进入 ADUC 即可将用户添加到 Windows 域。

有一个部分(如下)要求提供电话号码、清理输入并正确格式化它们以同步到 Azure/O365。它还会检查以确保办公室和手机的输入是 10 位数字,如果不是,则会引发错误对话框。我想找到一种方法,不仅可以将错误框扔到一边,还可以让脚本返回到电话输入代码的顶部,让他们在点击“确定”按钮后重新输入数字。这就是我不知所措的地方 - 让它回到该部分的顶部。

提前致谢! =)

    # Phone code begins here
$phoneform = New-Object System.Windows.Forms.Form
$phoneform.Text = 'Phone numbers'
$phoneform.Size = '300, 200'
$phoneform.StartPosition = "CenterScreen"
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(75, 120)
$OKButton.Size = '75, 23'
$OKButton.Text = 'OK'
$OKButton.DialogResult = 'Ok'
$phoneform.Controls.Add($OKButton)
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = '160, 120'
$CancelButton.Size = '75, 23'
$CancelButton.Text = 'Cancel'
$CancelButton.DialogResult = 'Cancel'
$phoneform.Controls.Add($CancelButton)
$phoneform.Topmost = $True
$phoneform.Add_Shown({ $phoneform.Activate() })

$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20) 
$objLabel.Size = New-Object System.Drawing.Size(280,20) 
$objLabel.Text = "Work and mobile numbers for $IHIfirstname $IHIlastname"
$phoneform.Controls.Add($objLabel) 

$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(40,42) 
$objLabel.Size = New-Object System.Drawing.Size(50,20) 
$objLabel.Text = "Work"
$phoneform.Controls.Add($objLabel) 

$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(40,72) 
$objLabel.Size = New-Object System.Drawing.Size(60,20) 
$objLabel.Text = "Cellphone"
$phoneform.Controls.Add($objLabel) 

$objTextBox = New-Object System.Windows.Forms.TextBox 
$objTextBox.Location = New-Object System.Drawing.Size(100,40) 
$objTextBox.Size = New-Object System.Drawing.Size(160,20) 
$phoneform.Controls.Add($objTextBox)

$objTextBox2 = New-Object System.Windows.Forms.TextBox 
$objTextBox2.Location = New-Object System.Drawing.Size(100,70) 
$objTextBox2.Size = New-Object System.Drawing.Size(160,20) 
$phoneform.Controls.Add($objTextBox2) 

if('Ok' -eq $phoneform.ShowDialog()){
    #write-host "form OK button clicked"
}else{
    #Write-Host 'Form cancelled'
exit
}

$worknumber = $objTextBox.text
$cellnumber = $objTextBox2.text
$worknumber = $worknumber -replace '[()-. ]',''
$cellnumber = $cellnumber -replace '[()-. ]',''
#write-host $worknumber
#write-host $cellnumber
$worknumber.Length
$cellnumber.Length
if ($worknumber.Length -eq 0) {$worknumber = "0000000000"}
if ($cellnumber.Length -eq 0) {$cellnumber = "0000000000"}

if (($worknumber.Length -eq 10) -and ($cellnumber.Length -eq 10)) {
#write-host "both match"
$worknumber = $worknumber.Insert(0,"(")
$worknumber = $worknumber.Insert(4,")")
$worknumber = $worknumber.Insert(5," ")
$worknumber = $worknumber.Insert(9,"-")

$cellnumber = $cellnumber.Insert(0,"(")
$cellnumber = $cellnumber.Insert(4,")")
$cellnumber = $cellnumber.Insert(5," ")
$cellnumber = $cellnumber.Insert(9,"-") }
Else {
write-host "One of these is not 10 digits"
$a= New-Object -ComObject wscript.shell
$numanswer = $a.popup("
Not enough digits entered
Work Phone - $worknumber
Cell Phone -  $cellnumber", `
0,"Error",0)
If ($numanswer -eq 6) {
exit }

}
# Phone code ends here

【问题讨论】:

  • designed for non-admins to add users to the Windows domain...为什么....
  • 您正在寻找的称为事件处理程序
  • 因为不是每个人都需要成为域管理员才能完成这项繁重的工作。而且因为脚本在后端做了很多工作来正确格式化属性以进行同步,并进行了一堆更新,而帮助台人员不必手动执行这些更新,并且有一个疯狂的分步过程。目前为止很方便,但我只需要这一段反复询问,直到输入正确的位数。
  • 您可以尝试将提示部分包裹在 Do { .. } Until ($outputexpected)
  • 可以授予 AD 权限以允许创建/修改帐户,而无需授予完整的域管理员权限。如果他们拥有这些权限,您就不需要让它自我提升(这也引出了一个问题,即您如何保护凭据,以便某人不能出于其他原因自行提升)

标签: powershell input dialog


【解决方案1】:

如上面的 cmets 中所述,如果您将代码包装在 do/until 中,您可以循环允许用户重试输入数据。请参阅下面的更新脚本。 (另外,由于其他所有内容都是 Winforms,因此我修改了脚本以使用 Winforms MessageBox 类,而不是调用 wscript.shell。)

do {

# Phone code begins here
$phoneform = New-Object System.Windows.Forms.Form
$phoneform.Text = 'Phone numbers'
$phoneform.Size = '300, 200'
$phoneform.StartPosition = "CenterScreen"
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(75, 120)
$OKButton.Size = '75, 23'
$OKButton.Text = 'OK'
$OKButton.DialogResult = 'Ok'
$phoneform.Controls.Add($OKButton)
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = '160, 120'
$CancelButton.Size = '75, 23'
$CancelButton.Text = 'Cancel'
$CancelButton.DialogResult = 'Cancel'
$phoneform.Controls.Add($CancelButton)
$phoneform.Topmost = $True
$phoneform.Add_Shown({ $phoneform.Activate() })

$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20) 
$objLabel.Size = New-Object System.Drawing.Size(280,20) 
$objLabel.Text = "Work and mobile numbers for $IHIfirstname $IHIlastname"
$phoneform.Controls.Add($objLabel) 

$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(40,42) 
$objLabel.Size = New-Object System.Drawing.Size(50,20) 
$objLabel.Text = "Work"
$phoneform.Controls.Add($objLabel) 

$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(40,72) 
$objLabel.Size = New-Object System.Drawing.Size(60,20) 
$objLabel.Text = "Cellphone"
$phoneform.Controls.Add($objLabel) 

$objTextBox = New-Object System.Windows.Forms.TextBox 
$objTextBox.Location = New-Object System.Drawing.Size(100,40) 
$objTextBox.Size = New-Object System.Drawing.Size(160,20) 
$phoneform.Controls.Add($objTextBox)

$objTextBox2 = New-Object System.Windows.Forms.TextBox 
$objTextBox2.Location = New-Object System.Drawing.Size(100,70) 
$objTextBox2.Size = New-Object System.Drawing.Size(160,20) 
$phoneform.Controls.Add($objTextBox2) 

if('Ok' -eq $phoneform.ShowDialog()){
    #write-host "form OK button clicked"
}else{
    #Write-Host 'Form cancelled'
    exit
}

$worknumber = $objTextBox.text
$cellnumber = $objTextBox2.text
$worknumber = $worknumber -replace '[()-. ]',''
$cellnumber = $cellnumber -replace '[()-. ]',''
#write-host $worknumber
#write-host $cellnumber
$worknumber.Length
$cellnumber.Length
if ($worknumber.Length -eq 0) {$worknumber = "0000000000"}
if ($cellnumber.Length -eq 0) {$cellnumber = "0000000000"}

if (($worknumber.Length -eq 10) -and ($cellnumber.Length -eq 10)) {
    #write-host "both match"
    $worknumber = $worknumber.Insert(0,"(")
    $worknumber = $worknumber.Insert(4,")")
    $worknumber = $worknumber.Insert(5," ")
    $worknumber = $worknumber.Insert(9,"-")

    $cellnumber = $cellnumber.Insert(0,"(")
    $cellnumber = $cellnumber.Insert(4,")")
    $cellnumber = $cellnumber.Insert(5," ")
    $cellnumber = $cellnumber.Insert(9,"-") 
}
Else 
{
    # Use Winforms MessageBox class instead of VBScript Dialog()
    $result = [System.Windows.Forms.MessageBox]::Show(
        "Not enough digits entered`nWork Phone - $worknumber`nCell Phone -  $cellnumber", 
        "Invalid Phone Number", 
        [System.Windows.Forms.MessageBoxButtons]::RetryCancel)
    if ($result -eq "Retry")
    {
        continue
    }
    else
    {
        exit
    }
}

} until ($false)

【讨论】:

    【解决方案2】:

    您还可以将电话号码解析转换为函数,并在数据未按照您希望的方式验证时使其递归调用自身。然后只需调用该函数并从返回的对象中提取worknumbercellnumber 属性。如果他们点击取消,它会返回$false(然后$return.worknumber 不会给出任何结果),因此可以验证它是否为假或只是以空白数据结束(取决于您当时需要脚本执行的操作。

    function Get-PhoneNumbers {
        # Create form to obtain phone numbers
        $phoneform = New-Object System.Windows.Forms.Form
        $phoneform.Text = 'Phone numbers'
        $phoneform.Size = '300, 200'
        $phoneform.StartPosition = "CenterScreen"
        $OKButton = New-Object System.Windows.Forms.Button
        $OKButton.Location = New-Object System.Drawing.Size(75, 120)
        $OKButton.Size = '75, 23'
        $OKButton.Text = 'OK'
        $OKButton.DialogResult = 'Ok'
        $phoneform.Controls.Add($OKButton)
        $CancelButton = New-Object System.Windows.Forms.Button
        $CancelButton.Location = '160, 120'
        $CancelButton.Size = '75, 23'
        $CancelButton.Text = 'Cancel'
        $CancelButton.DialogResult = 'Cancel'
        $phoneform.Controls.Add($CancelButton)
        $phoneform.Topmost = $True
        $phoneform.Add_Shown( { $phoneform.Activate() })
    
        $objLabel = New-Object System.Windows.Forms.Label
        $objLabel.Location = New-Object System.Drawing.Size(10, 20) 
        $objLabel.Size = New-Object System.Drawing.Size(280, 20) 
        $objLabel.Text = "Work and mobile numbers for $IHIfirstname $IHIlastname"
        $phoneform.Controls.Add($objLabel) 
    
        $objLabel = New-Object System.Windows.Forms.Label
        $objLabel.Location = New-Object System.Drawing.Size(40, 42) 
        $objLabel.Size = New-Object System.Drawing.Size(50, 20) 
        $objLabel.Text = "Work"
        $phoneform.Controls.Add($objLabel) 
    
        $objLabel = New-Object System.Windows.Forms.Label
        $objLabel.Location = New-Object System.Drawing.Size(40, 72) 
        $objLabel.Size = New-Object System.Drawing.Size(60, 20) 
        $objLabel.Text = "Cellphone"
        $phoneform.Controls.Add($objLabel) 
    
        $objTextBox = New-Object System.Windows.Forms.TextBox 
        $objTextBox.Location = New-Object System.Drawing.Size(100, 40) 
        $objTextBox.Size = New-Object System.Drawing.Size(160, 20) 
        $phoneform.Controls.Add($objTextBox)
    
        $objTextBox2 = New-Object System.Windows.Forms.TextBox 
        $objTextBox2.Location = New-Object System.Drawing.Size(100, 70) 
        $objTextBox2.Size = New-Object System.Drawing.Size(160, 20) 
        $phoneform.Controls.Add($objTextBox2)
    
        # Exit on Cancel rather than proceed on Ok to remove need for else.    
        if ('Cancel' -eq $phoneform.ShowDialog()) {
            return $false
        }
    
        # Do validation here
        $worknumber = $objTextBox.text
        $cellnumber = $objTextBox2.text
        $worknumber = $worknumber -replace '[()-. ]', ''
        $cellnumber = $cellnumber -replace '[()-. ]', ''
        #write-host $worknumber
        #write-host $cellnumber
        if ($worknumber.Length -eq 0) {$worknumber = "0000000000"}
        if ($cellnumber.Length -eq 0) {$cellnumber = "0000000000"}
    
        if (($worknumber.Length -eq 10) -and ($cellnumber.Length -eq 10)) {
            #write-host "both match"
            $worknumber = $worknumber.Insert(0, "(")
            $worknumber = $worknumber.Insert(4, ")")
            $worknumber = $worknumber.Insert(5, " ")
            $worknumber = $worknumber.Insert(9, "-")
    
            $cellnumber = $cellnumber.Insert(0, "(")
            $cellnumber = $cellnumber.Insert(4, ")")
            $cellnumber = $cellnumber.Insert(5, " ")
            $cellnumber = $cellnumber.Insert(9, "-")
            # Return now so that only a valid result returns.
            # Previous attempts will be dropped.
            return [pscustomobject]@{
                WorkNumber = $worknumber
                CellNumber = $cellnumber
            }
        }
        Else {
            # Use Winforms MessageBox class instead of VBScript Dialog()
            $result = [System.Windows.Forms.MessageBox]::Show(
                "Not enough digits entered`nWork Phone - $worknumber`nCell Phone -  $cellnumber", 
                "Invalid Phone Number", 
                [System.Windows.Forms.MessageBoxButtons]::RetryCancel)
            if ($result -eq "Retry") {
                Get-PhoneNumbers
            }
            else {
                return $false
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2022-11-16
      • 1970-01-01
      • 1970-01-01
      • 2021-07-12
      • 1970-01-01
      • 1970-01-01
      • 2020-01-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多