Powershell 取消在循环中获取凭据

Powershell 取消在循环中获取凭据,powershell,scripting,Powershell,Scripting,我正在开发PowerShell脚本,以便通过在WinRM中使用Invoke命令来自动化远程服务器上的任务 该脚本将使用服务器IP、测试WinRM和“Get Credential”cmdlet建立会话,并使用Invoke命令在远程服务器上运行另一个脚本。我已经在我想要实现的目标方面取得了重大进展,但是,我在如何设置代码方面遇到了问题,因此当我在获取凭据提示符上按下“取消”或“X”按钮时,它应该中止脚本并返回到常规PowerShell命令行提示符 下面是我到目前为止所做的,我已经删除了代码的注释和描

我正在开发PowerShell脚本,以便通过在WinRM中使用Invoke命令来自动化远程服务器上的任务

该脚本将使用服务器IP、测试WinRM和“Get Credential”cmdlet建立会话,并使用Invoke命令在远程服务器上运行另一个脚本。我已经在我想要实现的目标方面取得了重大进展,但是,我在如何设置代码方面遇到了问题,因此当我在获取凭据提示符上按下“取消”或“X”按钮时,它应该中止脚本并返回到常规PowerShell命令行提示符

下面是我到目前为止所做的,我已经删除了代码的注释和描述,以减少这里的字数

function SS
{

    Add-Type -AssemblyName System.Windows.Forms
    $BInput = [System.Windows.Forms.MessageBox]::Show('Do you want to proceed?', 'Confirmation',[System.Windows.Forms.MessageBoxButtons]::YesNo)
         switch ($BInput)
         { 
            "Yes" {             
                    while ($true)
                        {
                            $server=Read-Host "Enter Server IP Address"  
                            set-item -Path WSMan:\localhost\Client\TrustedHosts -Value "$server" -Force
                                if(Test-WSMan -ComputerName $server -ErrorAction SilentlyContinue)
                                    {
                                        Write-Host "$server is accessible, enter credentials to connect"
                                        
                                            while ($true)
                                                {
                                                    $creden=Get-Credential -Message "Please enter the server credentials that you want to connect"
                                                    $serversession = New-Pssession -ComputerName $server -Credential $creden -ErrorAction SilentlyContinue
                                                    if(-not($serversession))
                                                       {
                                                        write-warning "Credentials are not valild, please try again"                                                            
                                                       }
                                                    else
                                                       {
                                                        write-host "$server is connected, starting the workflow ......"                                                            
                                                        Invoke-Command -Session $serversession -FilePath "C:\Temp\XXX.ps1"                                                            
                                                       }                                                                         
                                                }
                                            Break
                                    }
                                else
                                    {
                                        write-host "Windows Remote Management (WinRM) protocol is not running, please check service and confirm."
                                    }
                        }
                    
                    Get-Pssession | Remove-PSSession
                    
                  }
                                     
            "No"  {  

                    Break
                  }
        }     
      
 }
我明白我必须在这一行之后应用更改/逻辑

$creden=Get-Credential -Message "Please enter the server credentials that you want to connect"
但似乎还没找到。我上网查了一下,采取了不同的方法,但到目前为止没有成功。我想就如何解决这一问题提出意见或建议,感谢您的帮助


谢谢

我看到的是你可能想得太多了。一个简单的
语句就可以了,试试:

$creden=Get-Credential -Message "Please enter the server credentials that you want to connect"
    if(!$creden){break}

继续我的评论。 尝试对您的用例进行重构

注意事项:注意已完全测试,因为我目前没有要测试的环境。

功能启动工作流
{
[cmdletbinding(SupportsShouldProcess)]
[别名('swf')]
Param
(
)
If((读取主机-提示“是否继续:[是/否]”)-eq“否”)
{Break}
其他的
{
Do{$RemoteServerIPAddress=(读取主机-提示“输入服务器IP地址”)}
直到($RemoteServerIPAddress-match“^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$”)
获取ChildItem-路径“WSMan:\localhost\Client\TrustedHosts”
尝试
{
(测试连接-计算机名$RemoteServerIPAddress-计数1-错误操作停止)。IPV4Address
#设置项-路径“WSMan:\localhost\Client\TrustedHosts”-值$RemoteServerIPAddress-Force
获取ChildItem-路径“WSMan:\localhost\Client\TrustedHosts”
尝试
{
测试WSMan-ComputerName$RemoteServerIPAddress-ErrorAction停止
$RemoteServerIPAddress可访问,请输入连接凭据
做
{
$Creds=$null
$CredMessage='请输入要连接的远程服务器凭据。'
$CredMessage=“$CredMessage如果凭据无效,系统将提示您重新输入凭据。”
$Creds=获取凭证-消息$CredMessage
若有(-非$creds)
{
写入警告-消息“凭证请求已取消”
开始睡眠-3秒
出口
}
$NewPSSessionSplat=@{
ComputerName=$RemoteServerIPAddress
凭证=$Creds
名称='RemoteSessionName'
ErrorAction='停止'
}
新建PSSession$NewPSSessionSplat
}
直到(获取PSSession-Name'RemoteSessionName')
$RemoteServerIPAddress已连接,正在启动工作流
调用命令-Session$RemoteServerSession-FilePath“C:\Temp\XXX.ps1”
}
抓住
{
写入警告-消息“会话连接结果:”
$PSitem.Exception.Message
}
最后
{
获得PSSession |
删除PSSession-ErrorAction Silently继续
}
}
抓住
{
写入警告消息“
远程服务器$RemoteServerIPAddress不可用
正在退出会话。”
开始睡眠-3秒
出口
}
}
}
启动工作流

