简体   繁体   English

Powershell 脚本在第一次执行时不运行

[英]Powershell script doesn't run on first execution

I wrote a Powershell-Script which downloads a pfx-Container via SCP to a Windows 2019 Server.我编写了一个 Powershell 脚本,它通过 SCP 将 pfx-Container 下载到 Windows 2019 服务器。 After that it will check if the currently installed server certificate matches the downloaded one or not.之后它将检查当前安装的服务器证书是否与下载的证书匹配。 If it does not match it will replace it with the downloaded one.如果不匹配,它将用下载的替换它。 This is to replace an outdated Letcencrypt certificate with a new one.这是用新证书替换过时的 Letcencrypt 证书。

#Retrieving SecureString Instance of PFX-Password
$pw = Get-Content "C:\Users\user\Desktop\example_password.txt" | ConvertTo-SecureString -Key (1..16) 

$getPwResult = $LastExitCode
if ($getPwResult -eq 0)
{
  Write-Host "Successfully got Secure Password!"
}
else
{
  Write-Host "Error retrieving password"
  Write-Host $getPwResult
  exit $getPwResult
}



$oldThumbprint = Get-ChildItem  -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -Match "server.example.org"} | Select Name -ExpandProperty Thumbprint 

$getoldThumbprintResult = $LastExitCode
if ($getoldThumbprintResult -eq 0)
{
 
  Write-Host "Successfully got old thumbprint! $oldThumbprint"
}
else
{
  Write-Host "Error retrieving old thumbprint"
  exit $getoldThumbprintResult
}

#Downloading current file via WinSCP
& "C:\Program Files (x86)\WinSCP\WinSCP.com" `
  /log="C:\Users\user\Desktop\WinSCP.log" /ini=nul `
  /command `
    "open sftp://username@server/" `
    "get -neweronly /path/to/server.pfx C:\Users\user\Desktop\" `
    "exit"

$winscpResult = $LastExitCode
if ($winscpResult -eq 0)
{
  Write-Host "Successfully downloaded file!"
}
else
{
  Write-Host "Error while downloading file"
  exit $winscpResult
}

$newThumbprint = (Get-PfxData -Password $pw -FilePath C:\Users\user\Desktop\server.pfx).EndEntityCertificates.Thumbprint
$getnewThumbprintResult = $LastExitCode
if ($getnewThumbprintResult -eq 0)
{
  Write-Host "Successfully got new thumbprint! $newThumbprint"
}
else
{
  Write-Host "Error retrieving new thumbprint"
  exit $getnewThumbprintResult
}


if ($oldThumbprint -ne $newThumbprint) {
  #Executing the import of new PFX
  Import-PfxCertificate -FilePath "C:\Users\user\Desktop\server.pfx" -Password $pw -CertStoreLocation Cert:\LocalMachine\My
  $installCertExitCode = $LastExitCode

  if ($getnewThumbprintResult -eq 0) {
    Write-Host "Installed new certificate"
  } else {
    Write-Host "An error occured while installing new certificate."
    exit $installCertExitCode
  }

} else {
    Write-Host "File has not been changed!"
}

All in all this works fine but when I wanted to create a scheudule for execution strange things happened.总而言之,这一切都很好,但是当我想创建一个执行计划时发生了奇怪的事情。 First of all the sript won't be executed via Windows scheudler regardless of what I tried...首先,无论我尝试了什么,都不会通过 Windows 调度程序执行 sript...

After closer inspection I recognized that sometimes most commands fail when I execute the Powershell-Script.经过仔细检查后,我发现执行 Powershell 脚本时,有时大多数命令都会失败。 I always happens at a freshly opened Powershell-Terminal at the first execution.我总是在第一次执行时出现在新打开的 Powershell 终端上。

So the folling happens (in the same PS-Terminal):所以会发生以下情况(在同一个 PS 终端中):

#First attempt:

PS C:\Users\user\Desktop> C:\Users\user\Desktop\install_cert.ps1
Error retrieving password


#Second attempt:

PS C:\Users\user\Desktop> C:\Users\user\Desktop\install_cert.ps1
Successfully got Secure Password!
Successfully got old thumbprint! 
[...]
Successfully downloaded file!
Successfully got new thumbprint! 
Installed new certificate.

I wrote a small batch file with the sole purpose of reproduce the behaeveour of the scheuduler task:我写了一个小批处理文件,其唯一目的是重现调度程序任务的行为:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noprofile -ExecutionPolicy UnRestricted -File C:\Users\user\Desktop\install_cert.ps1

When I execute it the script fails every time.当我执行它时,脚本每次都会失败。

PS C:\Users\user\Desktop> C:\Users\user\Desktop\install_cert.ps1
Error retrieving password

So I guess that this is the problem which has to be solved.所以我想这是必须解决的问题。

I also removed the first exit-statement which results in a error while executing 'Get-ChildItem -Path Cert:\LocalMachine\My [...]'.我还删除了在执行“Get-ChildItem -Path Cert:\LocalMachine\My [...]”时导致错误的第一个退出语句。

There is no output from the commands which makes debugging hard for me.命令中没有 output,这让我很难调试。

Does anybody know what is happening here and how to fix it?有谁知道这里发生了什么以及如何解决它?

Thanks in advance!提前致谢!

