使用Powershell-(中继,连接)在Windows Server中配置Smtp虚拟服务器

时间:2015-05-04 13:33:32

标签: powershell smtp

使用powershell我必须启用SMTP和

  • 添加继电器Ip
  • 添加连接IP
  • 设置访问控制身份验证

我找到了以下操作的以下代码

$GetSMTP = Get-CimInstance -Namespace "root\MicrosoftIISv2" -Class "IISSMTPServerSetting" -Filter "Name ='SmtpSvc/1'"
$RelayIps =  @(10,92,32,83,127,0,0,1)
$GetSMTP.RelayIpList = $RelayIps
Set-CimInstance -InputObject $GetSMTP

$GetSMTP
$GetSMTP = Get-CimInstance -Namespace "root\MicrosoftIISv2" -Class "IIsIPSecuritySetting" -Filter "Name ='SmtpSvc/1'"

$NewConnectionIps = @(
                     "10.92.32.80, 10.92.32.81";
                     "10.92.32.83,127.0.0.1";
                      )
$GetSMTP.ipgrant += $NewConnectionIps
Set-CimInstance -InputObject $GetSMTP

$GetSMTP

上面的powershell代码已成功执行,并在添加时列出。

但是当我连接到smtp服务器时,出现以下错误

enter image description here

我找到了解决上述问题的解决方案,删除“C:\ inetpub \ mailroot”中的文件夹,我可以启动默认的Smtp虚拟服务器,但是再次遇到问题,同时点击smtp vitrual服务器属性

enter image description here

4 个答案:

答案 0 :(得分:9)

  

加载功能安装模块

Import-Module ServerManager 
  

安装功能

Add-WindowsFeature SMTP-Server,Web-Mgmt-Console,WEB-WMI
  

为SMTP添加中继,连接IP和身份验证基本

$Networkip =@()
$Networks = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName    localhost | ? {$_.IPEnabled}
foreach($Network in $Networks)  {  $Networkip = $Network.IpAddress[0]  }
  

为SMTP添加中继和身份验证基本

$ipblock= @(24,0,0,128,
32,0,0,128,
60,0,0,128,
68,0,0,128,
1,0,0,0,
76,0,0,0,
0,0,0,0,
0,0,0,0,
1,0,0,0,
0,0,0,0,
2,0,0,0,
1,0,0,0,
4,0,0,0,
0,0,0,0,
76,0,0,128,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
255,255,255,255)

$ipList = @()
$octet = @()
$connectionips=$arg[0]       
$ipList = "127.0.0.1"
$octet += $ipList.Split(".")
$octet += $Networkip.Split(".")

$ipblock[36] +=2 
$ipblock[44] +=2;
$smtpserversetting = get-wmiobject -namespace root\MicrosoftIISv2 -computername localhost -Query "Select * from IIsSmtpServerSetting"
$ipblock += $octet
$smtpserversetting.AuthBasic=1
$smtpserversetting.RelayIpList = $ipblock
$smtpserversetting.put()
  

添加SMTP连接

$connectionips="10.10.10.10"      

$checkArray =$connectionips.split(",") 
if($checkArray -notcontains $Networkip)
{
 $connectionips += ","+$Networkip
}

$connectionipbuild=@()
$ipArray=$connectionips.split(",")
foreach ($ip in $ipArray)
{   
  $connectionipbuild +=$ip+",255.255.255.255;"     
}

$iisObject = new-object System.DirectoryServices.DirectoryEntry("IIS://localhost/SmtpSvc/1")
$ipSec = $iisObject.Properties["IPSecurity"].Value

# We need to pass values as one element object arrays
[Object[]] $grantByDefault = @()
$grantByDefault += , $false            # <<< We're setting it to false

$ipSec.GetType().InvokeMember("GrantByDefault", $bindingFlags, $null, $ipSec, $grantByDefault);

$iisObject.Properties["IPSecurity"].Value = $ipSec
$iisObject.CommitChanges()

$iisObject = new-object System.DirectoryServices.DirectoryEntry("IIS://localhost/SmtpSvc/1")
$ipSec = $iisObject.Properties["IPSecurity"].Value
$bindingFlags = [Reflection.BindingFlags] "Public, Instance, GetProperty"
$isGrantByDefault = $ipSec.GetType().InvokeMember("GrantByDefault", $bindingFlags, $null, $ipSec, $null);

# to set an iplist we need to get it first
if($isGrantByDefault)
{
    $ipList = $ipSec.GetType().InvokeMember("IPDeny", $bindingFlags, $null, $ipSec, $null);
}
else
{
    $ipList = $ipSec.GetType().InvokeMember("IPGrant", $bindingFlags, $null, $ipSec, $null);
}

# Add a single computer to the list:
$ipList = $ipList + $connectionipbuild

# This is important, we need to pass an object array of one element containing our ipList array
[Object[]] $ipArray = @()
$ipArray += , $ipList

# Now update
$bindingFlags = [Reflection.BindingFlags] "Public, Instance, SetProperty"
if($isGrantByDefault)
{
    $ipList = $ipSec.GetType().InvokeMember("IPDeny", $bindingFlags, $null, $ipSec, $ipArray);
}
else
{
    $ipList = $ipSec.GetType().InvokeMember("IPGrant", $bindingFlags, $null, $ipSec, $ipArray);
}

