You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求修改域控PowerShell脚本,将防火墙配置执行结果导出为CSV

修改后的PowerShell脚本(含执行结果统计与CSV日志)

以下是修改后的脚本,新增了执行结果统计(成功/失败节点数)及失败日志的CSV记录功能,同时修复了原脚本中的拼写错误和逻辑问题:

clear
write-host "`n`n`n==============================================================================="
write-host "============This script is to only allow specific subnet to particular ports ====================" -fore Green
write-host "NOTE: Before run the script make sure all the servers are UP, Reachable & WinRM Connectivity is fine" -fore Yellow
write-host "===============================================================================`n`n"

########## Port numbers to restrict access
$ports=@(22,53,88,135,136,137,138,139,389,445,1801,1433,3389,5985,5986,5671,5672,8080)
$IPsubnets = @("63.145.62.0/25")

# 初始化统计变量
$successCount = 0
$failureCount = 0
$failureLogs = @()

function configure-firewall($IPsubnets,$ports)
{
    foreach($port in $ports)
    {
        if(! (Get-NetFirewallPortFilter | Where-Object -Property LocalPort -EQ $port))
        {
            write-host "firewall rule not exists for port : $port. creating"
            try
            {
                New-NetFirewallRule -Group 'Philips' -Action Allow -LocalPort $port -Direction inbound -Protocol TCP -DisplayName 'PerimeterSecurity'
            }
            catch
            {
                $errorMsg = "Error creating rule for port $port : $($_.Exception.Message)"
                Write-Host $errorMsg -ForegroundColor Red
                throw $errorMsg # 抛出错误,让上层Invoke-Command捕获
            }
        }
        
        try
        {
            Get-NetFirewallPortFilter | Where-Object -Property LocalPort -EQ $port | 
            Get-NetFirewallRule | Where-Object -property Direction -EQ inbound| 
            Where-Object -Property Enabled -eq True | 
            Set-NetFirewallRule -Action Allow -RemoteAddress $($IPsubnets) -ErrorAction Stop
        }
        catch
        {
            $errorMsg = "Error updating rule for port $port : $($_.Exception.Message)"
            Write-Host $errorMsg -ForegroundColor Red
            throw $errorMsg
        }
    }
}

while($True)
{
    $IPsubnet =Read-host "Enter IP subnet Range  (example - 172.16.20.0/24)  "
    $status = [bool]($IPsubnet.split('/')[0] -as [ipaddress])
    
    if ($status) 
    {
        $IPsubnets += $IPsubnet
        $input = Read-Host "Do you want to add another Subnet ? (y/n)"
        if ($input -eq 'n')
        {
            break
        }
    }
    else
    {
        Write-Host "`n$IPsubnet is not a Valid IP Address.. Enter Valid IP Address" -fore Red
    }
}

# 获取成员服务器
try
{
    $memberServers=Get-ADComputer -Filter * -Properties ipv4Address 
}
catch 
{
    write-host "This is not a Domain controller. So firewall settings will be applied only to the local host" -ForegroundColor Yellow
    $memberServers = @([PSCustomObject]@{name = $env:COMPUTERNAME})
}

foreach ($memberServer in $memberServers)
{
    try
    {
        $serverName = $memberServer.name
        write-host "Executing on $serverName" -ForegroundColor Yellow
        
        # 初始化错误变量
        $invokeErrors = $null
        Invoke-Command -ComputerName $serverName -ScriptBlock ${function:configure-firewall} -ArgumentList $IPsubnets, $ports -ErrorVariable invokeErrors -ErrorAction SilentlyContinue
        
        if(-not $invokeErrors)
        {
            write-host "Successfully executed on $serverName" -ForegroundColor Green
            $successCount++
        }
        else
        {
            write-host "Error found on $serverName" -ForegroundColor Red
            write-host "Details: $($invokeErrors -join '; ')" -BackgroundColor Red
            
            # 记录失败日志
            $failureLogs += [PSCustomObject]@{
                ServerName = $serverName
                ErrorMessage = $invokeErrors -join '; '
                Timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
            }
            $failureCount++
        }
    }
    catch
    {
        $serverName = $memberServer.name
        $errorMsg = $_.Exception.Message
        write-host "Unexpected error on $serverName : $errorMsg" -BackgroundColor Red
        
        $failureLogs += [PSCustomObject]@{
            ServerName = $serverName
            ErrorMessage = $errorMsg
            Timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
        }
        $failureCount++
    }
}

# 生成统计摘要对象
$summary = [PSCustomObject]@{
    Category = "Summary"
    ServerName = "N/A"
    ErrorMessage = "Total Servers: $($successCount + $failureCount); Successful: $successCount; Failed: $failureCount"
    Timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
}

# 合并摘要与失败日志,写入CSV
$outputPath = ".\FirewallConfigResult_$(Get-Date -Format 'yyyyMMddHHmmss').csv"
$summary, $failureLogs | Export-Csv -Path $outputPath -NoTypeInformation -Encoding UTF8

write-host "`n==============================================================================="
write-host "Execution completed. Result saved to: $outputPath" -ForegroundColor Green
write-host "Summary: Successful servers: $successCount | Failed servers: $failureCount" -ForegroundColor Cyan
write-host "===============================================================================`n"

关键修改说明

  • 统计功能:新增$successCount、$failureCount变量实时统计执行结果,最终汇总到CSV的摘要行
  • 失败日志记录:用$failureLogs数组存储每个失败节点的服务器名、错误详情和时间戳,确保问题可追溯
  • 错误捕获优化:修复原脚本的拼写错误,同时在防火墙配置函数中抛出错误,确保远程执行的错误能被上层捕获
  • CSV输出:自动生成带时间戳的CSV文件,包含统计摘要和失败明细,便于后续分析
  • 兼容性修复:完善非域控制器场景下的本地主机处理逻辑,确保脚本在非DC环境也能正常执行

内容的提问来源于stack exchange,提问作者jimmyafflick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 08:02:02