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