脚本不错!你可能需要考虑的一些事情。是否有必要弹出一个窗口询问用户是否想继续?我可能会直接要求输入服务器IP,如果对该IP的响应为空或无效,那么我可能会退出脚本。此外,用户始终可以按Ctrl-C退出脚本。如果坚持询问是否继续,可以用一个
$response=Read Host“您确定要继续吗?(Y/N)”
替换弹出窗口,并检查是否返回了“Y”或“N”。如果不循环并再次询问,或者假设N。总体来说,做得很好,但是您有很多错误处理问题没有解决,并且您的函数命名应该遵循有文档记录的标准。稍后我会发布一个你发布的内容的重构,以展示我的意思。谢谢@Abraham,它成功了。
Function Start-WorkFlow
{
    <#
    .Synopsis
        Execute a workflow
    .DESCRIPTION
        Sets up a WinRM session to a remote host to execute the defined workflow
    .EXAMPLE
        Start-WorkFlow
    .EXAMPLE
        swf
    .INPUTS
        Remote host IPAddress
        Remove host credentials
    .OUTPUTS
        Resutls of teh workflow
    .NOTES
        V 0.0.1 - Prototype script. Clean-Up before production use
    .COMPONENT
        Stand-alone script
    .ROLE
        Administrative actions
    .FUNCTIONALITY
        Implemetned error logic for each code block
        Restrict the user input to only be a proper IPAddress
        Validate TCPIP state 
        Validate WSman state
        Establish a new session
        Process workflow
        Exit session
    #>

    [cmdletbinding(SupportsShouldProcess)]
    [Alias('swf')]
    Param
    (

    )

    
    If ((Read-Host -Prompt 'Do you want to proceed: [Yes/No]') -eq 'No' )
    {Break}
    Else
    {
        Do {$RemoteServerIPAddress = (Read-Host -Prompt 'Enter Server IP Address')}
        Until ($RemoteServerIPAddress -match "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$")

        Get-ChildItem -Path 'WSMan:\localhost\Client\TrustedHosts'

        Try
        {
            (Test-Connection -ComputerName $RemoteServerIPAddress -Count 1 -ErrorAction Stop).IPV4Address
            # Set-Item -Path 'WSMan:\localhost\Client\TrustedHosts' -Value $RemoteServerIPAddress -Force

            Get-ChildItem -Path 'WSMan:\localhost\Client\TrustedHosts'

            Try 
            {
                Test-WSMan -ComputerName $RemoteServerIPAddress -ErrorAction Stop
                "$RemoteServerIPAddress is accessible, enter credentials to connect"
                Do 
                {
                    $Creds        = $null
                    $CredMesssage = 'Please enter the remote server credentials that you want to connect.' 
                    $CredMesssage = "$CredMesssage If credentials are not valid, you will be prompted to re-enter them."
                    $Creds        = Get-Credential -Message $CredMesssage

                    if(-Not $creds)
                    {
                        Write-Warning -Message 'Credential request cancelled.'
                        Start-Sleep -Seconds 3
                        Exit
                    }
                    
                    $NewPSSessionSplat = @{
                        ComputerName = $RemoteServerIPAddress
                        Credential   = $Creds 
                        Name         = 'RemoteSessionName'
                        ErrorAction  = 'Stop'
                    }
                    New-PSSession $NewPSSessionSplat
                }
                Until (Get-PSSession -Name 'RemoteSessionName')

                "$RemoteServerIPAddress is connected, starting the workflow ......"
                Invoke-Command -Session $RemoteServerSession -FilePath 'C:\Temp\XXX.ps1'
            }
            Catch 
            {
                Write-Warning -Message 'Session connection results:'
                $PSitem.Exception.Message
            }
            Finally
            {
                Get-PSSession | 
                Remove-PSSession -ErrorAction SilentlyContinue        
            }
        }
        Catch
        {
            Write-Warning -Message "
            The remote server $RemoteServerIPAddress is not available
            Exiting the session."
            Start-Sleep -Seconds 3
            Exit
        }
    }
}


Start-WorkFlow