$iisObject.Properties["IPSecurity"].Value = $ipSec
$iisObject.CommitChanges()

答案 1 :(得分:0)

除了 PonVimal 答案(已接受):

此解决方案使用Indented.NetworkTools

中的Get-NetworkAddress功能

如果您想为计算机组而不是单个地址指定中继,您可以通过以下方式使用System.DirectoryServices(感谢this answer):

$IpRelayList = @("192.168.1.0, 255.255.0.0", 
                "127.3.4.0, 255.255.255.192")

#adding relays
$iisObject = new-object System.DirectoryServices.DirectoryEntry("IIS://localhost/smtpsvc/1")
$relays = $iisObject.Properties["RelayIpList"].Value
$bindingFlags = [Reflection.BindingFlags] "Public, Instance, GetProperty"
$ipList = $relays.GetType().InvokeMember("IPGrant", $bindingFlags, $null, $relays, $null);

#if relay list is empty we are retrieving host subnets and adding to relay
$Networkip =@()
if($IpRelayList.Count -eq 0)
{
    $Networks = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName localhost | ? {$_.IPEnabled}
    foreach($Network in $Networks)  
    {   
        $line = Get-NetworkAddress $Network.IpAddress[0] $Network.IpSubnet[0]
        $line = $line + ", " + $Network.IpSubnet[0]
        $Networkip += $line
    }
}

$ipList = $Networkip + $IpRelayList

# This is important, we need to pass an object array of one element containing our ipList array
[Object[]] $ipArray = @()
$ipArray += , $ipList

# Now update
$bindingFlags = [Reflection.BindingFlags] "Public, Instance, SetProperty"
$ipList = $relays.GetType().InvokeMember("IPGrant", $bindingFlags, $null, $relays, $ipArray);

$iisObject.Properties["RelayIpList"].Value = $relays
$iisObject.CommitChanges()

答案 2 :(得分:0)

除了PonVimal的回答(已接受):

我还希望SMTPSVC服务是自动的,并提供了幂等脚本,以确保该服务不仅已安装,而且设置为自动并已启动,因此任何后续的计算机重新启动都不需要我手动启动该服务。

# ----- Converting service: "Simple Mail Transfer Protocol" to be automatic from manual ------
$ServiceName= "SMTPSVC"

    If (Get-Service $ServiceName -ErrorAction SilentlyContinue) {
        If ((Get-Service $ServiceName).StartType -ne "Automatic") {
            If ((Get-Service $ServiceName).Status -eq 'Running') {
                Stop-Service $ServiceName
                "Stopping $ServiceName"
            } Else {
                        "ServiceName found, and it is stopped."
                    }
            Set-Service -Name $ServiceName -StartupType "Automatic"
            Do{
            "Starting service: $ServiceName"
            sc.exe start "$ServiceName"
            start-sleep -s 5
            $ServiceStatus = (get-service -name $ServiceName)
            } 
            Until ($ServiceStatus.Status -eq "running")
            "Service Started: $ServiceName"
        }

        If ((Get-Service $ServiceName).Status -eq 'Running') {
            "`n$ServiceName configured as automatic and running`n"
        } Else {
            Do{
            "Starting service: $ServiceName"
            sc.exe start "$ServiceName"
            start-sleep -s 5
              $ServiceStatus = (get-service -name $ServiceName)
            } 
            Until ($ServiceStatus.Status -eq "running")
            "Service Started: $ServiceName"
          }
        } Else {
        "$ServiceName not found"
    }

# Test to check if the service is configured correctly and is running
If (Get-Service $ServiceName) {

    If ((Get-Service $ServiceName).StartType -ne "Automatic") {
        throw "$ServiceName is not configured as automatic"

    }
    If ((Get-Service $ServiceName).Status -ne 'Running') {
        throw "$ServiceName is not running"

    }
    "`n$ServiceName configured as automatic and running`n"
}

答案 3 :(得分:0)

这实际上是可能的,并且比人们想象的要复杂。这个神奇的中继IP列表对象具有一些硬编码到其中的收集长度。

这是我发现怪异之后使用的脚本的一部分。

param(
    [Parameter(ValueFromRemainingArguments=$true)][object[]]$AllowedIPs
)

$SMTPServerWmi = Get-WmiObject IISSmtpServerSetting -namespace "ROOT\MicrosoftIISv2" | Where-Object { $_.name -like "SmtpSVC/1" }
$SMTPServerWmi.RelayIpList = @(24,0,0,128,
32,0,0,128,
60,0,0,128,
68,0,0,128,
1,0,0,0,
76,0,0,0,
0,0,0,0,
0,0,0,0,
1,0,0,0,
$AllowedIPs.Count,0,0,0,
2,0,0,0,
($AllowedIPs.Count + 1),0,0,0,
4,0,0,0,
0,0,0,0,
76,0,0,128,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
255,255,255,255) + $AllowedIPs.ForEach({ $_.Split(".")})

$SMTPServerWmi.Put()

如果这些值不正确,则UI可能会显示您的IP以及许多随机的垃圾,崩溃或损坏,以致您无法使用它使用UI从列表中删除项目。