Edit:编辑:

The WinSCP part works fine. WinSCP 部分工作正常。 The error occures in the statements before:错误发生在之前的语句中:

#Retrieving SecureString Instance of PFX-Password
$pw = Get-Content "C:\Users\user\Desktop\example_password.txt" | ConvertTo-SecureString -Key (1..16) 

$getPwResult = $LastExitCode
if ($getPwResult -eq 0)
{
  Write-Host "Successfully got Secure Password!"
}
else
{
  Write-Host "Error retrieving password"
  Write-Host $getPwResult
  exit $getPwResult
}



$oldThumbprint = Get-ChildItem  -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -Match "server.example.org"} | Select Name -ExpandProperty Thumbprint 

$getoldThumbprintResult = $LastExitCode
if ($getoldThumbprintResult -eq 0)
{
 
  Write-Host "Successfully got old thumbprint! $oldThumbprint"
}
else
{
  Write-Host "Error retrieving old thumbprint"
  exit $getoldThumbprintResult
}

As suggested I tried to replace the WinSCP-Code and it did not fix the problem.正如建议的那样,我尝试替换 WinSCP-Code 并没有解决问题。

Refactor your WinSCP command to this (that is if you choose not to use the WinSCP .NET implementation):将您的 WinSCP 命令重构为此(即,如果您选择不使用 WinSCP .NET 实现):

#Downloading current file via WinSCP
& "C:\Program Files (x86)\WinSCP\WinSCP.com" `
    '/log="C:\Users\user\Desktop\WinSCP.log"' `
    '/ini=nul' `
    /command `
    "open sftp://username@server/" `
    "get -neweronly /path/to/server.pfx C:\Users\user\Desktop\" `
    "exit"

Or this...或这个...

$AllArgs = @(
    '/log="C:\Users\user\Desktop\WinSCP.log"',
    '/ini=nul',
    '/command',
    'open sftp://username@server/',
    'get -neweronly /path/to/server.pfx C:\Users\user\Desktop\',
    'exit'
)
 & '$WinScpCmd' $AllArgs

and see if that works on the first run use case.看看这是否适用于第一次运行的用例。 Again, as per my comment above, use Trace-Command to watch what is happening.同样,根据我上面的评论,使用Trace-Command来观察正在发生的事情。

Okay I got the solution :好的,我得到了解决方案

I just copied the $LastExitCode from a script found on the internet and thought it was like $?我只是从互联网上找到的脚本中复制了$LastExitCode并认为它就像$? in linux.在 linux 中。 Unfortunately it it happens to be that this exact same command is suitable here too.不幸的是,恰好这个完全相同的命令也适用于此。

So if i replace it the script works fine:因此,如果我替换它,脚本可以正常工作:

#Retrieving SecureString Instance of PFX-Password
$pw = Get-Content "C:\Users\user\Desktop\example_password.txt" | ConvertTo-SecureString -Key (1..16) 

$getPwResult = $?
if ($getPwResult)
{
  Write-Host "Successfully got Secure Password!"
}
else
{
  Write-Host "Error retrieving password"
  Write-Host $getPwResult
  exit $getPwResult
}



$oldThumbprint = Get-ChildItem  -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -Match "server.example.org"} | Select Name -ExpandProperty Thumbprint 

$getoldThumbprintResult = $?
if ($getoldThumbprintResult)
{
 
  Write-Host "Successfully got old thumbprint! $oldThumbprint"
}
else
{
  Write-Host "Error retrieving old thumbprint"
  exit $getoldThumbprintResult
}

#Downloading current file via WinSCP
& "C:\Program Files (x86)\WinSCP\WinSCP.com" `
  /log="C:\Users\user\Desktop\WinSCP.log" /ini=nul `
  /command `
    "open sftp://username@server/" `
    "get -neweronly /path/to/server.pfx C:\Users\user\Desktop\" `
    "exit"

$winscpResult = $?
if ($winscpResult)
{
  Write-Host "Successfully downloaded file!"
}
else
{
  Write-Host "Error while downloading file"
  exit $winscpResult
}

$newThumbprint = (Get-PfxData -Password $pw -FilePath C:\Users\user\Desktop\server.pfx).EndEntityCertificates.Thumbprint
$getnewThumbprintResult = $?
if ($getnewThumbprintResult)
{
  Write-Host "Successfully got new thumbprint! $newThumbprint"
}
else
{
  Write-Host "Error retrieving new thumbprint"
  exit $getnewThumbprintResult
}


if ($oldThumbprint -ne $newThumbprint) {
  #Executing the import of new PFX
  Import-PfxCertificate -FilePath "C:\Users\user\Desktop\server.pfx" -Password $pw -CertStoreLocation Cert:\LocalMachine\My
  $installCertExitCode = $?

  if ($installCertExitCode) {
    Write-Host "Installed new certificate"
  } else {
    Write-Host "An error occured while installing new certificate."
    exit $installCertExitCode
  }

} else {
    Write-Host "File has not been changed!"
}

This would somehow explain why the script would run in the second attempt because this variable was set like postanote stated in the comment above.这可以以某种方式解释为什么该脚本会在第二次尝试中运行,因为该变量的设置类似于上面评论中所述的postanote

Thank you for your help!谢谢您的帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM