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

使用Powershell-(中继,连接)在windows服务器中配置Smtp虚拟服务器,powershell,smtp,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 = $Relay

使用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服务器时,出现以下错误

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

加载功能安装模块

安装功能

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

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

正在为SMTP添加连接

$connectionips=“10.10.10.10”
$checkArray=$connectionips.split(“,”)
if($checkArray-notcontains$Networkip)
{
$connectionips+=“,”+$Networkip
}
$connectionipbuild=@()
$ipArray=$connectionips.split(“,”)
foreach($ipArray中的ip)
{   
$connectionipbuild+=$ip+”,255.255.255.255;”
}
$iisObject=new object System.DirectoryServices.DirectoryEntry(“IIS://localhost/SmtpSvc/1”)
$ipSec=$iisObject.Properties[“IPSecurity”].Value
#我们需要将值作为一个元素对象数组传递
[对象[]]$grantByDefault=@()
$grantByDefault+=,$false#除了PonVimal的回答之外(接受):
此解决方案使用从中获取网络地址功能

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


除了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"
}

这实际上是可能的,而且比人们想象的要复杂得多。这个神奇的中继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从列表中删除项目。

感谢您添加这些详细信息。在那之前这个问题很模糊。那么事件观察家会怎么说?!事件查看器有一个警告“实例1具有无效的绑定描述符:”,还有一个错误“服务无法绑定实例1。数据是错误代码。”您好,请在回答中包含链接中的相关部分好吗?这样,如果链接失效,您的答案仍然有用。非常感谢,$ipblock数组代表什么?我在多个示例中看到过它,没有任何解释。本页上的脚本对元素36和44执行
+=1
。上面未编辑的答案有
$connectionipbuild=“10.10.10.10,11.11.11.11”
即,添加了2个硬编码地址,因此需要执行
+=2
。我相信,也许上面的脚本应该为它添加的
$ipList
$Networkip
中的每一个做
+=1
$ipblock
中的IP地址是否有特殊意义,但不是真正的IP地址?36和44处的元素似乎反映了对话框中的IP数。我尝试将其设置为随机值,然后尝试单击smtp中继对话框中的“应用”以覆盖它们,并导致mmc在访问内存时崩溃。
$Networkip =@()
$Networks = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName    localhost | ? {$_.IPEnabled}
foreach($Network in $Networks)  {  $Networkip = $Network.IpAddress[0]  }
$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()
$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()
$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()
# ----- 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"
}
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()