【问题标题】:Powershell foreach and if statementPowershell foreach 和 if 语句
【发布时间】:2021-08-27 06:54:49
【问题描述】:

我正在尝试检查凭据管理器是否有任何“域”条目,如果“域”条目 DOESN"T 存在,则会出现一个弹出窗口供用户输入用户名和密码。如果存在,则只需停止脚本。

假设此 PowerShell 脚本在 Windows 登录时运行,以便在 Windows 凭据管理器中不存在域凭据时添加域凭据,然后映射网络驱动器。如果脚本检测到没有在 Windows 凭据管理器中添加域凭据 - 那么它将提示用户输入它。

我对自己的逻辑错误感到困惑,当代码运行时它会忽略 IF 语句并继续弹出用户名和密码窗口,即使 Windows 凭据管理器中有域用户并运行 cmdkey /add 和 net use 命令。

我正在使用 Intune 部署此脚本,并且我已经在没有 IF 语句的情况下对其进行了测试,它工作正常。我试图让 IF 语句在再次测试之前先工作。

这是我的代码:

[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 
$error.clear()


try { 


cmdkey /list | foreach {
if($_ -match 'Domain')
    {
        [PSCustomObject]@{Account = $matches.1}
        [System.Windows.Forms.MessageBox]::Show("Already exist!")
        
    }

    

else {

    
# Captures username
#-------------------------------------------------------------------------


Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

$form = New-Object System.Windows.Forms.Form 
$form.Text = "Enter Username"
$form.Size = New-Object System.Drawing.Size(300,200) 
$form.StartPosition = "CenterScreen"

$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $OKButton
$form.Controls.Add($OKButton)

$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Point(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancel"
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.CancelButton = $CancelButton
$form.Controls.Add($CancelButton)

$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20) 
$label.Size = New-Object System.Drawing.Size(280,20) 
$label.Text = "Enter Username: "
$form.Controls.Add($label) 

$textBox = New-Object System.Windows.Forms.TextBox 
$textBox.Location = New-Object System.Drawing.Point(10,40) 
$textBox.Size = New-Object System.Drawing.Size(260,20) 
$form.Controls.Add($textBox) 

$form.Topmost = $True

$form.Add_Shown({$textBox.Select()})
$result = $form.ShowDialog()

if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
    $x = $textBox.Text
    $x
}




# Captures password
#-------------------------------------------------------------------------

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

$form = New-Object System.Windows.Forms.Form 
$form.Text = "Enter Password"
$form.Size = New-Object System.Drawing.Size(300,200) 
$form.StartPosition = "CenterScreen"

$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $OKButton
$form.Controls.Add($OKButton)

$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Point(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancel"
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.CancelButton = $CancelButton
$form.Controls.Add($CancelButton)

$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20) 
$label.Size = New-Object System.Drawing.Size(280,20) 
$label.Text = "Enter Password: "
$form.Controls.Add($label) 

$textBox = New-Object System.Windows.Forms.TextBox 
$textBox.Location = New-Object System.Drawing.Point(10,40) 
$textBox.Size = New-Object System.Drawing.Size(260,20) 
$form.Controls.Add($textBox) 

$form.Topmost = $True

$form.Add_Shown({$textBox.Select()})
$result = $form.ShowDialog()

if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
    $x2 = $textBox.Text
    $x2
}

 cmdkey.exe /add:ae7msd-dc /user:$x /pass:$x2
 net use U: "\\SERVER\FOLDER" /persistent:yes
 break

}

}
}




catch { [System.Windows.Forms.MessageBox]::Show("Not Working!") }
if (!$error) {
[System.Windows.Forms.MessageBox]::Show("IT'S DONE!")
}

这是当没有 DOMAIN 用户添加到 Windows 凭据管理器时我在 Powershell 编辑器上得到的输出:

PS C:\Users\hadi> C:\temp\add-cred.ps1

GAC    Version        Location                                                                                                                      
---    -------        --------                                                                                                                      
True   v4.0.30319     C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll       
hmohsen
Abc!2345

CMDKEY: Credential added successfully.
The command completed successfully.

OK

这是我在运行脚本时得到的结果,即使已经有一个域用户添加到 Windows 凭据管理器中:

PS C:\Users\hadi> C:\temp\add-cred.ps1

GAC    Version        Location                                                                                                                      
---    -------        --------                                                                                                                      
True   v4.0.30319     C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll       
hmohsen
Abc!2345

CMDKEY: Credential added successfully.
net : System error 85 has occurred.
At C:\temp\add-cred.ps1:124 char:2
+  net use U: "\\SERVER\FOLDER" /persistent:yes
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (System error 85 has occurred.:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
 
The local device name is already in use.
OK

我的目标是在 Windows 凭据管理器中有域用户条目时停止脚本脚本,但脚本仍然继续运行。 逻辑有问题,请问我该如何解决!

【问题讨论】:

  • 您只描述了您希望发生的事情,而没有提及实际发生的事情。您如何安排脚本在登录时运行?它会运行吗?有没有错误?你能用一个更简单的脚本来测试,比如只写一个文件来证明它运行了吗?
  • 谢谢@boxdog,我已经包含了输出
  • 可以分享脚本吗?否则,如果您阅读它,该错误确实会给出一些指示...
  • 谢谢@alexzelaya,这里是 ps1 we.tl/t-yxBQEeLuoR
  • @HQJ,请通过您的问题发布。打开不需要的 PS1 不是我们做的事情

标签: powershell if-statement foreach


【解决方案1】:

您的代码的问题在于以下语句:

cmdkey /list | foreach {
if($_ -match 'Domain')

if 语句永远不会计算为真,因为匹配永远不会为真。

cmdkey /list 命令返回一个格式化字符串数组。您要匹配的字符串是Type: Domain(前后可能有空格)。

将您的代码更改为以下内容应该会获得正确的匹配项:

cmdkey /list | ForEach-Object {
    if($_ -like '*Type: Domain*')
    {
        [PSCustomObject]@{Account = $matches.1}
        [System.Windows.Forms.MessageBox]::Show("Already exist!")
    }

【讨论】:

    猜你喜欢
    • 2021-12-13
    • 2012-06-20
    • 2021-11-09
    • 2012-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-21
    • 1970-01-01
    相关资源
    最近更新 更多