从文件中读取数据并使用 PowerShell 即时使用时遇到问题

Having problems reading in data from file and using it on the fly using PowerShell

我正在尝试创建一个 PowerShell 脚本,该脚本将在服务进入停止状态时发送电子邮件。我希望能够从另一个文件读取电子邮件配置。

电子邮件配置文件:

.\emailconfig.conf

$emailSmtpServer = "smtp.company.com"
$emailSmtpServerPort = "587"
$emailSmtpUser = "usera"
$emailSmtpPass = "passwordb"

$emailFrom = "userA@company.com"
$emailTo = "userB@company.com"
$emailcc= "userC@company.com"

这就是我目前在 PowerShell 脚本中的内容:

.\emailservicecheck.ps1

$A = Get-Service "Service B"

if ($A.Status -eq "Stopped") {
    Get-Content emailconfig.conf | Out-String

    $emailMessage = New-Object System.Net.Mail.MailMessage($emailFrom, $emailTo)
    $emailMessage.Cc.Add($emailcc)
    $emailMessage.Subject = "subject"
    #$emailMessage.IsBodyHtml = $true  # true or false depends
    $emailMessage.Body = Get-Service "Service B" | Out-String

    $SMTPClient = New-Object System.Net.Mail.SmtpClient($emailSmtpServer, $emailSmtpServerPort)
    $SMTPClient.EnableSsl = $False
    $SMTPClient.Credentials = New-Object System.Net.NetworkCredential($emailSmtpUser, $emailSmtpPass);
    $SMTPClient.Send($emailMessage)
}

如果我将电子邮件配置文件中的文本输入到脚本中,该脚本可以工作,但我似乎无法即时读取文件中的数据并使脚本工作。它出错并说我的变量是空的。

您似乎想从另一个文件中包含一些脚本。这可以通过 dot sourcing 完成,但是文件需要保存为 .ps1 文件,不能使用 .conf.

您可以按如下方式进行(代替您现有的 Get-Content)行:

. .\emailconfig.ps1

假设文件保存在脚本的当前工作目录中。

您的脚本无法运行,因为

get-content emailconfig.conf | Out-String

将该文件的内容返回到输出管道,而不是将其包含在脚本中并执行。

您要搜索的(我认为)是 .psd1 files。与其他配置格式相比,我个人更喜欢它们(连同 JSON)。我所指的 link 还描述了其他众所周知的格式以及如何在 PowerShell 中使用它们。

简而言之,模块清单工作如下:

configuration.psd1

@{
    SmtpServer = "";
    MailFrom = "";
    Auth = @{
        User = "";
        Pass = "";
    };
}

脚本.ps1

$mailConfig = Import-LocalizedData -BaseDirectory C:\ -FileName configuration.psd1
$emailMessage = New-Object System.Net.Mail.MailMessage( $$mailConfig.mailFrom , $mailConfig.mailTo )

我不确定我是否理解正确你想要什么。

如果要使用外部文件中的变量,则需要对外部脚本进行点源,例如,创建一个名为 variables.ps1 的文件并放在同一文件夹中 在主脚本的开头使用

. .\variables.ps1

如果您将外部文件中的变量扩展为电子邮件模板,请执行以下操作:

$HTMLBody = get-content "yourfilepath" | Foreach-Object {$ExecutionContext.InvokeCommand.ExpandString($_)}

这将展开所有变量并将其放入 $HTMLBody 变量中 然后使用:

$emailMessage.Body = (ConvertTo-Html -body $HTMLBody)

作为, Get-Content emailconfig.conf | Out-String will just output the content of the file, it won't define the variables in your code. For that you'd need to dot-source文件,需要文件扩展名为“.ps1”。

如果您想坚持使用简单的配置文件格式,我建议将文件更改为如下格式:

emailSmtpServer = smtp.company.com
emailSmtpServerPort = 587
emailSmtpUser = usera
emailSmtpPass = passwordb

emailFrom = userA@company.com
emailTo = userB@company.com
emailcc = userC@company.com

并将其导入 hashtable via ConvertFrom-StringData:

$cfg = Get-Content emailconfig.conf | Out-String | ConvertFrom-StringData

哈希表中的数据可以通过点符号 ($cfg.emailFrom) 以及索引运算符 ($cfg['emailFrom']) 访问,因此您的代码必须看起来像这样:

$msg = New-Object Net.Mail.MailMessage($cfg.emailFrom, $cfg.emailTo)
$msg.Cc.Add($cfg.emailcc)
$msg.Subject = 'subject'
$msg.Body    = Get-Service 'Service B' | Out-String

$smtp = New-Object Net.Mail.SmtpClient($cfg.emailSmtpServer, $cfg.emailSmtpServerPort)
$smtp.EnableSsl   = $false
$smtp.Credentials = New-Object Net.NetworkCredential($cfg.emailSmtpUser, $cfg.emailSmtpPass)
$smtp.Send($msg)