【问题标题】:Running a Powershell Script on Windows Service Failure. Works when run manually but not when service fails. Advice needed在 Windows 服务失败时运行 Powershell 脚本。手动运行时有效,但服务失败时无效。需要建议
【发布时间】:2017-12-07 16:21:15
【问题描述】:

所以我一直在编写一个脚本,以便在服务失败时发送电子邮件。该脚本工作得很好,因为我已经从 PowerShell 手动运行它。我收到了电子邮件,一切都检查出来了。 然后我将其添加到服务中: Service Recovery Options

我告诉它通过链接到可执行文件来运行 Powershell:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

然后执行以下脚本:

-command C:\Users\andreand\Desktop\Sendmail.ps1

如前所述,我在 PowerShell 中手动尝试了此操作,但出现错误。如果我在 -command 之前附加 PowerShell 位置,它可以工作。像这样:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command C:\Users\andreand\Desktop\Sendmail.ps1

所以如果我手动运行它就可以了,但是当服务失败时,什么也没有发生。 我通过/taskkill /F /PID pid 触发失败,我可以看到服务已停止。

我错过了什么?我觉得我是如此接近,令人沮丧!

【问题讨论】:

  • 检查系统事件日志以查看您的恢复脚本是否已执行。我还假设脚本作为服务的用户上下文运行,因此您可能需要检查该用户是否可以成功运行脚本。
  • 没错,就是这么做的。确实出现了一个错误,说明服务意外终止并表示“将在 0 毫秒内采取纠正措施;运行配置的恢复程序”。查看事件查看器的 Powershell 选项卡,我可以看到 Powershell 似乎也正在启动。我已经将 PowerShell 中的执行策略设置为 RemoteSigned,所以脚本应该可以运行。
  • 听起来它正在尝试执行它。您是否检查过它是否是用户上下文问题?
  • 还可以尝试将命令行参数更改为:-ExecutionPolicy Bypass -command C:\Users\andreand\Desktop\Sendmail.ps1。我的理论是运行服务/脚本的用户将执行策略设置为受限,因为当您手动运行它时这不是问题。
  • 我应该将它粘贴在命令行参数字段中还是我只使用 PowerShell 在相关机器上运行一次?

标签: windows powershell email


【解决方案1】:

正如 Mark Wragg 建议的那样,问题在于我用一个用户帐户加密了字符串,但试图用另一个用户帐户对其进行解密。通过不对密码使用加密,它可以工作。

我仍在尝试找出是否有任何方法可以保持加密并进行这项工作。

此外,我现在正在尝试将失败的服务嵌入到电子邮件主题字段中,但我不确定如何执行此操作。我见过 Get-Service Cmdlet,但这似乎获取了整个列表,我只需要它来读回失败的服务。非常欢迎对此提供任何帮助。

编辑:我现在找到了加密密码和检索服务列表的解决方案。 为了加密密码,我使用了加密密钥。它是这样的:

# Change this location as necessary.
PS C:\Users\andreand> $File = 'C:\SomeLocation\Key.txt'

PS C:\Users\andreand> [Byte[]] $Key = (1..16)

# The password for the mail account / SMTP client.
PS C:\Users\andreand> $Password = 'Passwordgoeshere' | ConvertTo-SecureString -AsPlainText -Force

PS C:\Users\andreand> $Password | ConvertFrom-SecureString -Key $Key | Out-File 
$File 

之后,我在脚本中输入以下内容以检索加密密钥:

$File = 'C:\SomeLocation\Key.txt'
[Byte[]] $Key = (1..16)
$Password = Get-Content $File | ConvertTo-SecureString -Key $Key

为了检索服务列表,我使用了 Get-Service cmdlet,但通过一些过滤来查找我想要的服务。像这样:

$Services = Get-Service | Where-Object {$_.DisplayName -like "ServiceName*"}

【讨论】:

    猜你喜欢
    • 2021-03-12
    • 1970-01-01
    • 2017-02-03
    • 1970-01-01
    • 1970-01-01
    • 2011-10-29
    • 2019-12-31
    • 2020-02-26
    • 2018-08-24
    相关资源
    最近更新 更多