For Each循环中的PowerShell变量用法

时间:2014-03-19 23:02:59

标签: powershell scripting

我正在编写一个PowerShell脚本,尝试连接到端口3389上的服务器列表。当连接失败时,脚本会发送一封电子邮件。

有问题的行(变量)在脚本开头注释掉,只有在循环中引用时才有效。你能帮我理解为什么,当$ subject和$ body变量在循环之外时,在循环内发送电子邮件时,$ server变量只是列表中最后一个服务器?

在我看来,当$ subject和$ body引用$ server变量时,它将被设置为ForEach循环当前使用的$ server。也许我一般误解脚本规则?

提前致谢!

# $subject = "$server is not accepting RDP connections!"  # Why do these two lines have to be in the loop?
# $body = " Hello, `n `n This is an automatically generated message indicating that an attempt to RDP to $server has failed. Please investigate ASAP. `n `n Thank you."

$serversArray = @("host1","host2","host3")
$port = 3389
$status = ""

$emailFrom = "example@example.com"
$emailTo = "example@example.com" # To address
$relay = "smtp.example.com"
$smtp=new-object Net.Mail.SmtpClient($relay)

# For each loop that iterates through each server in the $serversArray array. This creates a generic socket connection and then calls it for the current server name.
# If the socket connection returns True for the connected status, the connection is closed.
# Otherwise, a failure email is sent.
ForEach ($server in $serversArray)
{
    $socket = new-object Net.Sockets.TcpClient
    $socket.Connect($server, $port)

    if ($socket.Connected) {
        $socket.Close()
        $status += "RDP port 3389 is open on $server `n"
    }
    else {
        $subject = "$server is not accepting RDP connections!"  # Everything works when this line is here, in the loop
        $body = " Hello, `n `n This is an automatically generated message indicating that an attempt to RDP to $server has failed. Please investigate ASAP. `n `n Thank you." # Everything works when this line is here, in the loop
        $smtp.Send($emailFrom, $emailTo, $subject, $body)
        $status += "RDP port 3389 is NOT open on $server `n" 
    }
}

echo $status

2 个答案:

答案 0 :(得分:0)

这很好用:

$serversArray = @("one", "two", "three")
$serversArray
ForEach ($server in $serversArray) {
  echo $server
 }

输出:

one
two
three

one
two
three

SUGGESTIONS:

1)删除数组定义中无关的“,”

2)“划分和征服”:测试你脚本的各个部分,然后将它们放在一起。

ALSO:

3)是的,$ server仅存在于“ForEach”块

4)是的,您可以在顶部定义$ subject和$ body。你不能使用$ server,但是你可以很容易地将$ server字符串与你实际使用它的$ subject字符串连接起来(在循环内)。

'希望有所帮助......

答案 1 :(得分:0)

在循环外移动Subject和Body文本的一个选项是将它们放入循环外的脚本块中,然后在循环内调用脚本块。

$NewSubject = { "$server is not accepting RDP connections!" } 

 $NewBody = { @"
 Hello, 

 This is an automatically generated message indicating that an attempt to RDP to $server has failed. Please investigate ASAP.

 Thank you.
"@ }

$serversArray = @("host1","host2","host3")
$port = 3389
$status = ""

$emailFrom = "example@example.com"
$emailTo = "example@example.com" # To address
$relay = "smtp.example.com"
$smtp=new-object Net.Mail.SmtpClient($relay)

# For each loop that iterates through each server in the $serversArray array. This creates a    generic socket connection and then calls it for the current server name.
# If the socket connection returns True for the connected status, the connection is closed.
# Otherwise, a failure email is sent.
ForEach ($server in $serversArray)
{
    $socket = new-object Net.Sockets.TcpClient
    $socket.Connect($server, $port)

    if ($socket.Connected) {
        $socket.Close()
        $status += "RDP port 3389 is open on $server `n"
    }
    else {
        $subject = &$NewSubject
        $body = &$NewBody
        $smtp.Send($emailFrom, $emailTo, $subject, $body)
        $status += "RDP port 3389 is NOT open on $server `n" 
    }
}

echo $status

对于像电子邮件正文这样的多行文本,here-string可以让您使用文字换行输入文本而不必使用转义控制字符,从而使您的代码更容易阅读。