完整的WindowsServer服务器系统初始化配置、安全策略加固和基线检查脚本等保2.0适用

转载自:https://www.bilibili.com/read/cv14326780?spm_id_from=333.999.0.0

0x00 前言简述

最近单位在做等保测评,由于本人从事安全运维方面的工作(PS:曾经做过等保等方面的安全服务),所以自然而然的与信安的测评人员一起对接相关业务系统的检查,在做主机系统测评检查时发现了系统中某些配置不符合等保要求,需要对不满足要求的主机做进一步整改,好在我们众多的系统基本都是运行在虚拟机上搭建的kubernetes集群中,这样一来就可以尽可能减少加固系统给应用带来的影响,我们可以一台一台加固更新。

在这样环境的驱动下不得不将通宵熬夜,我准备好了枸杞和保温杯,当然也把测试环境也准备了一套,并将以前写的安全加固脚本进行重新整理,根据当前业务服务器系统版本进行更新和测试。(我还年轻,我还可加班!)

我们企业内部主要有WindowsServer2019、CentOS7、以及Ubuntu20.04三类操作系统,可以看出操作系统版本都还是比较新的,所以在下面的安全配置核查脚本以及安全加固脚本主要针对上述的三个版本的操作系统。

Linux 系统中采用Shell脚本、Wiindows Server系统中采用的是PowerShell脚本进行编写。

Github 项目地址: https://github.com/WeiyiGeek/SecOpsDev/blob/master/OS-操作系统/Linux/

Windows Sever2019 安全配置策略基线配置核查效果图

完整的WindowsServer服务器系统初始化配置、安全策略加固和基线检查脚本等保2.0适用
完整的WindowsServer服务器系统初始化配置、安全策略加固和基线检查脚本等保2.0适用
完整的WindowsServer服务器系统初始化配置、安全策略加固和基线检查脚本等保2.0适用
完整的WindowsServer服务器系统初始化配置、安全策略加固和基线检查脚本等保2.0适用

Windows Sever2019 主机测评项安全加固效果图

完整的WindowsServer服务器系统初始化配置、安全策略加固和基线检查脚本等保2.0适用
完整的WindowsServer服务器系统初始化配置、安全策略加固和基线检查脚本等保2.0适用
完整的WindowsServer服务器系统初始化配置、安全策略加固和基线检查脚本等保2.0适用

0x01 WindowServer2019 配置核查

Windows Server 安全配置策略基线加固项

系统账号策略
系统事件审核策略
系统组策略安全选项策略
注册表相关安全策略
防火墙服务相关安全策略
针对于系统暂无办法通过注册表以及组策略配置的安全加固项
从微软安全中心拉取服务器安全补丁列表信息与本地已打补丁做比较

废话不多,上才艺(脚本 )

Windows Server 安全配置策略基线检测脚本: WindowsSecurityBaseLine.ps1

#######################################################
@Author: WeiyiGeek
@Description:  Windows Server 安全配置策略基线检测脚本
@Create Time:  2019年5月6日 11:04:42
@Last Modified time: 2021-11-15 11:06:31
@E-mail: master@weiyigeek.top
@Blog: https://www.weiyigeek.top
@wechat: WeiyiGeeker
@Github: https://github.com/WeiyiGeek/SecOpsDev/tree/master/OS-操作系统/Windows/
@Version: 1.8
@Runtime: Server 2019 / Windows 10
#######################################################

<# .synopsis windows server 安全配置策略基线检测脚本 (脚本将会在github上持续更新) .description 操作系统配置策略核查 (符合等保3级的关键检查项) .example windowssecuritybaseline.ps1 -executor weiyigeek -msrcupdate false - executor : 脚本执行者 msrcupdate 是否在线拉取微软安全中心的服务器安全补丁列表信息(建议一台主机拉取好之后将wsuslist.json和wsuslistid.json拷贝到当前脚本同级目录下) .notes 注意:不同的版本操作系统以下某些关键项可能会不存在会有一些警告(需要大家提交issue,共同完成)。 #>
[Cmdletbinding()]
param(
  [Parameter(Mandatory=$true)][String]$Executor,
  [Boolean]$MsrcUpdate
)

* &#x6587;&#x4EF6;&#x8F93;&#x51FA;&#x9ED8;&#x8BA4;&#x4E3A;UTF-8&#x683C;&#x5F0F;
$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'

################################################################################################################################
**********************#
* &#x5168;&#x5C40;&#x516C;&#x7528;&#x5DE5;&#x5177;&#x4F9D;&#x8D56;&#x51FD;&#x6570;  *
**********************#
Function F_IsCurrentUserAdmin
{
<# .synopsis f_iscurrentuseradmin 函数:全局公用工具依赖。 .description 判断当前运行的powershell终端是否管理员执行,返回值 true 或者 false .example #>
  $user = [Security.Principal.WindowsIdentity]::GetCurrent();
  (New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}

function F_Logging {
<# .synopsis f_logging 日志输出函数 .description 用于输出脚本执行结果并按照不同的日志等级输出显示到客户终端上。 .example -level [info|warning|error] -msg "测试输出字符串" #>
  param (
    [Parameter(Mandatory=$true)]$Msg,
    [ValidateSet("Info","Warning","Error")]$Level
  )

  switch ($Level) {
    Info {
      Write-Host "[INFO] ${Msg}" -ForegroundColor Green;
    }
    Warning {
      Write-Host "[WARN] ${Msg}" -ForegroundColor Yellow;
    }
    Error {
      Write-Host "[ERROR] ${Msg}" -ForegroundColor Red;
    }
    Default {
      Write-Host "[*] F_Logging &#x65E5;&#x5FD7; Level &#x7B49;&#x7EA7;&#x9519;&#x8BEF;n Useage: F_Logging -Level [Info|Warning|Error] -Msg '测试输出字符串'" -ForegroundColor Red;
    }
  }
}

function F_Tools {
<# .synopsis f_tools 检测对比函数 .description 验证判断传入的字段是否与安全加固字段一致 .example -key "itemdemo" -value "2" -operator "eq" -defaultvalue "1" -msg "对比itemdemo字段值与预设值" #>
  param (
    [Parameter(Mandatory=$true)][String]$Key,
    [Parameter(Mandatory=$true)]$Value,
    [Parameter(Mandatory=$true)]$DefaultValue,
    [String]$Msg,
    [String]$Operator
  )

  if ( $Operator -eq  "eq" ) {
    if ( $Value -eq $DefaultValue ) {
      $Result = @{"$($Key)"="[合格项]|$($Value)|$($DefaultValue)|$($Msg)-【符合】等级保护标准."}
      Write-Host "$($Key)"=" [合格项]|$($Value)|$($DefaultValue)|$($Msg)-【符合】等级保护标准." -ForegroundColor White
      return $Result
    } else {
      $Result = @{"$($Key)"="[异常项]|$($Value)|$($DefaultValue)|$($Msg)-【不符合】等级保护标准."}
      Write-Host "$($Key)"=" [异常项]|$($Value)|$($DefaultValue)|$($Msg)-【不符合】等级保护标准." -ForegroundColor red
      return $Result
    }

  } elseif ($Operator -eq  "ne" ) {

    if ( $Value -ne $DefaultValue ) {
      $Result = @{"$($Key)"="[合格项]|$($Value)|$($DefaultValue)|$($Msg)-【符合】等级保护标准."}
      Write-Host "$($Key)"=" [合格项]|$($Value)|$($DefaultValue)|$($Msg)-【符合】等级保护标准." -ForegroundColor White
      return $Result
    } else {
      $Result = @{"$($Key)"="[异常项]|$($Value)|$($DefaultValue)|$($Msg)-【不符合】等级保护标准."}
      Write-Host "$($Key)"=" [异常项]|$($Value)|$($DefaultValue)|$($Msg)-【不符合】等级保护标准." -ForegroundColor red
      return $Result
    }

  } elseif ($Operator -eq  "le") {

    if ( $Value -le $DefaultValue ) {
      $Result = @{"$($Key)"="[合格项]|$($Value)|$($DefaultValue)|$($Msg)-【符合】等级保护标准."}
      Write-Host "$($Key)"=" [合格项]|$($Value)|$($DefaultValue)|$($Msg)-【符合】等级保护标准." -ForegroundColor White
      return $Result
    } else {
      $Result = @{"$($Key)"="[异常项]|$($Value)|$($DefaultValue)|$($Msg)-【不符合】等级保护标准."}
      Write-Host "$($Key)"=" [异常项]|$($Value)|$($DefaultValue)|$($Msg)-【不符合】等级保护标准." -ForegroundColor red
      return $Result
    }

  } elseif ($Operator -eq "ge") {

    if ( $Value -ge $DefaultValue ) {
      $Result =  @{"$($Key)"="[合格项]|$($Value)|$($DefaultValue)|$($Msg)-【符合】等级保护标准."}
      Write-Host "$($Key)"=" [合格项]|$($Value)|$($DefaultValue)|$($Msg)-【符合】等级保护标准." -ForegroundColor White
      return $Result
    } else {
      $Result = @{"$($Key)"="[异常项]|$($Value)|$($DefaultValue)|$($Msg)-【不符合】等级保护标准."}
      Write-Host "$($Key)"=" [异常项]|$($Value)|$($DefaultValue)|$($Msg)-【不符合】等级保护标准." -ForegroundColor red
      return $Result
    }
  }
}

function F_GetRegPropertyValue {
  param (
    [Parameter(Mandatory=$true)][String]$Key,
    [Parameter(Mandatory=$true)][String]$Name,
    [Parameter(Mandatory=$true)][String]$Operator,
    [Parameter(Mandatory=$true)]$DefaultValue,
    [Parameter(Mandatory=$true)][String]$Msg
  )

  try {
    $Value = Get-ItemPropertyValue -Path "Registry::$Key" -ErrorAction Ignore -WarningAction Ignore -Name $Name
    $Result = F_Tools -Key "Registry::$($Name)" -Value $Value -Operator $Operator -DefaultValue $DefaultValue  -Msg $Msg
    return $Result
  } catch {
   $Result = @{"Registry::$($Name)"="[异常项]|$($Key)中$($Name)不存在该项|$($DefaultValue)|$($Msg)"}
   Write-Host $Result.Values -ForegroundColor Red
   return $Result
  }
}

Function F_UrlRequest {
  param (
    [Parameter(Mandatory=$true)][String]$Msrc_api
  )
  Write-Host "[-] $($Msrc_api)" -ForegroundColor Gray
  $Response=Invoke-WebRequest -Uri "$($Msrc_api)"
  Return ConvertFrom-Json -InputObject $Response
}

################################################################################################################################
#
* 操作系统基础信息记录函数 * #
#
- 系统信息记录函数 - #
$SysInfo = @{}
- Get-Computer 命令使用
Tips :在 Server 2019 以及 Windows 10 以下系统无该命令
$Item = 'WindowsProductName','WindowsEditionId','WindowsInstallationType','WindowsCurrentVersion','WindowsVersion','WindowsProductId','BiosManufacturer','BiosFirmwareType','BiosName','BiosVersion','BiosBIOSVersion','BiosSeralNumber','CsBootupState','OsBootDevice','BiosReleaseDate','CsName','CsAdminPasswordStatus','CsManufacturer','CsModel','OsName','OsType','OsProductType','OsServerLevel','OsArchitecture','CsSystemType','OsOperatingSystemSKU','OsVersion','OsBuildNumber','OsSerialNumber','OsInstallDate','OsSystemDevice','OsSystemDirectory','OsCountryCode','OsCodeSet','OsLocaleID','OsCurrentTimeZone','TimeZone','OsLanguage','OsLocalDateTime','OsLastBootUpTime','CsProcessors','OsBuildType','CsNumberOfProcessors','CsNumberOfLogicalProcessors','OsMaxNumberOfProcesses','OsTotalVisibleMemorySize','OsFreePhysicalMemory','OsTotalVirtualMemorySize','OsFreeVirtualMemory','OsInUseVirtualMemory','OsMaxProcessMemorySize','CsNetworkAdapters','OsHotFixes'
- Systeminfo 命令使用(通用-推荐)
$Item = 'Hostname','OSName','OSVersion','OSManufacturer','OSConfiguration','OS Build Type','RegisteredOwner','RegisteredOrganization','Product ID','Original Install Date','System Boot Time','System Manufacturer','System Model','System Type','Processor(s)','BIOS Version','Windows Directory','System Directory','Boot Device','System Locale','Input Locale','Time Zone','Total Physical Memory','Available Physical Memory','Virtual Memory: Max Size','Virtual Memory: Available','Virtual Memory: In Use','Page File Location(s)','Domain','Logon Server','Hotfix(s)','Network Card(s)'
Function F_SysInfo {
  # - 当前系统及计算机相关信息 (Primary)
  # Server 2019 以及 Windows 10 适用
  # $Computer = Get-ComputerInfo
  $Computer = systeminfo.exe /FO CSV /S $env:COMPUTERNAME |Select-Object -Skip 1 | ConvertFrom-CSV -Header $Item
  foreach( $key in $Item) {
    $SysInfo += @{"$($key)"=$Computer.$key}
  }
  # - 通用设置针对采用.exe命令方式
  $SysInfo += @{"WindowsProductName"="$($SysInfo.OSName)"}
  $SysInfo.OsVersion=($Sysinfo.OSVersion -split " ")[0]
  $SysInfo += @{"CsSystemType"=($Sysinfo."System Type" -split " ")[0]}

  # - 当前系统 PowerShell 版本信息以及是否为虚拟机
  $SysInfo += @{"PSVersion"=$PSVersionTable.PSEdition+"-"+$PSVersionTable.PSVersion}

  # - 验证当前计算机产品及其版本 (Primary)
  $Flag = $SysInfo.WindowsProductName -match  "Windows 8.1|Windows 10|Server 2008|Server 2012|Server 2016|Server 2019"
  $ProductName = "$($Matches.Values)"
  if ( $ProductName.Contains("Windows")) {
    $SysInfo += @{"ProductType"="Client"}
    $SysInfo += @{"ProductName"=$ProductName}
    $SysInfo += @{"WindowsVersion"=Get-ItemPropertyValue -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name ReleaseId}
  } else {
    $SysInfo += @{"ProductType"="Server"}
    $SysInfo += @{"ProductName"=$ProductName}
  }

  # - 验证当前计算机产品是是物理机还是虚拟机 (Primary)
  $ComputerType = get-wmiobject win32_computersystem
  if ($ComputerType.Manufacturer -match "VMware"){
    $SysInfo += @{"ComputerType"="虚拟机 - $($ComputerType.Model)"}
  } else {
    $SysInfo += @{"ComputerType"="物理机 - $($ComputerType.Model)"}
  }

  # # - 当前计算机温度值信息记录 (WINDOWSERVER2019支持)
  # Get-CimInstance -Namespace ROOT/WMI -Class MSAcpi_ThermalZoneTemperature | % {
  #   $currentTempKelvin = $_.CurrentTemperature / 10
  #   $currentTempCelsius = $currentTempKelvin - 273.15
  #   $currentTempFahrenheit = (9/5) * $currentTempCelsius + 32
  #   $Temperature += "InstanceName: " + $_.InstanceName+ " ==>> " +  $currentTempCelsius.ToString() + " 摄氏度(C);  " + $currentTempFahrenheit.ToString() + " 华氏度(F) ; " + $currentTempKelvin + "开氏度(K) "
  # }
  # $SysInfo += @{"Temperature"=$Temperature}

  return $SysInfo
}

#
* - &#x8BA1;&#x7B97;&#x673A;Mac&#x53CA;IP&#x5730;&#x5740;&#x4FE1;&#x606F;&#x51FD;&#x6570; * #
#
 * &#x7CFB;&#x7EDF;&#x7F51;&#x7EDC;&#x53CA;&#x9002;&#x914D;&#x5668;&#x4FE1;&#x606F;&#x53D8;&#x91CF; * #
$SysNetAdapter = @{}
function F_SysNetAdapter {
  # - &#x8BA1;&#x7B97;&#x673A;Mac&#x53CA;IP&#x5730;&#x5740;&#x4FE1;&#x606F;
  $Adapter = Get-NetAdapter | Sort-Object -Property LinkSpeed
  foreach ( $Item in $Adapter) {
    $IPAddress = (Get-NetIPAddress -AddressFamily IPv4 -InterfaceIndex $Item.ifIndex).IPAddress
    $SysNetAdapter += @{"$($Item.MacAddress)"="$($Item.Status) | $($Item.Name) | $($IPAddress) | $($Item.LinkSpeed) | $($Item.InterfaceDescription)"}
  }
  return $SysNetAdapter
}

#
* - &#x8BA1;&#x7B97;&#x673A;&#x7CFB;&#x7EDF;&#x78C1;&#x76D8;&#x4E0E;&#x7A7A;&#x95F4;&#x5269;&#x4F59;&#x67E5;&#x8BE2;&#x51FD;&#x6570; * #
#
- &#x7CFB;&#x7EDF;&#x78C1;&#x76D8;&#x4E0E;&#x7A7A;&#x95F4;&#x5269;&#x4F59;&#x4FE1;&#x606F; - #
$SysDisk = @{}
function F_SysDisk {
  # - &#x8BA1;&#x7B97;&#x673A;&#x78C1;&#x76D8;&#x4FE1;&#x606F;
  $Disk = Get-Disk
  foreach ( $Item in $Disk) {
    $SysDisk += @{"$($Item.SerialNumber)"="$($Item.Number) | $($Item.FriendlyName) | $($Item.HealthStatus)| $($Item.Size / [math]::Pow(1024,3)) GB | $($Item.PartitionStyle) |$($Item.OperationalStatus)"}
  }
  $Drive = Get-PSDrive -PSProvider FileSystem | Sort-Object -Property Name
  $Drive | % {
    $Free = [Math]::Round( $_.Free / [math]::pow(1024,3),2 )
    $Used = [Math]::Round( $_.Used / [math]::pow(1024,3),2 )
    $Total = [Math]::Ceiling($Free + $Used)
    $SysDisk += @{"FileSystem::$($_.Name)"="$($_.Name) | Free: $($Free) GB | Used: $($Used) GB | Total: $($Total) GB"}
  }
  return $SysDisk
}

#
* &#x7CFB;&#x7EDF;&#x8D26;&#x53F7;&#x68C0;&#x67E5;&#x51FD;&#x6570;  * #
#
- &#x7CFB;&#x7EDF;&#x8D26;&#x6237;&#x4FE1;&#x606F;&#x53D8;&#x91CF; - #
$SysAccount = @{}
Function F_SysAccount {
  # - &#x8D26;&#x6237;&#x68C0;&#x67E5;
  $Account = Get-WmiObject -Class Win32_UserAccount | Select-Object Name,AccountType,Caption,SID
  Write-Host "* &#x5F53;&#x524D;&#x7CFB;&#x7EDF;&#x5B58;&#x5728;&#x7684; $($Account.Length) &#x540D;&#x8D26;&#x6237; : $($Account.Name)" -ForegroundColor Green
  if($Acount.Length -ge 4 -and ($Account.sid  | Select-String -Pattern "^((?!(-500|-501|-503|-504)).)*$")) {
    $Result = @{"SysAccount"="[&#x5F02;&#x5E38;&#x9879;]-&#x7CFB;&#x7EDF;&#x4E2D;&#x5B58;&#x5728;&#x5176;&#x4ED6;&#x8D26;&#x53F7;&#x8BF7;&#x68C0;&#x67E5;: $($Account.Name)"}
    $SysAccount += $Result
  }else{
    $Result = @{"SysAccount"="[&#x5408;&#x683C;&#x9879;]-&#x7CFB;&#x7EDF;&#x4E2D;&#x65E0;&#x591A;&#x4F59;&#x5176;&#x4ED6;&#x8D26;&#x53F7;";}
    $SysAccount += $Result
  }
  return $SysAccount
}

#
* &#x7CFB;&#x7EDF;&#x8D26;&#x53F7;&#x7B56;&#x7565;&#x914D;&#x7F6E;&#x6838;&#x67E5;&#x51FD;&#x6570;  * #
#
- &#x7CFB;&#x7EDF;&#x8D26;&#x53F7;&#x7B56;&#x7565; - #
$SysAccountPolicy = @{
  # + &#x5BC6;&#x7801;&#x6700;&#x77ED;&#x7559;&#x5B58;&#x671F;
  "MinimumPasswordAge" = @{operator="le";value=1;msg="&#x5BC6;&#x7801;&#x6700;&#x77ED;&#x7559;&#x5B58;&#x671F;"}
  # + &#x5BC6;&#x7801;&#x6700;&#x957F;&#x7559;&#x5B58;&#x671F;
  "MaximumPasswordAge" = @{operator="le";value=90;msg="&#x5BC6;&#x7801;&#x6700;&#x957F;&#x7559;&#x5B58;&#x671F;"}
  # + &#x5BC6;&#x7801;&#x957F;&#x5EA6;&#x6700;&#x5C0F;&#x503C;
  "MinimumPasswordLength" = @{operator="ge";value=14;msg="&#x5BC6;&#x7801;&#x957F;&#x5EA6;&#x6700;&#x5C0F;&#x503C;"}
  # + &#x5BC6;&#x7801;&#x5FC5;&#x987B;&#x7B26;&#x5408;&#x590D;&#x6742;&#x6027;&#x8981;&#x6C42;
  "PasswordComplexity" = @{operator="eq";value=1;msg="&#x5BC6;&#x7801;&#x5FC5;&#x987B;&#x7B26;&#x5408;&#x590D;&#x6742;&#x6027;&#x8981;&#x6C42;&#x7B56;&#x7565;"}
  # + &#x5F3A;&#x5236;&#x5BC6;&#x7801;&#x5386;&#x53F2; N&#x4E2A;&#x8BB0;&#x4F4F;&#x7684;&#x5BC6;&#x7801;
  "PasswordHistorySize" = @{operator="ge";value=3;msg="&#x5F3A;&#x5236;&#x5BC6;&#x7801;&#x5386;&#x53F2;&#x4E2A;&#x8BB0;&#x4F4F;&#x7684;&#x5BC6;&#x7801;"}
  # + &#x8D26;&#x6237;&#x767B;&#x5F55;&#x5931;&#x8D25;&#x9501;&#x5B9A;&#x9608;&#x503C;N&#x6B21;&#x6570;
  "LockoutBadCount" = @{operator="le";value=6;msg="&#x8D26;&#x6237;&#x767B;&#x5F55;&#x5931;&#x8D25;&#x9501;&#x5B9A;&#x9608;&#x503C;&#x6B21;&#x6570;"}
  # + &#x8D26;&#x6237;&#x9501;&#x5B9A;&#x65F6;&#x95F4;(&#x5206;&#x949F;)
  "ResetLockoutCount" = @{operator="ge";value=15;msg="&#x8D26;&#x6237;&#x9501;&#x5B9A;&#x65F6;&#x95F4;(&#x5206;&#x949F;)"}
  # + &#x590D;&#x4F4D;&#x8D26;&#x6237;&#x9501;&#x5B9A;&#x8BA1;&#x6570;&#x5668;&#x65F6;&#x95F4;(&#x5206;&#x949F;)
  "LockoutDuration" = @{operator="ge";value=15;msg="&#x590D;&#x4F4D;&#x8D26;&#x6237;&#x9501;&#x5B9A;&#x8BA1;&#x6570;&#x5668;&#x65F6;&#x95F4;(&#x5206;&#x949F;)"}
  # + &#x4E0B;&#x6B21;&#x767B;&#x5F55;&#x5FC5;&#x987B;&#x66F4;&#x6539;&#x5BC6;&#x7801;
  "RequireLogonToChangePassword" = @{operator="eq";value=0;msg="&#x4E0B;&#x6B21;&#x767B;&#x5F55;&#x5FC5;&#x987B;&#x66F4;&#x6539;&#x5BC6;&#x7801;"}
  # + &#x5F3A;&#x5236;&#x8FC7;&#x671F;
  "ForceLogoffWhenHourExpire" = @{operator="eq";value=0;msg="&#x5F3A;&#x5236;&#x8FC7;&#x671F;"}
  # + &#x5F53;&#x524D;&#x7BA1;&#x7406;&#x8D26;&#x53F7;&#x767B;&#x9646;&#x540D;&#x79F0;
  "NewAdministratorName" = @{operator="ne";value='"Administrator"';msg="&#x5F53;&#x524D;&#x7CFB;&#x7EDF;&#x9ED8;&#x8BA4;&#x7BA1;&#x7406;&#x8D26;&#x53F7;&#x767B;&#x9646;&#x540D;&#x79F0;&#x7B56;&#x7565;"}
  # + &#x5F53;&#x524D;&#x6765;&#x5BBE;&#x7528;&#x6237;&#x767B;&#x9646;&#x540D;&#x79F0;
  "NewGuestName" = @{operator="ne";value='"Guest"';msg="&#x5F53;&#x524D;&#x7CFB;&#x7EDF;&#x9ED8;&#x8BA4;&#x6765;&#x5BBE;&#x7528;&#x6237;&#x767B;&#x9646;&#x540D;&#x79F0;&#x7B56;&#x7565;"}
  # + &#x7BA1;&#x7406;&#x5458;&#x662F;&#x5426;&#x88AB;&#x542F;&#x7528;
  "EnableAdminAccount" = @{operator="eq";value=1;msg="&#x7BA1;&#x7406;&#x5458;&#x8D26;&#x6237;&#x505C;&#x7528;&#x4E0E;&#x542F;&#x7528;&#x7B56;&#x7565;"}
  # + &#x6765;&#x5BBE;&#x7528;&#x6237;&#x662F;&#x5426;&#x542F;&#x7528;
  "EnableGuestAccount" = @{operator="eq";value=0;msg="&#x6765;&#x5BBE;&#x8D26;&#x6237;&#x505C;&#x7528;&#x4E0E;&#x542F;&#x7528;&#x7B56;&#x7565;"}
  # + &#x6307;&#x793A;&#x662F;&#x5426;&#x4F7F;&#x7528;&#x53EF;&#x9006;&#x52A0;&#x5BC6;&#x6765;&#x5B58;&#x50A8;&#x5BC6;&#x7801;&#x4E00;&#x822C;&#x7981;&#x7528;(&#x9664;&#x975E;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x8981;&#x6C42;&#x8D85;&#x8FC7;&#x4FDD;&#x62A4;&#x5BC6;&#x7801;&#x4FE1;&#x606F;&#x7684;&#x9700;&#x8981;)
  "ClearTextPassword" = @{operator="eq";value=0;msg="&#x6307;&#x793A;&#x662F;&#x5426;&#x4F7F;&#x7528;&#x53EF;&#x9006;&#x52A0;&#x5BC6;&#x6765;&#x5B58;&#x50A8;&#x5BC6;&#x7801; (&#x9664;&#x975E;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x8981;&#x6C42;&#x8D85;&#x8FC7;&#x4FDD;&#x62A4;&#x5BC6;&#x7801;&#x4FE1;&#x606F;&#x7684;&#x9700;&#x8981;)"}
  # + &#x542F;&#x7528;&#x65F6;&#x6B64;&#x8BBE;&#x7F6E;&#x5141;&#x8BB8;&#x533F;&#x540D;&#x7528;&#x6237;&#x67E5;&#x8BE2;&#x672C;&#x5730;LSA&#x7B56;&#x7565;(0&#x5173;&#x95ED;)
  "LSAAnonymousNameLookup" = @{operator="eq";value=0;msg="&#x542F;&#x7528;&#x65F6;&#x6B64;&#x8BBE;&#x7F6E;&#x5141;&#x8BB8;&#x533F;&#x540D;&#x7528;&#x6237;&#x67E5;&#x8BE2;&#x672C;&#x5730;LSA&#x7B56;&#x7565; (0&#x5173;&#x95ED;)"}
  # + &#x68C0;&#x67E5;&#x7ED3;&#x679C;&#x5B58;&#x653E;&#x7684;&#x7A7A;&#x6570;&#x7EC4;
  "CheckResults" = @()
  }
Function F_SysAccountPolicy {
  $Count = $Config.Count
  for ($i=0;$i -lt $Count; $i++){
    $Line = $Config[$i] -split " = "
    if ($SysAccountPolicy.ContainsKey("$($Line[0])")) {
      $Result = F_Tools -Key "SysAccountPolicy::$($Line[0])" -Value $Line[1] -Operator $SysAccountPolicy["$($Line[0])"].Operator -DefaultValue $SysAccountPolicy["$($Line[0])"].Value  -Msg "&#x7CFB;&#x7EDF;&#x8D26;&#x53F7;&#x7B56;&#x7565;&#x914D;&#x7F6E;-$($SysAccountPolicy["$($Line[0])"].Msg)"
      $SysAccountPolicy['CheckResults'] += $Result
    }
    if ( $Line[0] -eq "[Event Audit]" ) { break;}
  }
  return $SysAccountPolicy['CheckResults']
}

#
* &#x7CFB;&#x7EDF;&#x4E8B;&#x4EF6;&#x5BA1;&#x6838;&#x7B56;&#x7565;&#x914D;&#x7F6E;&#x6838;&#x67E5;&#x51FD;&#x6570;  * #
#
- &#x7CFB;&#x7EDF;&#x4E8B;&#x4EF6;&#x5BA1;&#x6838;&#x7B56;&#x7565; - #
$SysEventAuditPolicy  = @{
  # + &#x5BA1;&#x6838;&#x7CFB;&#x7EDF;&#x4E8B;&#x4EF6;(0) [&#x6210;&#x529F;(1)&#x3001;&#x5931;&#x8D25;(2)] (3)
  AuditSystemEvents = @{operator="eq";value=3;msg="&#x5BA1;&#x6838;&#x7CFB;&#x7EDF;&#x4E8B;&#x4EF6;"}
  # + &#x5BA1;&#x6838;&#x767B;&#x5F55;&#x4E8B;&#x4EF6; &#x6210;&#x529F;&#x3001;&#x5931;&#x8D25;
  AuditLogonEvents = @{operator="eq";value=3;msg="&#x5BA1;&#x6838;&#x767B;&#x5F55;&#x4E8B;&#x4EF6;"}
  # + &#x5BA1;&#x6838;&#x5BF9;&#x8C61;&#x8BBF;&#x95EE; &#x6210;&#x529F;&#x3001;&#x5931;&#x8D25;
  AuditObjectAccess = @{operator="eq";value=3;msg="&#x5BA1;&#x6838;&#x5BF9;&#x8C61;&#x8BBF;&#x95EE;"}
  # + &#x5BA1;&#x6838;&#x7279;&#x6743;&#x4F7F;&#x7528; &#x5931;&#x8D25;
  AuditPrivilegeUse = @{operator="ge";value=2;msg="&#x5BA1;&#x6838;&#x7279;&#x6743;&#x4F7F;&#x7528;"}
  # + &#x5BA1;&#x6838;&#x7B56;&#x7565;&#x66F4;&#x6539; &#x6210;&#x529F;&#x3001;&#x5931;&#x8D25;
  AuditPolicyChange = @{operator="eq";value=3;msg="&#x5BA1;&#x6838;&#x7B56;&#x7565;&#x66F4;&#x6539;"}
  # + &#x5BA1;&#x6838;&#x8D26;&#x6237;&#x7BA1;&#x7406; &#x6210;&#x529F;&#x3001;&#x5931;&#x8D25;
  AuditAccountManage = @{operator="eq";value=3;msg="&#x5BA1;&#x6838;&#x8D26;&#x6237;&#x7BA1;&#x7406;"}
  # + &#x5BA1;&#x6838;&#x8FC7;&#x7A0B;&#x8FFD;&#x8E2A; &#x5931;&#x8D25;
  AuditProcessTracking = @{operator="ge";value=2;msg="&#x5BA1;&#x6838;&#x8FC7;&#x7A0B;&#x8FFD;&#x8E2A;"}
  # + &#x5BA1;&#x6838;&#x76EE;&#x5F55;&#x670D;&#x52A1;&#x8BBF;&#x95EE; &#x5931;&#x8D25;
  AuditDSAccess = @{operator="ge";value=2;msg="&#x5BA1;&#x6838;&#x76EE;&#x5F55;&#x670D;&#x52A1;&#x8BBF;&#x95EE;"}
  # + &#x5BA1;&#x6838;&#x8D26;&#x6237;&#x767B;&#x5F55;&#x4E8B;&#x4EF6; &#x6210;&#x529F;&#x3001;&#x5931;&#x8D25;
  AuditAccountLogon = @{operator="eq";value=3;msg="&#x5BA1;&#x6838;&#x8D26;&#x6237;&#x767B;&#x5F55;&#x4E8B;&#x4EF6;"}
  # + &#x68C0;&#x67E5;&#x7ED3;&#x679C;&#x5B58;&#x653E;&#x7684;&#x7A7A;&#x6570;&#x7EC4;
  CheckResults = @()
}
function F_SysEventAuditPolicy {
  $Count = $Config.Count
  for ($i=0;$i -lt $Count; $i++){
    $Line = $Config[$i] -split " = "
    if ( $Line[0] -eq "[Registry Values]" ) { break;}
    if ($SysEventAuditPolicy.ContainsKey("$($Line[0])")) {
      $Result = F_Tools -Key "SysEventAuditPolicy::$($Line[0])" -Value $Line[1] -Operator $SysEventAuditPolicy["$($Line[0])"].Operator -DefaultValue $SysEventAuditPolicy["$($Line[0])"].Value  -Msg "&#x7CFB;&#x7EDF;&#x8D26;&#x53F7;&#x7B56;&#x7565;&#x914D;&#x7F6E;-$($SysEventAuditPolicy["$($Line[0])"].Msg)"
      $SysEventAuditPolicy['CheckResults'] += $Result
    }
  }

  return $SysEventAuditPolicy['CheckResults']
}

#
* &#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#x7528;&#x6237;&#x6743;&#x9650;&#x7BA1;&#x7406;&#x7B56;&#x7565;&#x68C0;&#x67E5;  * #
#
- &#x7EC4;&#x7B56;&#x7565;&#x7528;&#x6237;&#x6743;&#x9650;&#x7BA1;&#x7406;&#x7B56;&#x7565; - #
$SysUserPrivilegePolicy = @{
+ &#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#x672C;&#x5730;&#x5173;&#x673A;&#x7B56;&#x7565;&#x5B89;&#x5168;
SeShutdownPrivilege = @{operator="eq";value='*S-1-5-32-544';msg="&#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#x672C;&#x5730;&#x5173;&#x673A;&#x7B56;&#x7565;"}
+ &#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#x8FDC;&#x7A0B;&#x5173;&#x673A;&#x7B56;&#x7565;&#x5B89;&#x5168;
SeRemoteShutdownPrivilege = @{operator="eq";value='*S-1-5-32-544';msg="&#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#x8FDC;&#x7A0B;&#x5173;&#x673A;&#x7B56;&#x7565;"}
+ &#x53D6;&#x5F97;&#x6587;&#x4EF6;&#x6216;&#x5176;&#x4ED6;&#x5BF9;&#x8C61;&#x7684;&#x6240;&#x6709;&#x6743;&#x9650;&#x7B56;&#x7565;
SeProfileSingleProcessPrivilege = @{operator="eq";value='*S-1-5-32-544';msg="&#x53D6;&#x5F97;&#x6587;&#x4EF6;&#x6216;&#x5176;&#x4ED6;&#x5BF9;&#x8C61;&#x7684;&#x6240;&#x6709;&#x6743;&#x9650;&#x7B56;&#x7565;"}
+ &#x4ECE;&#x7F51;&#x7EDC;&#x8BBF;&#x95EE;&#x6B64;&#x8BA1;&#x7B97;&#x673A;&#x7B56;&#x7565;
SeNetworkLogonRight = @{operator="eq";value='*S-1-5-32-544,*S-1-5-32-545,*S-1-5-32-551';msg="&#x4ECE;&#x7F51;&#x7EDC;&#x8BBF;&#x95EE;&#x6B64;&#x8BA1;&#x7B97;&#x673A;&#x7B56;&#x7565;"}
CheckResults = @()
}

Function F_SysUserPrivilegePolicy {
  # - &#x7B56;&#x7565;&#x7EC4;&#x7528;&#x6237;&#x6743;&#x9650;&#x914D;&#x7F6E;
  $Hash = $SysUserPrivilegePolicy.Clone()  # &#x5DE8;&#x5751;&#x4E4B;&#x5904;
  foreach ( $Name in $Hash.keys) {
    if ( $Name.Equals("CheckResults")){ continue; }
    $Line = ($Config | Select-String $Name.toString()) -split " = "
    $Result = F_Tools -Key "SysUserPrivilegePolicy::$($Line[0])" -Value $Line[1] -Operator $SysUserPrivilegePolicy["$($Line[0])"].Operator -DefaultValue $SysUserPrivilegePolicy["$($Line[0])"].Value  -Msg "&#x7B56;&#x7565;&#x7EC4;&#x7528;&#x6237;&#x6743;&#x9650;&#x914D;&#x7F6E;-$($SysUserPrivilegePolicy["$($Line[0])"].Msg)"
    $SysUserPrivilegePolicy['CheckResults'] += $Result
  }
  return $SysUserPrivilegePolicy['CheckResults']
}

#
* &#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#x7B56;&#x7565;&#x7EC4;&#x5B89;&#x5168;&#x9009;&#x9879;&#x6743;&#x9650;&#x914D;&#x7F6E;&#x68C0;&#x67E5; * #
#
- &#x7EC4;&#x7B56;&#x7565;&#x5B89;&#x5168;&#x9009;&#x9879;&#x7B56;&#x7565; - #
$SysSecurityOptionPolicy = @{
  # - &#x5E10;&#x6237;:&#x4F7F;&#x7528;&#x7A7A;&#x5BC6;&#x7801;&#x7684;&#x672C;&#x5730;&#x5E10;&#x6237;&#x53EA;&#x5141;&#x8BB8;&#x8FDB;&#x884C;&#x63A7;&#x5236;&#x53F0;&#x767B;&#x5F55;(&#x542F;&#x7528;),&#x6CE8;&#x610F;&#x6B64;&#x8BBE;&#x7F6E;&#x4E0D;&#x5F71;&#x54CD;&#x4F7F;&#x7528;&#x57DF;&#x5E10;&#x6237;&#x7684;&#x767B;&#x5F55;&#x3002;(0&#x7981;&#x7528;|1&#x542F;&#x7528;)
  LimitBlankPasswordUse = @{operator="eq";value="MACHINE\System\CurrentControlSet\Control\Lsa\LimitBlankPasswordUse=4,1";msg="&#x5E10;&#x6237;-&#x4F7F;&#x7528;&#x7A7A;&#x5BC6;&#x7801;&#x7684;&#x672C;&#x5730;&#x5E10;&#x6237;&#x53EA;&#x5141;&#x8BB8;&#x8FDB;&#x884C;&#x63A7;&#x5236;&#x53F0;&#x767B;&#x5F55;(&#x542F;&#x7528;)"}

  # - &#x4EA4;&#x4E92;&#x5F0F;&#x767B;&#x5F55;: &#x4E0D;&#x663E;&#x793A;&#x4E0A;&#x6B21;&#x767B;&#x5F55;&#x7528;&#x6237;&#x540D;&#x503C;(&#x542F;&#x7528;)
  DontDisplayLastUserName = @{operator="eq";value="MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\DontDisplayLastUserName=4,1";msg="&#x4EA4;&#x4E92;&#x5F0F;&#x767B;&#x5F55;-&#x4E0D;&#x663E;&#x793A;&#x4E0A;&#x6B21;&#x767B;&#x5F55;&#x7528;&#x6237;&#x540D;&#x503C;(&#x542F;&#x7528;)"}
  # - &#x4EA4;&#x4E92;&#x5F0F;&#x767B;&#x5F55;: &#x767B;&#x5F55;&#x65F6;&#x4E0D;&#x663E;&#x793A;&#x7528;&#x6237;&#x540D;
  DontDisplayUserName = @{operator="eq";value="MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\DontDisplayUserName=4,1";msg="&#x4EA4;&#x4E92;&#x5F0F;&#x767B;&#x5F55;: &#x767B;&#x5F55;&#x65F6;&#x4E0D;&#x663E;&#x793A;&#x7528;&#x6237;&#x540D;"}
  # - &#x4EA4;&#x4E92;&#x5F0F;&#x767B;&#x5F55;: &#x9501;&#x5B9A;&#x4F1A;&#x8BDD;&#x65F6;&#x663E;&#x793A;&#x7528;&#x6237;&#x4FE1;&#x606F;(&#x4E0D;&#x663E;&#x793A;&#x4EFB;&#x4F55;&#x4FE1;&#x606F;)
  DontDisplayLockedUserId = @{operator="eq";value="MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\DontDisplayLockedUserId=4,3";msg="&#x4EA4;&#x4E92;&#x5F0F;&#x767B;&#x5F55;: &#x9501;&#x5B9A;&#x4F1A;&#x8BDD;&#x65F6;&#x663E;&#x793A;&#x7528;&#x6237;&#x4FE1;&#x606F;(&#x4E0D;&#x663E;&#x793A;&#x4EFB;&#x4F55;&#x4FE1;&#x606F;)"}
  # - &#x4EA4;&#x4E92;&#x5F0F;&#x767B;&#x5F55;: &#x65E0;&#x9700;&#x6309; CTRL+ALT+DEL(&#x7981;&#x7528;)
  DisableCAD = @{operator="eq";value="MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\DisableCAD=4,0";msg="&#x4EA4;&#x4E92;&#x5F0F;&#x767B;&#x5F55;-&#x65E0;&#x9700;&#x6309;CTRL+ALT+DEL&#x503C;(&#x7981;&#x7528;)"}
  # - &#x4EA4;&#x4E92;&#x5F0F;&#x767B;&#x5F55;&#xFF1A;&#x8BA1;&#x7B97;&#x673A;&#x4E0D;&#x6D3B;&#x52A8;&#x9650;&#x5236;&#x503C;&#x4E3A;600&#x79D2;&#x6216;&#x66F4;&#x5C11;
  InactivityTimeoutSecs = @{operator="le";value="MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\InactivityTimeoutSecs=4,600";msg="&#x4EA4;&#x4E92;&#x5F0F;&#x767B;&#x5F55;-&#x8BA1;&#x7B97;&#x673A;&#x4E0D;&#x6D3B;&#x52A8;&#x9650;&#x5236;&#x503C;&#x4E3A;600&#x79D2;&#x6216;&#x66F4;&#x5C11;"}
  # - &#x4EA4;&#x4E92;&#x5F0F;&#x767B;&#x5F55;: &#x8BA1;&#x7B97;&#x673A;&#x5E10;&#x6237;&#x9608;&#x503C;&#x6B64;&#x7B56;&#x7565;&#x8BBE;&#x7F6E;&#x786E;&#x5B9A;&#x53EF;&#x5BFC;&#x81F4;&#x8BA1;&#x7B97;&#x673A;&#x91CD;&#x542F;&#x7684;&#x5931;&#x8D25;&#x767B;&#x5F55;&#x5C1D;&#x8BD5;&#x6B21;&#x6570;
  MaxDevicePasswordFailedAttempts = @{operator="le";value="MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\MaxDevicePasswordFailedAttempts=4,10";msg="&#x4EA4;&#x4E92;&#x5F0F;&#x767B;&#x5F55;: &#x6B64;&#x7B56;&#x7565;&#x8BBE;&#x7F6E;&#x786E;&#x5B9A;&#x53EF;&#x5BFC;&#x81F4;&#x8BA1;&#x7B97;&#x673A;&#x91CD;&#x542F;&#x7684;&#x5931;&#x8D25;&#x767B;&#x5F55;&#x5C1D;&#x8BD5;&#x6B21;&#x6570;"}
  # - &#x4EA4;&#x4E92;&#x5F0F;&#x767B;&#x5F55;: &#x8BD5;&#x56FE;&#x767B;&#x5F55;&#x7684;&#x7528;&#x6237;&#x7684;&#x6D88;&#x606F;&#x6807;&#x9898;
  LegalNoticeCaption = @{operator="eq";value='MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\LegalNoticeCaption=1,"&#x5B89;&#x5168;&#x767B;&#x9646;"';msg="&#x4EA4;&#x4E92;&#x5F0F;&#x767B;&#x5F55;: &#x8BD5;&#x56FE;&#x767B;&#x5F55;&#x7684;&#x7528;&#x6237;&#x7684;&#x6D88;&#x606F;&#x6807;&#x9898;"}
  # - &#x4EA4;&#x4E92;&#x5F0F;&#x767B;&#x5F55;: &#x8BD5;&#x56FE;&#x767B;&#x5F55;&#x7684;&#x7528;&#x6237;&#x7684;&#x6D88;&#x606F;&#x6587;&#x672C;
  LegalNoticeText = @{operator="eq";value='MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\LegalNoticeText=7,&#x8BF7;&#x8C28;&#x614E;&#x7684;&#x64CD;&#x4F5C;&#x670D;&#x52A1;&#x5668;&#x4E2D;&#x6570;&#x636E;,&#x60A8;&#x6240;&#x6709;&#x64CD;&#x4F5C;&#x5C06;&#x88AB;&#x8BB0;&#x5F55;&#x5BA1;&#x8BA1;';msg="&#x4EA4;&#x4E92;&#x5F0F;&#x767B;&#x5F55;: &#x8BD5;&#x56FE;&#x767B;&#x5F55;&#x7684;&#x7528;&#x6237;&#x7684;&#x6D88;&#x606F;&#x6587;&#x672C;"}

  # - Microsoft&#x7F51;&#x7EDC;&#x5BA2;&#x6237;&#x7AEF;: &#x5C06;&#x672A;&#x52A0;&#x5BC6;&#x7684;&#x5BC6;&#x7801;&#x53D1;&#x9001;&#x5230;&#x7B2C;&#x4E09;&#x65B9; SMB &#x670D;&#x52A1;&#x5668;(&#x7981;&#x7528;)
  EnablePlainTextPassword = @{operator="eq";value="MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters\EnablePlainTextPassword=4,0";msg="Microsoft&#x7F51;&#x7EDC;&#x5BA2;&#x6237;&#x7AEF;-&#x5C06;&#x672A;&#x52A0;&#x5BC6;&#x7684;&#x5BC6;&#x7801;&#x53D1;&#x9001;&#x5230;&#x7B2C;&#x4E09;&#x65B9; SMB &#x670D;&#x52A1;&#x5668;(&#x7981;&#x7528;)"}
  # - Microsoft&#x7F51;&#x7EDC;&#x670D;&#x52A1;&#x5668;&#xFF1A;&#x6682;&#x505C;&#x4F1A;&#x8BDD;&#x524D;&#x6240;&#x9700;&#x7684;&#x7A7A;&#x95F2;&#x65F6;&#x95F4;&#x6570;&#x91CF;&#x503C;&#x4E3A;15&#x5206;&#x949F;&#x6216;&#x66F4;&#x5C11;&#x4F46;&#x4E0D;&#x4E3A;0
  AutoDisconnect = @{operator="eq";value="MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\AutoDisconnect=4,15";msg="Microsoft&#x7F51;&#x7EDC;&#x670D;&#x52A1;&#x5668;-&#x6682;&#x505C;&#x4F1A;&#x8BDD;&#x524D;&#x6240;&#x9700;&#x7684;&#x7A7A;&#x95F2;&#x65F6;&#x95F4;&#x6570;&#x91CF;&#x503C;&#x4E3A;15&#x5206;&#x949F;"}

  # - &#x7F51;&#x7EDC;&#x5B89;&#x5168;: &#x518D;&#x4E0B;&#x4E00;&#x6B21;&#x6539;&#x53D8;&#x5BC6;&#x7801;&#x65F6;&#x4E0D;&#x5B58;&#x50A8;LAN&#x7BA1;&#x7406;&#x5668;&#x54C8;&#x5E0C;&#x503C;(&#x542F;&#x7528;)
  NoLMHash = @{operator="eq";value="MACHINE\System\CurrentControlSet\Control\Lsa\NoLMHash=4,1";msg="&#x7F51;&#x7EDC;&#x5B89;&#x5168;-&#x5728;&#x4E0B;&#x4E00;&#x6B21;&#x6539;&#x53D8;&#x5BC6;&#x7801;&#x65F6;&#x4E0D;&#x5B58;&#x50A8;LAN&#x7BA1;&#x7406;&#x5668;&#x54C8;&#x5E0C;&#x503C;(&#x542F;&#x7528;)"}

  # - &#x7F51;&#x7EDC;&#x8BBF;&#x95EE;: &#x4E0D;&#x5141;&#x8BB8;SAM&#x8D26;&#x6237;&#x7684;&#x533F;&#x540D;&#x679A;&#x4E3E;&#x503C;&#x4E3A;(&#x542F;&#x7528;)
  RestrictAnonymousSAM = @{operator="eq";value="MACHINE\System\CurrentControlSet\Control\Lsa\RestrictAnonymousSAM=4,1";msg="&#x7F51;&#x7EDC;&#x8BBF;&#x95EE;-&#x4E0D;&#x5141;&#x8BB8;SAM&#x8D26;&#x6237;&#x7684;&#x533F;&#x540D;&#x679A;&#x4E3E;&#x503C;&#x4E3A;(&#x542F;&#x7528;)"}
  # - &#x7F51;&#x7EDC;&#x8BBF;&#x95EE;:&#x4E0D;&#x5141;&#x8BB8;SAM&#x8D26;&#x6237;&#x548C;&#x5171;&#x4EAB;&#x7684;&#x533F;&#x540D;&#x679A;&#x4E3E;&#x503C;&#x4E3A;(&#x542F;&#x7528;)
  RestrictAnonymous = @{operator="eq";value="MACHINE\System\CurrentControlSet\Control\Lsa\RestrictAnonymous=4,1";msg="&#x7F51;&#x7EDC;&#x8BBF;&#x95EE;-&#x4E0D;&#x5141;&#x8BB8;SAM&#x8D26;&#x6237;&#x548C;&#x5171;&#x4EAB;&#x7684;&#x533F;&#x540D;&#x679A;&#x4E3E;&#x503C;&#x4E3A;(&#x542F;&#x7528;)"}

  # - &#x5173;&#x673A;:&#x8BBE;&#x7F6E;&#x786E;&#x5B9A;&#x662F;&#x5426;&#x53EF;&#x4EE5;&#x5728;&#x65E0;&#x9700;&#x767B;&#x5F55; Windows &#x7684;&#x60C5;&#x51B5;&#x4E0B;&#x5173;&#x95ED;&#x8BA1;&#x7B97;&#x673A;(&#x7981;&#x7528;)
  ClearPageFileAtShutdown = @{operator="eq";value="MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management\ClearPageFileAtShutdown=4,0";msg="&#x5173;&#x673A;-&#x8BBE;&#x7F6E;&#x786E;&#x5B9A;&#x662F;&#x5426;&#x53EF;&#x4EE5;&#x5728;&#x65E0;&#x9700;&#x767B;&#x5F55; Windows &#x7684;&#x60C5;&#x51B5;&#x4E0B;&#x5173;&#x95ED;&#x8BA1;&#x7B97;&#x673A;(&#x7981;&#x7528;)"}

  "CheckResults" = @()
}
Function F_SysSecurityOptionPolicy {
  $Hash = $SysSecurityOptionPolicy.Clone()  # &#x5DE8;&#x5751;&#x4E4B;&#x5904;
  foreach ( $Name in $Hash.keys) {
    if ( $Name.Equals("CheckResults")){ continue; }
    $Flag = $Config | Select-String $Name.toString()
    $Value = $SysSecurityOptionPolicy["$($Name)"].Value -split ","
    if ( $Flag ) {
      $Line = $Flag -split ","
      $Result = F_Tools -Key "SysSecurityOptionPolicy::$($Name)" -Value $Line[1] -Operator $SysSecurityOptionPolicy["$($Name)"].Operator -DefaultValue $Value[1] -Msg "&#x7B56;&#x7565;&#x7EC4;&#x5B89;&#x5168;&#x9009;&#x9879;&#x914D;&#x7F6E;-$($SysSecurityOptionPolicy["$($Name)"].Msg)"
      $SysSecurityOptionPolicy['CheckResults'] += $Result
    } else {
      $Result = @{"SysSecurityOptionPolicy::$($Name)"="[&#x5F02;&#x5E38;&#x9879;]|&#x672A;&#x914D;&#x7F6E;|$($Value[1])|&#x7B56;&#x7565;&#x7EC4;&#x5B89;&#x5168;&#x9009;&#x9879;&#x914D;&#x7F6E;-$($SysSecurityOptionPolicy["$($Name)"].Msg)-&#x3010;&#x4E0D;&#x7B26;&#x5408;&#x3011;&#x7B49;&#x7EA7;&#x4FDD;&#x62A4;&#x6807;&#x51C6;."}
      $SysSecurityOptionPolicy['CheckResults'] += $Result
    }
  }
  return $SysSecurityOptionPolicy['CheckResults']
}

#
* &#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#x6CE8;&#x518C;&#x8868;&#x76F8;&#x5173;&#x914D;&#x7F6E;&#x68C0;&#x67E5;&#x51FD;&#x6570;  * #
#
- &#x6CE8;&#x518C;&#x8868;&#x76F8;&#x5173;&#x5B89;&#x5168;&#x7B56;&#x7565;  -
$SysRegistryPolicy = @{
+ &#x5C4F;&#x5E55;&#x81EA;&#x52A8;&#x4FDD;&#x62A4;&#x7A0B;&#x5E8F;
ScreenSaveActive = @{regname="HKEY_CURRENT_USER\Control Panel\Desktop";name="ScreenSaveActive";operator="eq";value=1;msg="&#x7CFB;&#x7EDF;&#x57FA;&#x914D;&#x6838;&#x67E5;-&#x5C4F;&#x5E55;&#x81EA;&#x52A8;&#x4FDD;&#x62A4;&#x7A0B;&#x5E8F;&#x7B56;&#x7565;"}
+ &#x5C4F;&#x5E55;&#x6062;&#x590D;&#x65F6;&#x4F7F;&#x7528;&#x5BC6;&#x7801;&#x4FDD;&#x62A4;
ScreenSaverIsSecure = @{regname="HKEY_CURRENT_USER\Control Panel\Desktop";name="ScreenSaverIsSecure";operator="eq";value=1;msg="&#x7CFB;&#x7EDF;&#x57FA;&#x914D;&#x6838;&#x67E5;-&#x5C4F;&#x5E55;&#x6062;&#x590D;&#x65F6;&#x4F7F;&#x7528;&#x5BC6;&#x7801;&#x4FDD;&#x62A4;&#x7B56;&#x7565;"}
+ &#x5C4F;&#x5E55;&#x4FDD;&#x62A4;&#x7A0B;&#x5E8F;&#x542F;&#x52A8;&#x65F6;&#x95F4;
ScreenSaveTimeOut = @{regname="HKEY_CURRENT_USER\Control Panel\Desktop";name="ScreenSaveTimeOut";operator="le";value=600;msg="&#x7CFB;&#x7EDF;&#x57FA;&#x914D;&#x6838;&#x67E5;-&#x5C4F;&#x5E55;&#x4FDD;&#x62A4;&#x7A0B;&#x5E8F;&#x542F;&#x52A8;&#x65F6;&#x95F4;&#x7B56;&#x7565;"}

+ &#x7981;&#x6B62;&#x5168;&#x90E8;&#x9A71;&#x52A8;&#x5668;&#x81EA;&#x52A8;&#x64AD;&#x653E;
DisableAutoplay  = @{regname="HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer";name="DisableAutoplay";regtype="DWord";operator="eq";value=1;msg="&#x7981;&#x6B62;&#x5168;&#x90E8;&#x9A71;&#x52A8;&#x5668;&#x81EA;&#x52A8;&#x64AD;&#x653E;"}
NoDriveTypeAutoRun = @{regname="HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer";name="NoDriveTypeAutoRun";regtype="DWord";operator="eq";value=255;msg="&#x7981;&#x6B62;&#x5168;&#x90E8;&#x9A71;&#x52A8;&#x5668;&#x81EA;&#x52A8;&#x64AD;&#x653E;"}

- &#x68C0;&#x67E5;&#x5173;&#x95ED;&#x9ED8;&#x8BA4;&#x5171;&#x4EAB;&#x76D8;
restrictanonymous = @{regname="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa";name="restrictanonymous";operator="eq";value=1;msg="&#x7CFB;&#x7EDF;&#x7F51;&#x7EDC;&#x57FA;&#x914D;&#x6838;&#x67E5;-&#x5173;&#x95ED;&#x9ED8;&#x8BA4;&#x5171;&#x4EAB;&#x76D8;&#x7B56;&#x7565;"}
restrictanonymoussam = @{regname="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa";name="restrictanonymoussam";regtype="DWord";operator="eq";value=1;msg="&#x4E0D;&#x5141;&#x8BB8;SAM&#x8D26;&#x6237;&#x7684;&#x533F;&#x540D;&#x679A;&#x4E3E;&#x503C;&#x4E3A;(&#x542F;&#x7528;)"}

- &#x7981;&#x7528;&#x78C1;&#x76D8;&#x5171;&#x4EAB;(SMB)
AutoShareWks = @{regname="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lanmanserver\parameters";name="AutoShareWks";regtype="DWord";operator="eq";value=0;msg="&#x5173;&#x95ED;&#x7981;&#x7528;&#x9ED8;&#x8BA4;&#x5171;&#x4EAB;&#x7B56;&#x7565;-Server2012"}
AutoShareServer = @{regname="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lanmanserver\parameters";name="AutoShareServer";regtype="DWord";operator="eq";value=0;msg="&#x5173;&#x95ED;&#x7981;&#x7528;&#x9ED8;&#x8BA4;&#x5171;&#x4EAB;&#x7B56;&#x7565;-Server2012"}

- &#x7CFB;&#x7EDF;&#x3001;&#x5E94;&#x7528;&#x3001;&#x5B89;&#x5168;&#x3001;PS&#x65E5;&#x5FD7;&#x67E5;&#x770B;&#x5668;&#x5927;&#x5C0F;&#x8BBE;&#x7F6E;(&#x6B64;&#x5904;&#x8BBE;&#x7F6E;&#x9ED8;&#x8BA4;&#x7684;&#x4E24;&#x500D;&#x914D;&#x7F6E;-&#x5EFA;&#x8BAE;&#x4E00;&#x5B9A;&#x901A;&#x8FC7;&#x65E5;&#x5FD7;&#x91C7;&#x96C6;&#x5E73;&#x53F0;&#x91C7;&#x96C6;&#x7CFB;&#x7EDF;&#x65E5;&#x5FD7;&#x6BD4;&#x5982;ELK)
EventlogSystemMaxSize = @{regname="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\System";name="MaxSize";operator="ge";value=41943040;msg="&#x7CFB;&#x7EDF;&#x57FA;&#x65E5;&#x5FD7;&#x914D;&#x6838;&#x67E5;-&#x7CFB;&#x7EDF;&#x65E5;&#x5FD7;&#x67E5;&#x770B;&#x5668;&#x5927;&#x5C0F;&#x8BBE;&#x7F6E;&#x7B56;&#x7565;"}
EventlogApplicationMaxSize = @{regname="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application";name="MaxSize";operator="ge";value=41943040;msg="&#x7CFB;&#x7EDF;&#x65E5;&#x5FD7;&#x57FA;&#x914D;&#x6838;&#x67E5;-&#x5E94;&#x7528;&#x65E5;&#x5FD7;&#x67E5;&#x770B;&#x5668;&#x5927;&#x5C0F;&#x8BBE;&#x7F6E;&#x7B56;&#x7565;"}
EventlogSecurityMaxSize = @{regname="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security";name="MaxSize";operator="ge";value=41943040;msg="&#x7CFB;&#x7EDF;&#x65E5;&#x5FD7;&#x57FA;&#x914D;&#x6838;&#x67E5;-&#x5B89;&#x5168;&#x65E5;&#x5FD7;&#x67E5;&#x770B;&#x5668;&#x5927;&#x5C0F;&#x8BBE;&#x7F6E;&#x7B56;&#x7565;"}
EventlogPSMaxSize = @{regname="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Windows PowerShell";name="MaxSize";operator="ge";value=31457280;msg="&#x7CFB;&#x7EDF;&#x65E5;&#x5FD7;&#x57FA;&#x914D;&#x6838;&#x67E5;-PS&#x65E5;&#x5FD7;&#x67E5;&#x770B;&#x5668;&#x5927;&#x5C0F;&#x8BBE;&#x7F6E;&#x7B56;&#x7565;"}

- &#x9632;&#x706B;&#x5899;&#x76F8;&#x5173;&#x64CD;&#x4F5C;&#x8BBE;&#x7F6E;&#xFF08;&#x5F00;&#x542F;&#x3001;&#x534F;&#x8BAE;&#x3001;&#x670D;&#x52A1;&#xFF09;
DomainEnableFirewall  = @{regname='HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile';name='EnableFirewall';regtype="DWord";operator="eq";value=1;msg="&#x5F00;&#x542F;&#x57DF;&#x7F51;&#x7EDC;&#x9632;&#x706B;&#x5899;"}
StandardEnableFirewall = @{regname='HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile';name='EnableFirewall';regtype="DWord";operator="eq";value=1;msg="&#x5F00;&#x542F;&#x4E13;&#x7528;&#x7F51;&#x7EDC;&#x9632;&#x706B;&#x5899;"}
PPEnableFirewall = @{regname='HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile';name='EnableFirewall';regtype="DWord";operator="eq";value=1;msg="&#x5F00;&#x542F;&#x516C;&#x7528;&#x7F51;&#x7EDC;&#x9632;&#x706B;&#x5899;"}

- &#x7ED3;&#x679C;&#x5B58;&#x50A8;
CheckResults=@()
}
Function F_SysRegistryPolicy {
  $Registry=  $SysRegistryPolicy.Clone()
  foreach ( $item in $Registry.keys) {
    if ( $item -eq "CheckResults" ){ continue;}
    $Result = F_GetRegPropertyValue -Key $SysRegistryPolicy.$item.regname -Name $SysRegistryPolicy.$item.name -Operator $SysRegistryPolicy.$item.operator -DefaultValue $SysRegistryPolicy.$item.value -Msg $SysRegistryPolicy.$item.msg
    $SysRegistryPolicy['CheckResults'] += $Result
  }
  return $SysRegistryPolicy['CheckResults']
}

#
* &#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#x670D;&#x52A1;&#x53CA;&#x8FD0;&#x884C;&#x7A0B;&#x5E8F;&#x68C0;&#x67E5;&#x51FD;&#x6570;  * #
#
$SysProcessServicePolicy = @{"CheckResults"=@()}
function F_SysProcessServicePolicy {
  # + &#x68C0;&#x6D4B;&#x7CFB;&#x7EDF;&#x53CA;&#x7528;&#x6237;&#x5F00;&#x673A;&#x542F;&#x52A8;&#x9879;
  $SysAutoStart = Get-Item -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run'
  $SysAutoStart.GetValueNames() | % {
    $res += "$($_)#$($SysAutoStart.GetValue($_)) "
  }
  $Result = @{"SysProcessServicePolicy::SysAutoStart"=$res}
  $SysProcessServicePolicy['CheckResults'] += $Result

  $UserAutoStart = Get-Item -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run'
  $UserAutoStart.GetValueNames() | % {
    $res += "$($_)#$($SysAutoStart.GetValue($_)) "
  }
  $Result = @{"SysProcessServicePolicy::UserAutoStart"=$res}
  $SysProcessServicePolicy['CheckResults'] += $Result

  # + &#x5426;&#x542F;&#x7528;&#x8FDC;&#x7A0B;&#x684C;&#x9762;&#x670D;&#x52A1;
  $RDPStatus = (Get-Service -Name "TermService").Status
  # if ($RDP -eq "0" -and $RDPStatus -eq "Running" ) {
  #   $Result = @{"SysProcessServicePolicy::RDPStatus"="&#x5F53;&#x524D;&#x7CFB;&#x7EDF;&#x3010;&#x5DF2;&#x542F;&#x7528;&#x3011;&#x8FDC;&#x7A0B;&#x684C;&#x9762;&#x670D;&#x52A1;."}
  # } else {
  #   $Result = @{"SysProcessServicePolicy::RDPStatus"="&#x5F53;&#x524D;&#x7CFB;&#x7EDF;&#x3010;&#x672A;&#x542F;&#x7528;&#x3011;&#x8FDC;&#x7A0B;&#x684C;&#x9762;&#x670D;&#x52A1;."}
  # }
  if ($RDPStatus -eq "Running" ) {
    $Result = F_GetRegPropertyValue -Key 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Terminal Server' -Name 'fDenyTSConnections' -Operator "eq" -DefaultValue 0 -Msg "&#x662F;&#x5426;&#x5C06;&#x8FDC;&#x7A0B;&#x684C;&#x9762;&#x670D;&#x52A1;&#x7981;&#x7528;"
  } else {
    $Result = @{"SysProcessServicePolicy::RDPStatus"="&#x5F53;&#x524D;&#x7CFB;&#x7EDF;&#x3010;&#x672A;&#x542F;&#x7528;&#x3011;&#x8FDC;&#x7A0B;&#x684C;&#x9762;&#x670D;&#x52A1;."}
  }
  $SysProcessServicePolicy['CheckResults'] += $Result
  # - &#x5426;&#x542F;&#x7528;NTP&#x670D;&#x52A1;&#x6765;&#x540C;&#x6B65;&#x65F6;&#x949F;
  # $NTP = F_GetReg -Key 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer' -Name 'Enabled'
  # if ( $NTP -eq "1") {
  #   $Result = @{"SysProcessServicePolicy::NtpServerEnabled"="[&#x5408;&#x683C;&#x9879;]|$NTP|1|&#x7CFB;&#x7EDF;&#x57FA;&#x7840;&#x914D;&#x7F6E;&#x6838;&#x67E5;-&#x542F;&#x7528;NTP&#x670D;&#x52A1;&#x540C;&#x6B65;&#x65F6;&#x949F;&#x7B56;&#x7565;-&#x3010;&#x7B26;&#x5408;&#x3011;&#x7B49;&#x7EA7;&#x4FDD;&#x62A4;&#x6807;&#x51C6;."}
  # } else {
  #   $Result = @{"SysProcessServicePolicy::NtpServerEnabled"="[&#x5F02;&#x5E38;&#x9879;]|$NTP|1|&#x7CFB;&#x7EDF;&#x57FA;&#x7840;&#x914D;&#x7F6E;&#x6838;&#x67E5;-&#x542F;&#x7528;NTP&#x670D;&#x52A1;&#x540C;&#x6B65;&#x65F6;&#x949F;&#x7B56;&#x7565;-&#x3010;&#x4E0D;&#x7B26;&#x5408;&#x3011;&#x7B49;&#x7EA7;&#x4FDD;&#x62A4;&#x6807;&#x51C6;."}
  # }
  $Result = F_GetRegPropertyValue -Key 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer' -Name 'Enabled' -Operator "eq" -DefaultValue 1 -Msg "&#x662F;&#x5426;&#x542F;&#x7528;NTP&#x670D;&#x52A1;&#x540C;&#x6B65;&#x65F6;&#x949F;&#x7B56;&#x7565;"
  $SysProcessServicePolicy['CheckResults'] += $Result

  # - &#x662F;&#x5426;&#x4FEE;&#x6539;&#x9ED8;&#x8BA4;&#x7684;&#x8FDC;&#x7A0B;&#x684C;&#x9762;&#x7AEF;&#x53E3;
  $RDP1 = Get-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp\' | % {$_.GetValue("PortNumber")}
  $RDP2 = Get-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\Wds\rdpwd\Tds\tcp\' | % {$_.GetValue("PortNumber")}
  if ( $RDP1 -eq $RDP2 -and $RDP2 -ne "3389") {
    $Result = @{"SysProcessServicePolicy::RDPPort"="[&#x5408;&#x683C;&#x9879;]|$RDP1|&#x9664;3389&#x4EE5;&#x5916;&#x7684;&#x7AEF;&#x53E3;|&#x7CFB;&#x7EDF;&#x57FA;&#x7840;&#x914D;&#x7F6E;&#x6838;&#x67E5;-&#x9ED8;&#x8BA4;&#x7684;&#x8FDC;&#x7A0B;&#x684C;&#x9762;&#x7AEF;&#x53E3;&#x5DF2;&#x4FEE;&#x6539;-&#x3010;&#x7B26;&#x5408;&#x3011;&#x7B49;&#x7EA7;&#x4FDD;&#x62A4;&#x6807;&#x51C6;."}
  } else {
    $Result = @{"SysProcessServicePolicy::RDPPort"="[&#x5F02;&#x5E38;&#x9879;]|$RDP1|&#x9664;3389&#x4EE5;&#x5916;&#x7684;&#x7AEF;&#x53E3;|&#x7CFB;&#x7EDF;&#x57FA;&#x7840;&#x914D;&#x7F6E;&#x6838;&#x67E5;-&#x9ED8;&#x8BA4;&#x7684;&#x8FDC;&#x7A0B;&#x684C;&#x9762;&#x7AEF;&#x53E3;&#x672A;&#x4FEE;&#x6539;-&#x3010;&#x4E0D;&#x7B26;&#x5408;&#x3011;&#x7B49;&#x7EA7;&#x4FDD;&#x62A4;&#x6807;&#x51C6;."}
  }
  $SysProcessServicePolicy['CheckResults'] += $Result
}

#
* &#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#x5B89;&#x5168;&#x68C0;&#x6D4B;&#x51FD;&#x6570; *
#
* &#x5FAE;&#x8F6F;Windows&#x670D;&#x52A1;&#x5668;&#x5B89;&#x5168;&#x8865;&#x4E01;&#x5217;&#x8868;&#x4FE1;&#x606F; * #
$Msrc_api = "https://api.msrc.microsoft.com/sug/v2.0/zh-CN/affectedProduct?%24orderBy=releaseDate+desc&%24filter=productFamilyId+in+%28%27100000010%27%29+and+severityId+in+%28%27100000000%27%2C%27100000001%27%29+and+%28releaseDate+gt+2020-01-14T00%3A00%3A00%2B08%3A00%29+and+%28releaseDate+lt+2021-05-22T23%3A59%3A59%2B08%3A00%29"
$SysWSUSList = @{}
$SysWSUSListId = @()
$AvailableWSUSList = @{}
function F_SysSecurityPolicy {

  # - &#x7CFB;&#x7EDF;&#x8865;&#x4E01;&#x9A8C;&#x8BC1;
  if ( $MsrcUpdate -or ! (Test-Path -Path .\WSUSList.json) ) {
    $MSRC_JSON = F_UrlRequest -Msrc_api $Msrc_api
    $MSRC_JSON.value | % {
      $id = $_.id;
      $product = $_.product;
      $articleName = $_.kbArticles.articleName | Get-Unique;
      $fixedBuildNumber = $_.kbArticles.fixedBuildNumber | Get-Unique;
      $severity = $_.severity;
      $impact = $_.impact;
      $baseScore = $_.baseScore;
      $cveNumber = $_.cveNumber | Get-Unique;
      $releaseDate = $_.releaseDate
      $SysWSUSList += @{"$($id)"=@{"product"=$product;"articleName"=$articleName;"fixedBuildNumber"=$fixedBuildNumber;"severity"=$severity;"impact"=$impact;"baseScore"=$baseScore;"cveNumber"=$cveNumber;"releaseDate"=$releaseDate}}
    }
    while ($MSRC_JSON.'@odata.nextLink'.length) {
      $MSRC_JSON = F_UrlRequest -Msrc_api $MSRC_JSON.'@odata.nextLink'
      $MSRC_JSON.value | % {
        $id = $_.id;
        $product = $_.product;
        $articleName = $_.kbArticles.articleName | Get-Unique;
        $fixedBuildNumber = $_.kbArticles.fixedBuildNumber | Get-Unique;
        $severity = $_.severity;
        $impact = $_.impact;
        $baseScore = $_.baseScore;
        $cveNumber = $_.cveNumber | Get-Unique;
        $releaseDate = $_.releaseDate
        $SysWSUSList += @{"$($id)"=@{"product"=$product;"articleName"=$articleName;"fixedBuildNumber"=$fixedBuildNumber;"severity"=$severity;"impact"=$impact;"baseScore"=$baseScore;"cveNumber"=$cveNumber;"releaseDate"=$releaseDate }}
      }
    }
    Write-Host "[-] &#x5DF2;&#x4ECE; Microsoft &#x5B89;&#x5168;&#x54CD;&#x5E94;&#x4E2D;&#x5FC3;&#x83B7;&#x53D6;&#x66F4;&#x65B0; $($MSRC_JSON.'@odata.count') &#x6761;&#x8865;&#x4E01;&#x4FE1;&#x606F;!" -ForegroundColor Green
    Write-Host "[-] &#x6B63;&#x5728;&#x5C06;&#x83B7;&#x53D6;&#x7684;&#x66F4;&#x65B0; $($MSRC_JSON.'@odata.count') &#x6761;&#x8865;&#x4E01;&#x4FE1;&#x606F;&#x5199;&#x5165;&#x5230;&#x672C;&#x5730; WSUSList.json &#x6587;&#x4EF6;&#x4E4B;&#x4E2D;!" -ForegroundColor Green
    $SysWSUSList | ConvertTo-Json | Out-File WSUSList.json -Encoding utf8
    $SysWSUSListId = $SysWSUSList.keys
    $SysWSUSList.keys | ConvertTo-Json | Out-File WSUSListId.json -Encoding utf8
  } else {
    # &#x4ECE;&#x672C;&#x5730;&#x8BFB;&#x53D6;JSON&#x6587;&#x4EF6;&#x5B58;&#x50A8;&#x7684;&#x8865;&#x4E01;&#x4FE1;&#x606F;&#x3002;
    if (Test-Path -Path .\WSUSList.json) {
      $SysWSUSList = Get-Content -Raw -Encoding UTF8 .\WSUSList.json | ConvertFrom-Json
      $SysWSUSListId  = Get-Content -Raw -Encoding UTF8 .\WSUSListId.json | ConvertFrom-Json
      Write-Host "[-] &#x5DF2;&#x4ECE;&#x672C;&#x5730; WSUSList.json &#x6587;&#x4EF6;&#x83B7;&#x5F97; $($SysWSUSListId.count) &#x6761;&#x8865;&#x4E01;&#x4FE1;&#x606F;!" -ForegroundColor Green
    } else {
      Write-Host "[-] &#x672C;&#x5730;&#x672A;&#x80FD;&#x627E;&#x5230;&#x5B58;&#x653E;&#x8865;&#x4E01;&#x4FE1;&#x606F;&#x7684; WSUSList.json &#x6587;&#x4EF6;! &#x8BF7;&#x91C7;&#x7528; -Update True &#x6807;&#x8BB0;&#x4ECE;Microsoft &#x5B89;&#x5168;&#x54CD;&#x5E94;&#x4E2D;&#x5FC3;&#x83B7;&#x53D6;&#x66F4;&#x65B0;" -ForegroundColor Red
      break
      exit
    }
  }

  # &#x83B7;&#x53D6;&#x5F53;&#x524D;&#x7CFB;&#x7EDF;&#x7248;&#x672C;&#x53EF;&#x7528;&#x7684;&#x8865;&#x4E01;&#x5217;&#x8868;
  $AvailableWSUSListId = @()
  if ($SysInfo.ProductType -eq "Client") {
    Write-Host "[-] Desktop Client" -ForegroundColor Gray
    foreach ($KeyName in $SysWSUSListId) {
      if(($SysWSUSList."$KeyName".product -match $SysInfo.ProductName) -and ($SysWSUSList."$KeyName".product -match $SysInfo.WindowsVersion) -and ($SysWSUSList."$KeyName".product -match ($SysInfo.CsSystemType -split " ")[0])) {
        if (($SysWSUSList."$KeyName".fixedBuildNumber -match $SysInfo.OsVersion) -or ($SysWSUSList."$KeyName".fixedBuildNumber.length -eq 0 )) {
          $AvailableWSUSList."$KeyName" = $SysWSUSList."$KeyName"
          $AvailableWSUSListId += "$KeyName"
        }
      }
    }
  } else {
    Write-Host "[-] Windows Server" -ForegroundColor Gray
    foreach ($KeyName in $SysWSUSListId) {
      if(($SysWSUSList."$KeyName".product -match $SysInfo.ProductName) -and ($SysWSUSList."$KeyName".product -match $SysInfo.ProductName)) {
        $AvailableWSUSList."$KeyName" = $SysWSUSList."$KeyName"
        $AvailableWSUSListId += "$KeyName"
      }
    }
  }
  Write-Host $SysInfo.ProductName $SysInfo.WindowsVersion ($SysInfo.CsSystemType -split " ")[0] $SysInfo.OsVersion
  Write-Host "[-] &#x5DF2;&#x4ECE;&#x68B3;&#x7406;&#x51FA;&#x9002;&#x7528;&#x4E8E;&#x5F53;&#x524D; $($SysInfo.ProductType) &#x7CFB;&#x7EDF;&#x7248;&#x672C;&#x7684; $($AvailableWSUSList.count) &#x6761;&#x8865;&#x4E01;&#x4FE1;&#x606F;!n" -ForegroundColor Green

  # 已安装的补丁
  $InstallWSUSList = @{}
  $msg = @()
  foreach ($id in $AvailableWSUSListId) {
    if( $SysInfo.'Hotfix(s)' -match $AvailableWSUSList."$id".articleName ) {
      $InstallWSUSList."$id" = $SysWSUSList."$id"
      $msg += "[+]" + $SysWSUSList."$id".product + $SysWSUSList."$id".fixedBuildNumber + " " +  $SysWSUSList."$id".articleName + "(" + $SysWSUSList."$id".cveNumber   + ")" + $SysWSUSList."$id".severity  + $SysWSUSList."$id".baseScore + ""
    }
  }
  Write-Host "[-] $($SysInfo.'Hotfix(s)') &#xFF0C;&#x5171; $($AvailableWSUSList.count) &#x6761;&#x6F0F;&#x6D1E;&#x8865;&#x4E01;&#x4FE1;&#x606F;!n$($msg)" -ForegroundColor Green

  # 未安装的补丁
  $NotInstallWSUSList = @{}
  $msg = @()
  foreach ($id in $AvailableWSUSListId) {
    if(-not($InstallWSUSList."$id")) {
     $NotInstallWSUSList."$id" = $SysWSUSList."$id"
     $msg += "[+]" + $SysWSUSList."$id".product + $SysWSUSList."$id".fixedBuildNumber + " " + $SysWSUSList."$id".articleName + "(" + $SysWSUSList."$id".cveNumber + ")" + $SysWSUSList."$id".severity + $SysWSUSList."$id".baseScore + ""
    }
  }
  Write-Host "[-] &#x672A;&#x5B89;&#x88C5; $($NotInstallWSUSList.count) &#x6761;&#x6F0F;&#x6D1E;&#x8865;&#x4E01;&#x4FE1;&#x606F;&#xFF0C;&#x5171; $($AvailableWSUSList.count) &#x6761;&#x6F0F;&#x6D1E;&#x8865;&#x4E01;&#x4FE1;&#x606F;!n$($msg)" -ForegroundColor red
}

#
* 杂类检测函数 *
#
$OtherCheck = @{}
function F_OtherCheckPolicy {
  # - 当前系统已安装的软件
  $Product = Get-WmiObject -Class Win32_Product | Select-Object -Property Name,Version,IdentifyingNumber | Sort-Object Name | Out-String
  $OtherCheck += @{"Product"="$($Product)"}

  # - 当前系统最近访问文件或者目录
  $Recent = (Get-ChildItem ~\AppData\Roaming\Microsoft\Windows\Recent).Name
  $OtherCheck += @{"Recent"="$($Recent)"}
  return $OtherCheck
}

function Main() {
<# .synopsis main 函数程序执行入口 .description 调用上述编写的相关检测脚本 .example #>

$ScanStartTime = Get-date -Format 'yyyy-M-d H:m:s'
F_Logging -Level Info -Msg "#################################################################################"
F_Logging -Level Info -Msg "- @Desc: Windows Server 安全配置策略基线检测脚本  [将会在Github上持续更新-star]"
F_Logging -Level Info -Msg "- @Author: WeiyiGeek"
F_Logging -Level Info -Msg "- @Blog: https://www.weiyigeek.top"
F_Logging -Level Info -Msg "- @Github: https://github.com/WeiyiGeek/SecOpsDev/tree/master/OS-操作系统/Windows"
F_Logging -Level Info -Msg "#################################################################################"

F_Logging -Level Info -Msg "[*] Windows Server &#x5B89;&#x5168;&#x914D;&#x7F6E;&#x7B56;&#x7565;&#x57FA;&#x7EBF;&#x68C0;&#x6D4B;&#x811A;&#x672C;&#x5DF2;&#x542F;&#x52A8;."
F_Logging -Level Info -Msg "[*] &#x811A;&#x672C;&#x6267;&#x884C;: $($Executor), &#x662F;&#x5426;&#x5728;&#x7EBF;&#x62C9;&#x53D6;&#x5FAE;&#x8F6F;&#x5B89;&#x5168;&#x4E2D;&#x5FC3;&#x7684;&#x670D;&#x52A1;&#x5668;&#x5B89;&#x5168;&#x8865;&#x4E01;&#x5217;&#x8868;&#x4FE1;&#x606F;: $($MsrcUpdate)n"
1.判断当前运行的powershell终端是否管理员执行
F_Logging -Level Info -Msg "[-] 正在检测当前运行的PowerShell终端是否管理员权限..."
$flag = F_IsCurrentUserAdmin
if (!($flag)) {
  F_Logging -Level Error -Msg "[*] &#x811A;&#x672C;&#x6267;&#x884C;&#x53D1;&#x751F;&#x9519;&#x8BEF;,&#x8BF7;&#x4F7F;&#x7528;&#x7BA1;&#x7406;&#x5458;&#x6743;&#x9650;&#x8FD0;&#x884C;&#x8BE5;&#x811A;&#x672C;..&#x4F8B;&#x5982;: Start-Process powershell -Verb runAs...."
  F_Logging -Level Warning -Msg "[*] &#x6B63;&#x5728;&#x9000;&#x51FA;&#x6267;&#x884C;&#x8BE5;&#x811A;&#x672C;......"
  return
}
F_Logging -Level Info -Msg "[*] PowerShell &#x7BA1;&#x7406;&#x5458;&#x6743;&#x9650;&#x68C0;&#x67E5;&#x901A;&#x8FC7;...n"

2.当前系统策略配置文件导出 (注意必须系统管理员权限运行)
F_Logging -Level Info -Msg "[-] 正在导出当前系统策略配置文件 config.cfg......"
secedit /export /cfg config.cfg /quiet
start-sleep 3
if ( -not(Test-Path -Path config.cfg)) {
  F_Logging -Level Error -Msg "[*] &#x5F53;&#x524D;&#x7CFB;&#x7EDF;&#x7B56;&#x7565;&#x914D;&#x7F6E;&#x6587;&#x4EF6; config.cfg &#x4E0D;&#x5B58;&#x5728;,&#x8BF7;&#x68C0;&#x67E5;......n"
  F_Logging -Level Warning -Msg "[*] 正在退出执行该脚本......"
  return
} else {
  Copy-Item -Path config.cfg -Destination config.cfg.bak -Force
}
$Config = Get-Content -path config.cfg

3.系统相关信息以及系统安全组策略检测
F_Logging -Level Info -Msg "[-] 当前系统信息一览"
$SysInfo = F_SysInfo
$SysInfo

F_Logging -Level Info -Msg "[-] 当前系统网络信息一览"
$SysNetAdapter = F_SysNetAdapter
$SysNetAdapter

F_Logging -Level Info -Msg "[-] 当前系统磁盘信息一览"
$SysDisk = F_SysDisk
$SysDisk

F_Logging -Level Info -Msg "[-] 当前系统账户信息一览"
$SysAccount = F_SysAccount
$SysAccount

F_Logging -Level Info -Msg "[-] 当前系统安全策略信息一览"
$SysAccountPolicy.CheckResults = F_SysAccountPolicy
$SysEventAuditPolicy.CheckResults = F_SysEventAuditPolicy
$SysUserPrivilegePolicy.CheckResults = F_SysUserPrivilegePolicy
$SysSecurityOptionPolicy.CheckResults = F_SysSecurityOptionPolicy
$SysRegistryPolicy.CheckResults = F_SysRegistryPolicy
$SysProcessServicePolicy.CheckResults = F_SysProcessServicePolicy

F_Logging -Level Info -Msg "[-] 当前系统杂类信息一览"
$OtherCheck = F_OtherCheckPolicy
$OtherCheck.Values

F_Logging -Level Info -Msg "[-] 当前系统安全补丁情况信息一览"
F_SysSecurityPolicy

4.程序执行完毕
$ScanEndTime = Get-date -Format 'yyyy-M-d H:m:s'
F_Logging -Level Info -Msg "- Windows Server 安全配置策略基线检测脚本已执行完毕......&#x5F00;&#x59CB;&#x65F6;&#x95F4;&#xFF1A;${ScanStartTime}n完成时间: ${ScanEndTime}"
}
Main
</#></#></#></#></#>
</code></pre>
<p>0x02 WindowServer2019 安全加固</p>
<p>Windows Server 安全配置策略基线加固脚本: WindowsSecurityReinforce.ps1</p>
<pre><code>## ----------------------------------------- ##
@Author: WeiyiGeek
@Description:  Windows Server 安全配置策略基线加固脚本
@Create Time:  2019年5月6日 11:04:42
@Last Modified time: 2021-11-15 11:06:31
@E-mail: master@weiyigeek.top
@Blog: https://www.weiyigeek.top
@wechat: WeiyiGeeker
@Github: https://github.com/WeiyiGeek/SecOpsDev/tree/master/OS-操作系统/Windows/
@Version: 1.8
@Runtime: Server 2019 / Windows 10
## ----------------------------------------- ##
脚本主要功能说明:
(1) Windows 系统安全策略相关基础配置
(2) Windows 默认共享关闭、屏保、超时时间以及WSUS补丁更新。
(3) Windows 等保主机测评项安全加固配置
## ----------------------------------------- ##

* 文件输出默认为UTF-8格式
$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'

<# .synopsis windows server 安全配置策略基线加固脚本 (脚本将会在github上持续更新) .description 操作系统配置策略 (符合等保3级的关键检查项) - 系统账号策略 系统事件审核策略 系统组策略安全选项策略 注册表相关安全策略 防火墙服务相关安全策略 针对于系统暂无办法通过注册表以及组策略配置的安全加固项 .example windowssecurityreinforce.ps1 .notes 注意:不同的版本操作系统以下某些关键项可能会不存在会有一些警告(需要大家提交issue,共同完成)。 #>

- 系统账号策略 - #
$SysAccountPolicy = @{
  # + 密码最短留存期
  "MinimumPasswordAge" = @{operator="eq";value=1;msg="密码最短留存期"}
  # + 密码最长留存期
  "MaximumPasswordAge" = @{operator="eq";value=90;msg="密码最长留存期"}
  # + 密码长度最小值
  "MinimumPasswordLength" = @{operator="ge";value=14;msg="密码长度最小值"}
  # + 密码必须符合复杂性要求
  "PasswordComplexity" = @{operator="eq";value=1;msg="开启密码符合复杂性要求策略"}
  # + 强制密码历史 N个记住的密码
  "PasswordHistorySize" = @{operator="ge";value=3;msg="强制密码历史N个记住的密码"}
  # + 账户登录失败锁定阈值N次数
  "LockoutBadCount" = @{operator="eq";value=6;msg="账户登录失败锁定阈值次数"}
  # + 账户锁定时间(分钟)
  "ResetLockoutCount" = @{operator="ge";value=15;msg="账户锁定时间(分钟)"}
  # + 复位账户锁定计数器时间(分钟)
  "LockoutDuration" = @{operator="ge";value=15;msg="复位账户锁定计数器时间(分钟)"}
  # + 下次登录必须更改密码
  "RequireLogonToChangePassword" = @{operator="eq";value=0;msg="下次登录必须更改密码"}
  # + 强制过期
  "ForceLogoffWhenHourExpire" = @{operator="eq";value=1;msg="强制过期"}
  # + 当前管理账号登陆名称
  "NewAdministratorName" = @{operator="ne";value='"Admin"';msg="更改当前系统管理账号登陆名称为Admin策略"}
  # + 当前来宾用户登陆名称
  "NewGuestName" = @{operator="ne";value='"Guester"';msg="更改当前系统来宾用户登陆名称为Guester策略"}
  # + 管理员是否被启用
  "EnableAdminAccount" = @{operator="eq";value=1;msg="管理员账户停用与启用策略"}
  # + 来宾用户是否启用
  "EnableGuestAccount" = @{operator="eq";value=0;msg="来宾账户停用与启用策略"}
  # + 指示是否使用可逆加密来存储密码一般禁用(除非应用程序要求超过保护密码信息的需要)
  "ClearTextPassword" = @{operator="eq";value=0;msg="指示是否使用可逆加密来存储密码 (除非应用程序要求超过保护密码信息的需要)"}
  # + 启用时此设置允许匿名用户查询本地LSA策略(0关闭)
  "LSAAnonymousNameLookup" = @{operator="eq";value=0;msg="启用时此设置允许匿名用户查询本地LSA策略 (0关闭)"}
}

- 系统事件审核策略 - #
$SysEventAuditPolicy  = @{
  # + 审核系统事件(0) [成功(1)、失败(2)] (3)
  AuditSystemEvents = @{operator="eq";value=3;msg="审核系统事件"}
  # + 审核登录事件 成功、失败
  AuditLogonEvents = @{operator="eq";value=3;msg="审核登录事件"}
  # + 审核对象访问 成功、失败
  AuditObjectAccess = @{operator="eq";value=3;msg="审核对象访问"}
  # + 审核特权使用 失败
  AuditPrivilegeUse = @{operator="ge";value=2;msg="审核特权使用"}
  # + 审核策略更改 成功、失败
  AuditPolicyChange = @{operator="eq";value=3;msg="审核策略更改"}
  # + 审核账户管理 成功、失败
  AuditAccountManage = @{operator="eq";value=3;msg="审核账户管理"}
  # + 审核过程追踪 失败
  AuditProcessTracking = @{operator="ge";value=2;msg="审核过程追踪"}
  # + 审核目录服务访问 失败
  AuditDSAccess = @{operator="ge";value=2;msg="审核目录服务访问"}
  # + 审核账户登录事件 成功、失败
  AuditAccountLogon = @{operator="eq";value=3;msg="审核账户登录事件"}
}

- 系统组策略安全选项策略 - #
$SysSecurityOptionPolicy = @{
  # - 帐户:使用空密码的本地帐户只允许进行控制台登录(启用),注意此设置不影响使用域帐户的登录。(0禁用|1启用)
  LimitBlankPasswordUse = @{operator="eq";value="MACHINE\System\CurrentControlSet\Control\Lsa\LimitBlankPasswordUse=4,1";msg="帐户-使用空密码的本地帐户只允许进行控制台登录(启用)"}
  # - 交互式登录: 不显示上次登录用户名值(启用)
  DontDisplayLastUserName = @{operator="eq";value="MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\DontDisplayLastUserName=4,1";msg="交互式登录-不显示上次登录用户名值(启用)"}
  # - 交互式登录: 登录时不显示用户名
  DontDisplayUserName = @{operator="eq";value="MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\DontDisplayUserName=4,1";msg="交互式登录: 登录时不显示用户名"}
  # - 交互式登录: 锁定会话时显示用户信息(不显示任何信息)
  DontDisplayLockedUserId = @{operator="eq";value="MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\DontDisplayLockedUserId=4,3";msg="交互式登录: 锁定会话时显示用户信息(不显示任何信息)"}
  # - 交互式登录: 无需按 CTRL+ALT+DEL(禁用)
  DisableCAD = @{operator="eq";value="MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\DisableCAD=4,0";msg="交互式登录-无需按CTRL+ALT+DEL值(禁用)"}
  # - 交互式登录:计算机不活动限制值为600秒或更少
  InactivityTimeoutSecs = @{operator="eq";value="MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\InactivityTimeoutSecs=4,600";msg="交互式登录-计算机不活动限制值为600秒或更少"}
  # - 交互式登录: 计算机帐户阈值此策略设置确定可导致计算机重启的失败登录尝试次数
  MaxDevicePasswordFailedAttempts = @{operator="le";value="MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\MaxDevicePasswordFailedAttempts=4,10";msg="交互式登录: 此策略设置确定可导致计算机重启的失败登录尝试次数"}
  # - 交互式登录: 试图登录的用户的消息标题
  LegalNoticeCaption = @{operator="eq";value='MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\LegalNoticeCaption=1,"安全登陆"';msg="交互式登录: 试图登录的用户的消息标题"}
  # - 交互式登录: 试图登录的用户的消息文本
  LegalNoticeText = @{operator="eq";value='MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\LegalNoticeText=7,请谨慎的操作服务器中数据,您所有操作将被记录审计';msg="交互式登录: 试图登录的用户的消息文本"}

  # - Microsoft网络客户端: 将未加密的密码发送到第三方 SMB 服务器(禁用)
  EnablePlainTextPassword = @{operator="eq";value="MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters\EnablePlainTextPassword=4,0";msg="Microsoft网络客户端-将未加密的密码发送到第三方 SMB 服务器(禁用)"}
  # - Microsoft网络服务器:暂停会话前所需的空闲时间数量值为15分钟或更少但不为0
  AutoDisconnect = @{operator="15";value="MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\AutoDisconnect=4,15";msg="Microsoft网络服务器-暂停会话前所需的空闲时间数量值为15分钟"}

  # - 网络安全: 再下一次改变密码时不存储LAN管理器哈希值(启用)
  NoLMHash = @{operator="eq";value="MACHINE\System\CurrentControlSet\Control\Lsa\NoLMHash=4,1";msg="网络安全-在下一次改变密码时不存储LAN管理器哈希值(启用)"}

  # - 网络访问: 不允许SAM账户的匿名枚举值为(启用)
  RestrictAnonymousSAM = @{operator="eq";value="MACHINE\System\CurrentControlSet\Control\Lsa\RestrictAnonymousSAM=4,1";msg="网络访问-不允许SAM账户的匿名枚举值为(启用)"}
  # - 网络访问:不允许SAM账户和共享的匿名枚举值为(启用)
  RestrictAnonymous = @{operator="eq";value="MACHINE\System\CurrentControlSet\Control\Lsa\RestrictAnonymous=4,1";msg="网络访问-不允许SAM账户和共享的匿名枚举值为(启用)"}

  # - 关机:设置确定是否可以在无需登录 Windows 的情况下关闭计算机(禁用)
  ClearPageFileAtShutdown = @{operator="eq";value="MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management\ClearPageFileAtShutdown=4,0";msg="关机-设置确定是否可以在无需登录 Windows 的情况下关闭计算机(禁用)"}
}

- 操作系统组策略用户权限管理策略 - #
$SysUserPrivilegePolicy = @{
  # + 操作系统本地关机策略安全
  SeShutdownPrivilege = @{operator="eq";value='*S-1-5-32-544';msg="操作系统本地关机策略"}
  # + 操作系统远程关机策略安全
  SeRemoteShutdownPrivilege = @{operator="eq";value='*S-1-5-32-544';msg="操作系统远程关机策略"}
  # + 取得文件或其他对象的所有权限策略
  SeProfileSingleProcessPrivilege = @{operator="eq";value='*S-1-5-32-544';msg="取得文件或其他对象的所有权限策略"}
  # + 从网络访问此计算机策略
  SeNetworkLogonRight = @{operator="eq";value='*S-1-5-32-544,*S-1-5-32-545,*S-1-5-32-551';msg="从网络访问此计算机策略"}
}

- 注册表相关安全策略  -
$SysRegistryPolicy = @{
  # + 屏幕自动保护程序
  ScreenSaveActive = @{reg="HKEY_CURRENT_USER\Control Panel\Desktop";name="ScreenSaveActive";regtype="String";value=1;operator="eq";msg="开启屏幕自动保护程序策略"}
  # + 屏幕恢复时使用密码保护
  ScreenSaverIsSecure = @{reg="HKEY_CURRENT_USER\Control Panel\Desktop";name="ScreenSaverIsSecure";regtype="String";value=1;operator="eq";msg="开启屏幕恢复时使用密码保护策略"}
  # + 屏幕保护程序启动时间
  ScreenSaveTimeOut = @{reg="HKEY_CURRENT_USER\Control Panel\Desktop";name="ScreenSaveTimeOut";regtype="String";value=600;operator="le";msg="开启屏幕保护程序启动时间策略"}

  # + 禁止全部驱动器自动播放
  DisableAutoplay  = @{reg="HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer";name="DisableAutoplay";regtype="DWord";operator="eq";value=1;msg="禁止全部驱动器自动播放"}
  NoDriveTypeAutoRun = @{reg="HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer";name="NoDriveTypeAutoRun";regtype="DWord";operator="eq";value=255;msg="禁止全部驱动器自动播放"}

  # + 限制IPC共享(禁止SAM帐户和共享的匿名枚举)
  restrictanonymous = @{reg="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa";name="restrictanonymous";regtype="DWord";operator="eq";value=1;msg="不允许SAM账户和共享的匿名枚举值为(启用)"}
  restrictanonymoussam = @{reg="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa";name="restrictanonymoussam";regtype="DWord";operator="eq";value=1;msg="不允许SAM账户的匿名枚举值为(启用)"}

  # + 禁用磁盘共享(SMB)
  AutoShareWks = @{reg="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lanmanserver\parameters";name="AutoShareWks";regtype="DWord";operator="eq";value=0;msg="关闭禁用默认共享策略-Server2012"}
  AutoShareServer = @{reg="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lanmanserver\parameters";name="AutoShareServer";regtype="DWord";operator="eq";value=0;msg="关闭禁用默认共享策略-Server2012"}

  # + 系统、应用、安全、PS日志查看器大小(单位字节)设置(此处设置默认的两倍配置-建议一定通过日志采集平台采集系统日志比如ELK)
  EventlogSystemMaxSize = @{reg="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\System";name="MaxSize";regtype="DWord";operator="ge";value=41943040;msg="系统基日志配核查-系统日志查看器大小设置策略"}
  EventlogApplicationMaxSize = @{reg="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application";name="MaxSize";regtype="DWord";operator="ge";value=41943040;msg="系统日志基配核查-应用日志查看器大小设置策略"}
  EventlogSecurityMaxSize = @{reg="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security";name="MaxSize";regtype="DWord";operator="ge";value=41943040;msg="系统日志基配核查-安全日志查看器大小设置策略"}
  EventlogPSMaxSize = @{reg="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Windows PowerShell";name="MaxSize";regtype="DWord";operator="ge";value=31457280;msg="系统日志基配核查-PS日志查看器大小设置策略"}

  # + 远程桌面开启与关闭
  fDenyTSConnections = @{reg='HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Terminal Server';name='fDenyTSConnections';regtype="DWord";operator="eq";value=0;msg="是否禁用远程桌面服务-1则为禁用"}
  UserAuthentication = @{reg='HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp';name='UserAuthentication ';regtype="DWord";operator="eq";value=1;msg="只允许运行带网络级身份验证的远程桌面的计算机连接"}
  RDPTcpPortNumber = @{reg='HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp';name='PortNumber';regtype="DWord";operator="eq";value=39393;msg="远程桌面服务端口RDP-Tcp非3389"}
  TDSTcpPortNumber = @{reg='HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\Wds\rdpwd\Tds\tcp';name='PortNumber';regtype="DWord";operator="eq";value=39393;msg="远程桌面服务端口TDS-Tcp非3389"}

  # + 防火墙相关操作设置(开启、协议、服务)
  DomainEnableFirewall  = @{reg='HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile';name='EnableFirewall';regtype="DWord";operator="eq";value=1;msg="开启域网络防火墙"}
  StandardEnableFirewall = @{reg='HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile';name='EnableFirewall';regtype="DWord";operator="eq";value=1;msg="开启专用网络防火墙"}
  PPEnableFirewall = @{reg='HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile';name='EnableFirewall';regtype="DWord";operator="eq";value=1;msg="开启公用网络防火墙"}

  # + 源路由欺骗保护
  DisableIPSourceRouting = @{reg='HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters';name='DisableIPSourceRouting';regtype="DWord";operator="eq";value=2;msg="源路由欺骗保护"}

  # + 碎片攻击保护
  EnablePMTUDiscovery = @{reg='HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters';name='EnablePMTUDiscovery';regtype="DWord";operator="eq";value=1;msg="碎片攻击保护"}

  # 【TCP/IP 协议栈的调整可能会引起某些功能的受限,管理员应该在进行充分了解和测试的前提下进行此项工作】
  # + 防SYN洪水攻击:
  # SynAttackProtect = @{reg='HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters';name='EnablePMTUDiscovery';regtype="DWord";operator="eq";value=1;msg="设置防syn洪水攻击"}
  # TcpMaxHalfOpen = @{reg='HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters';name='TcpMaxHalfOpen';regtype="DWord";operator="eq";value=500;msg="允许的最大半开连接数"}
  # TcpMaxHalfOpenRetried = @{reg='HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters';name='TcpMaxHalfOpenRetried';regtype="DWord";operator="eq";value=400;msg="处于至少已发送一次重传的 SYN_RCVD 状态中的TCP连接数"}
  # + 防止DDOS攻击保护
  # EnableICMPRedirect = @{reg='HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters';name='EnableICMPRedirect';regtype="DWord";operator="eq";value=0;msg="防止DDOS攻击保护,不启用 ICMP 重定向"}

  # + 启用并正确配置WSUS(自定义WSUS地址)启用 (一般中大企业都会有自己的WSUS补丁服务器),你需要将下述http://wsus.weiyigeek.top改为企业中自建的地址
  # 启用策略组“配置自动更新”
  AUOptions = @{reg="HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU";name="AUOptions";regtype="DWord";operator="eq";value=3;msg="自动下载并计划安装(4)-建议设置3自动下载并通知安装"}
  AutomaticMaintenanceEnabled = @{reg="HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU";name="AutomaticMaintenanceEnabled";regtype="DWord";operator="eq";value=1;msg="启用自动维护"}
  NoAutoUpdate = @{reg="HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU";name="NoAutoUpdate";regtype="DWord";operator="eq";value=0;msg="关闭无自动更新设置"}
  ScheduledInstallDay = @{reg="HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU";name="ScheduledInstallDay";regtype="DWord";operator="eq";value=7;msg="计划安装日期为每周六"}
  ScheduledInstallTime = @{reg="HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU";name="ScheduledInstallTime";regtype="DWord";operator="eq";value=1;msg="计划安装时间为凌晨1点"}
  # 启用策略组(指定Intranet Microsoft更新服务位置)
  UseWUServer = @{reg="HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU";name="UseWUServer";regtype="DWord";operator="eq";value=1;msg="指定Intranet Microsoft更新服务补丁服务器"}
  WUServer = @{reg="HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate";name="WUServer";regtype="String";value="http://wsus.weiyigeek.top";operator="eq";msg="设置检测更新的intranet更新服务"}
  WUStatusServer = @{reg="HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate";name="WUStatusServer";regtype="String";value="http://wsus.weiyigeek.top";operator="eq";msg="设置Intranet统计服务器"}
  UpdateServiceUrlAlternate = @{reg="HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate";name="UpdateServiceUrlAlternate";regtype="String";value="http://wsus.weiyigeek.top";operator="eq";msg="设置备用下载服务器"}
}

################################################################################################################################
**********************#
* 全局公用工具依赖函数  *
**********************#
function F_Logging {
<# .synopsis f_logging 函数全局工具 .description 用于输出脚本执行结果并按照不同的日志等级输出显示到客户终端上。 .example -level [info|warning|error] -msg "测试输出字符串" #>
  param (
    [Parameter(Mandatory=$true)]$Msg,
    [ValidateSet("Info","Warning","Error")]$Level
  )

  switch ($Level) {
    Info {
      Write-Host "[INFO] ${Msg}" -ForegroundColor Green;
    }
    Warning {
      Write-Host "[WARN] ${Msg}" -ForegroundColor Yellow;
    }
    Error {
      Write-Host "[ERROR] ${Msg}" -ForegroundColor Red;
    }
    Default {
      Write-Host "[*] F_Logging 日志 Level 等级错误 Useage&#xFF1A; F_Logging -Level [Info|Warning|Error] -Msg '&#x6D4B;&#x8BD5;&#x8F93;&#x51FA;&#x5B57;&#x7B26;&#x4E32;'" -ForegroundColor Red;
    }
  }
}

Function F_IsCurrentUserAdmin
{
<# .synopsis f_iscurrentuseradmin 函数:全局公用工具依赖。 .description 判断当前运行的powershell终端是否管理员执行,返回值 true 或者 false .example #>
  $user = [Security.Principal.WindowsIdentity]::GetCurrent();
  (New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}

function F_Detection {
<# 1 .synopsis f_detection 函数: 全局公用工具依赖。 .description 函数用于检测 config.cfg 关键项是否匹配并返回相应的结果,返回值 或者 0。 .example -value $value -operator $operator -defaultvalue $defaultvalue #>
  param (
    [Parameter(Mandatory=$true)]$Value,
    [Parameter(Mandatory=$true)]$Operator,
    [Parameter(Mandatory=$true)]$DefaultValue
  )
  if ( $Operator -eq "eq" ) {
    if ( $Value -eq "$DefaultValue" ) {return 1;} else { return 0;}
  } elseif ($Operator -eq  "ne" ) {
    if ( $Value -ne $DefaultValue ) {return 1;} else { return 0;}
  } elseif ($Operator -eq  "le") {
    if ( $Value -le $DefaultValue ) {return 1;} else { return 0;}
  } elseif ($Operator -eq "ge") {
    if ( $Value -ge $DefaultValue ) {return 1;} else { return 0;}
  }
}

function F_GetRegPropertyValue {
<# .synopsis f_getregpropertyvalue 函数: 全局公用工具依赖函数。 .description 函数用于获取指定键与值并与预定义的进行对比,正常返回结果为1或者0,如果键不存在则返回notexist。 .example an example #>
  param (
    [Parameter(Mandatory=$true)][String]$Key,
    [Parameter(Mandatory=$true)][String]$Name,
    [Parameter(Mandatory=$true)][String]$Operator,
    [Parameter(Mandatory=$true)]$DefaultValue
  )

  try {
    $Value = Get-ItemPropertyValue -Path "Registry::$Key" -Name $Name -ErrorAction Ignore -WarningAction Ignore
    $Result = F_Detection -Value $Value -Operator $Operator -DefaultValue $DefaultValue
    return $Result
  } catch {
    F_Logging -Level Warning -Msg "[*] $Key - $Name - NotExist"
    return 'NotExist'
  }
}

function F_SeceditReinforce() {
<# .synopsis f_seceditreinforce 函数:实现系统策略组配置项对比和修改。 .description 针对 config.cfg 安全配置项进行检测并修改,主要涉及系统账号策略设置、系统事件审核策略设置、系统组策略安全选项配置、操作系统组用户权限管理策略配置 .example #>
  # - &#x7CFB;&#x7EDF;&#x8D26;&#x53F7;&#x7B56;&#x7565;&#x8BBE;&#x7F6E;
  $Hash = $SysAccountPolicy.Clone()
  foreach ( $Name in $Hash.keys ) {
    $Flag = $Config | Select-String -AllMatches -Pattern "^$($Name.toString())"
    if ($Flag) {
      F_Logging -Level Info -Msg "[*] Update - $Name"
      $Line = $Flag -split " = "
      $Result = F_Detection -Value $Line[1] -Operator $SysAccountPolicy["$($Line[0])"].operator -DefaultValue $SysAccountPolicy["$($Line[0])"].value
      $NewLine = $Line[0] + " = " + $SysAccountPolicy["$($Line[0])"].value
      # - &#x5728;&#x4E0D;&#x5339;&#x914D;&#x65F6;&#x8FDB;&#x884C;&#x5173;&#x952E;&#x9879;&#x66FF;&#x6362;&#x914D;&#x7F6E;
      if ( -not($Result) -or $Line[0] -eq "NewGuestName" -or $Line[0] -eq "NewAdministratorName" ) {
          write-host "    $Flag -->> $NewLine"
        # &#x6B64;&#x5904;&#x91C7;&#x7528;&#x6B63;&#x5219;&#x8FDB;&#x884C;&#x5339;&#x914D;&#x7CFB;&#x7EDF;&#x8D26;&#x53F7;&#x7B56;&#x7565;&#x76F8;&#x5173;&#x9879;,&#x9632;&#x6B62;&#x540E;&#x7EED;
        $SecConfig = $SecConfig -replace "$Flag", "$NewLine"
      }
    } else {
      F_Logging -Level Info -Msg "[+] Insert - $Name"
      $NewLine = $Name + " = " + $SysAccountPolicy["$Name"].value
      Write-Host "    $NewLine "
      # - &#x5728;&#x4E0D;&#x5B58;&#x5728;&#x8BE5;&#x914D;&#x7F6E;&#x9879;&#x65F6;&#x8FDB;&#x884C;&#x63D2;&#x5165;
      $SecConfig = $SecConfig -replace "\[System Access\]", "[System Access]n$NewLine"
    }
  }

  # - 系统事件审核策略设置
  $Hash = $SysEventAuditPolicy.Clone()
  foreach ( $Name in $Hash.keys ) {
    $Flag = $Config | Select-String $Name.toString()
    if ($Flag) {
      F_Logging -Level Info -Msg "[*] Update - $Name"
      $Line = $Flag -split " = "
      $Result = F_Detection -Value $Line[1] -Operator $SysEventAuditPolicy["$($Line[0])"].operator -DefaultValue $SysEventAuditPolicy["$($Line[0])"].value
      $NewLine = $Line[0] + " = " + $SysEventAuditPolicy["$($Line[0])"].value
      # - 在不匹配时进行关键项替换配置
      if (-not($Result)) {
        $SecConfig = $SecConfig -replace "$Flag", "$NewLine"
      }
    } else {
      F_Logging -Level Info -Msg "[+] Insert - $Name"
      $NewLine = $Name + " = " + $SysEventAuditPolicy["$Name"].value
      Write-Host "  $NewLine"
      # - 在不存在该配置项时进行插入
      $SecConfig = $SecConfig -replace "\[Event Audit\]", "[Event Audit] $NewLine"
    }
  }

  # - &#x7CFB;&#x7EDF;&#x7EC4;&#x7B56;&#x7565;&#x5B89;&#x5168;&#x9009;&#x9879;&#x914D;&#x7F6E; - #
  $Hash = $SysSecurityOptionPolicy.Clone()
  foreach ( $Name in $Hash.keys ) {
    $Flag = $Config | Select-String $Name.toString()
    if ($Flag) {
      F_Logging -Level Info -Msg "[*] Update - $Name"
      # &#x6E90;&#x5B57;&#x7B26;&#x4E32;
      $Line = $Flag -split "="
      # &#x76EE;&#x6807;&#x5B57;&#x7B26;&#x4E32;
      $Value = $SysSecurityOptionPolicy["$($Name)"].value -split "="
      $Result = F_Detection -Value $Line[1] -Operator $SysSecurityOptionPolicy["$($Name)"].operator -DefaultValue $Value[1]
      $NewLine = $Line[0] + "=" + $Value[1]
      if (-not($Result)) {
        $SecConfig = $SecConfig -Replace ([Regex]::Escape("$Flag")),"$NewLine"
      }
    } else {
      F_Logging -Level Info -Msg "[+] Insert - $Name"
      $NewLine = $SysSecurityOptionPolicy["$Name"].value
      Write-Host "   $NewLine"
      # &#x4E0D;&#x91C7;&#x7528;&#x6B63;&#x5219;&#x5339;&#x914D;&#x539F;&#x5B57;&#x7B26;&#x4E32;(&#x503C;&#x5F97;&#x5B66;&#x4E60;)
      $SecConfig = $SecConfig -Replace ([Regex]::Escape("[Registry Values]")),"[Registry Values]n$NewLine"
    }
  }

  # - 操作系统组用户权限管理策略配置
  $Hash = $SysUserPrivilegePolicy.Clone()
  foreach ( $Name in $Hash.keys ) {
    $Flag = $Config | Select-String $Name.toString()
    if ($Flag) {
      F_Logging -Level Info -Msg "[*] Update - $Name"
      $Line = $Flag -split " = "
      $Result = F_Detection -Value $Line[1] -Operator $SysUserPrivilegePolicy["$($Line[0])"].operator -DefaultValue $SysUserPrivilegePolicy["$($Line[0])"].value
      $NewLine = $Line[0] + " = " + $SysUserPrivilegePolicy["$($Line[0])"].value
      if (-not($Result)) {
        $SecConfig = $SecConfig -Replace ([Regex]::Escape("$Flag")), "$NewLine"
      }
    } else {
      F_Logging -Level Info -Msg "[+] Insert - $Name"
      $NewLine = $Name + " = " + $SysUserPrivilegePolicy["$Name"].value
      Write-Host "    $NewLine"
      $SecConfig = $SecConfig -Replace ([Regex]::Escape("[Privilege Rights]")),"[Privilege Rights]$NewLine"
    }
  }
   # &#x5C06;&#x751F;&#x6210;&#x7684;&#x672C;&#x5730;&#x5B89;&#x5168;&#x7EC4;&#x7B56;&#x7565;&#x914D;&#x7F6E;&#x8F93;&#x5230;secconfig.cfg,&#x3010;&#x5751;&#x3011;&#x975E;&#x5E38;&#x6CE8;&#x610F;&#x6587;&#x4EF6;&#x7F16;&#x7801;&#x683C;&#x5F0F;&#x4E3A;UTF16-LE,&#x6B64;&#x65F6;&#x9700;&#x8981;&#x6DFB;&#x52A0;-Encoding&#x53C2;&#x6570;&#x5E76;&#x6307;&#x5B9A;&#x4E3A;string
   $SecConfig | Out-File secconfig.cfg -Encoding string
}

function F_SysRegistryReinforce()  {
<# .synopsis f_sysregistryreinforce 函数针对于注册表中系统相关配置。 .description 针对操作系统注册表安全配置项与sysregistrypolicy哈希表的键值进行检测与设置。 .example #>
  # - &#x6EE1;&#x8DB3;&#x7B49;&#x7EA7;&#x4FDD;&#x62A4;&#x76F8;&#x5173;&#x57FA;&#x7840;&#x914D;&#x7F6E;
  $Hash = $SysRegistryPolicy.Clone()
  foreach ( $Name in $Hash.keys ) {
    $Result = F_GetRegPropertyValue -Key $SysRegistryPolicy.$Name.reg -Name $SysRegistryPolicy.$Name.name -Operator $SysRegistryPolicy.$Name.operator -DefaultValue $SysRegistryPolicy.$Name.value
    F_Logging -Level Info -Msg "Get-ItemProperty -Path Registry::$($SysRegistryPolicy.$Name.reg)"
    if ( $Result -eq 'NotExist' ){
      # - &#x5224;&#x65AD;&#x6CE8;&#x518C;&#x8868;&#x9879;&#x662F;&#x5426;&#x5B58;&#x5728;&#x4E0D;&#x5B58;&#x5728;&#x5219;&#x521B;&#x5EFA;
      if (-not(Test-Path -Path "Registry::$($SysRegistryPolicy.$Name.reg)")){
        F_Logging -Level Info -Msg "&#x6B63;&#x5728;&#x521B;&#x5EFA; $($SysRegistryPolicy.$Name.reg) &#x6CE8;&#x518C;&#x8868;&#x9879;......"
        New-Item -Path "registry::$($SysRegistryPolicy.$Name.reg)" -Force
      }
      # - &#x53EF;&#x80FD;&#x7684;&#x679A;&#x4E3E;&#x503C;&#x5305;&#x62EC;"String&#x3001;ExpandString&#x3001;Binary&#x3001;DWord&#x3001;MultiString&#x3001;QWord&#x3001;Unknown"
      New-ItemProperty -Path "Registry::$($SysRegistryPolicy.$Name.reg)" -Name $SysRegistryPolicy.$Name.name -PropertyType $SysRegistryPolicy.$Name.regtype -Value $SysRegistryPolicy.$Name.value
    } elseif ( $Result -eq 0 ) {
      Set-ItemProperty -Path "Registry::$($SysRegistryPolicy.$Name.reg)" -Name $SysRegistryPolicy.$Name.name -Value $SysRegistryPolicy.$Name.value
    }
  }
}

function F_ServiceManager() {
<# .synopsis f_servicemanager 函数:针对于系统中相关服务管理操作 .description 主要对系统中某些服务进行停止禁用 .example -name server -operator restart -starttype automatic #>
  param (
    [Parameter(Mandatory=$true)]$Name,
    [ValidateSet("Start","Stop","Restart")]$Operator,
    [ValidateSet("Automatic","Manual","Disabled","Boot","System")]$StartType
  )
  # - &#x9A8C;&#x8BC1;&#x670D;&#x52A1;&#x662F;&#x5426;&#x5B58;&#x5728;
  F_Logging -Level Info -Msg "&#x6B63;&#x5728;&#x5BF9; $Name &#x670D;&#x52A1;&#x8FDB;&#x884C;&#x64CD;&#x4F5C;&#x7BA1;&#x7406;......."
  $ServiceStatus = (Get-Service $Name -ErrorAction SilentlyContinue).Status
  if( -not($ServiceStatus.Length) ) {
    F_Logging -Level Error -Msg "$Name Service is not exsit with current system!!!!!!"
    return
  }

  # - &#x6839;&#x636E;$Operator&#x64CD;&#x4F5C;&#x670D;&#x52A1;&#x542F;&#x52A8;&#x3001;&#x505C;&#x6B62;&#x3001;&#x91CD;&#x542F;
  switch ($Operator) {
    Start {
      if ( "$ServiceStatus" -ne "Running" ) {
        F_Logging -Level Info -Msg "&#x6B63;&#x5728;&#x542F;&#x52A8; $Name &#x670D;&#x52A1;";Start-Service -Name $Name -Force
      }
    }
    Stop {
      if ( "$ServiceStatus" -ne "Stopped" ) {
        F_Logging -Level Warning -Msg "&#x6B63;&#x5728;&#x505C;&#x6B62; $Name &#x670D;&#x52A1;";Stop-Service -Name $Name -Force
      }
    }
    Restart {
      F_Logging -Level Warning -Msg "&#x6B63;&#x5728;&#x91CD;&#x542F; $Name &#x670D;&#x52A1;";Restart-Service -Name $Name -Force
    }
    Default { F_Logging -Level Info -Msg "&#x672A;&#x5BF9; $Name &#x670D;&#x52A1;&#x505A;&#x4EFB;&#x4F55;&#x64CD;&#x4F5C;!" }
  }

  # - &#x6839;&#x636E;$StartType&#x8BBE;&#x7F6E;&#x670D;&#x52A1;&#x542F;&#x52A8;&#x7C7B;&#x578B;
  switch ($StartType) {
    Automatic { Set-Service -Name $Name -StartupType Automatic}
    Manual { Set-Service -Name $Name -StartupType Manual }
    Disabled { Set-Service -Name $Name -StartupType Disabled}
    Boot { Set-Service -Name $Name -StartupType Boot}
    System {Set-Service -Name $Name -StartupType System }
    Default {F_Logging -Level Info -Msg "&#x672A;&#x5BF9; $Name &#x670D;&#x52A1;&#x505A;&#x4EFB;&#x4F55;&#x81EA;&#x542F;&#x914D;&#x7F6E;&#x64CD;&#x4F5C;!"}
  }
}

Function F_ExtentionReinforce() {
<# .synopsis f_extentionreinforce 函数:针对于系统暂无办法通过注册表以及组策略配置的将在此处执行。 .description 执行系统加固的相关命令,其中保护powershell或者cmd相关命令 .example #>
  # [+] &#x7981;&#x7528;&#x5171;&#x4EAB;&#x670D;&#x52A1;&#x4EE5;&#x53CA;&#x5220;&#x9664;&#x5F53;&#x524D;&#x4E3B;&#x673A;&#x4E2D;&#x6240;&#x6709;&#x5171;&#x4EAB;

  F_ServiceManager -Name lanmanserver -Operator Stop -StartType Manual
  (gwmi -class win32_share).delete()
  # &#x65B9;&#x5F0F;2.(Get-WmiObject -class win32_share).delete()

  # [+] &#x542F;&#x7528;windows&#x9632;&#x706B;&#x5899;&#x4EE5;&#x53CA;&#x9632;&#x706B;&#x5899;&#x76F8;&#x5173;
  netsh advfirewall set allprofiles state on
  # &#x542F;&#x7528;&#x3001;&#x6216;&#x8005;&#x7981;&#x7528;&#x6587;&#x4EF6;&#x548C;&#x6253;&#x5370;&#x673A;&#x5171;&#x4EAB;(&#x56DE;&#x663E;&#x8BF7;&#x6C42; - ICMPv4-In) &#x6839;&#x636E;&#x9700;&#x6C42;&#x800C;&#x5B9A;
  # Enable-NetFirewallRule -Name FPS-ICMP4-ERQ-In
  Disable-NetFirewallRule  -Name FPS-ICMP4-ERQ-In
  Get-NetFirewallRule -Name "CustomSecurity-Remote-Desktop-Port" -ErrorAction SilentlyContinue
  if ($?) {
    # &#x5141;&#x8BB8;&#x5176;&#x5B83;&#x4E3B;&#x673A;&#x8BBF;&#x95EE; Remote-Desktop-Port &#x7684;39393&#x7AEF;&#x53E3;&#x3002;
    New-NetFirewallRule -Name "CustomSecurity-Remote-Desktop-Port" -DisplayName "CustomSecurity-Remote-Desktop-Port" -Description "CustomSecurity-Remote-Desktop-Port" -Direction Inbound -LocalPort 39393 -Protocol TCP -Action Allow -Enabled True
  }
}

Function F_SensitiveFile() {
<# # .synopsis f_sensitivefile 函数:针对于系统中相关服务的敏感文件检测。(后续扩充) .description 针对 config.cfg 安全配置项进行检测并修改 .example>
  $SensitiveFile = @("%systemroot%\system32\inetsrv\iisadmpwd")
  if (Test-Path -Path $SensitiveFile[$i]) {
    # 1.&#x5220;&#x9664;&#x5177;&#x6709;&#x4EFB;&#x4F55;&#x6587;&#x4EF6;&#x6269;&#x5C55;&#x540D;&#x7684;&#x6587;&#x4EF6;
    Remove-Item C:\Test\*.* # == Del C:\Test\*.*
    Remove-Item -Path C:\Test\file.txt -Force

    # 2.&#x5220;&#x9664;&#x7279;&#x6B8A;&#x6761;&#x4EF6;&#x7684;&#x6587;&#x4EF6;&#x6216;&#x8005;&#x76EE;&#x5F55;
    Remove-Item -Path C:\temp\DeleteMe -Recurse # &#x9012;&#x5F52;&#x5220;&#x9664;&#x5B50;&#x6587;&#x4EF6;&#x5939;&#x4E2D;&#x7684;&#x6587;&#x4EF6;
    }
}

function Main {
<# .synopsis main 函数程序执行入口 .description 调用上述编写的相关检测加固函数 .example #>
F_Logging -Level Info -Msg "#################################################################################"
F_Logging -Level Info -Msg "- @Desc: Windows Server &#x5B89;&#x5168;&#x914D;&#x7F6E;&#x7B56;&#x7565;&#x57FA;&#x7EBF;&#x52A0;&#x56FA;&#x811A;&#x672C; [&#x5C06;&#x4F1A;&#x5728;Github&#x4E0A;&#x6301;&#x7EED;&#x66F4;&#x65B0;-star]"
F_Logging -Level Info -Msg "- @Author: WeiyiGeek"
F_Logging -Level Info -Msg "- @Blog: https://www.weiyigeek.top"
F_Logging -Level Info -Msg "- @Github: https://github.com/WeiyiGeek/SecOpsDev/tree/master/OS-&#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;/Windows"
$StartTime = Get-date -Format 'yyyy-M-d H:m:s'
F_Logging -Level Info -Msg "#################################################################################n"

1.当前系统策略配置文件导出 (注意必须系统管理员权限运行)
F_Logging -Level Info -Msg "- 正在检测当前运行的PowerShell终端是否管理员权限..."
$flag = F_IsCurrentUserAdmin
if (!($flag)) {
  F_Logging -Level Error -Msg "- &#x811A;&#x672C;&#x6267;&#x884C;&#x53D1;&#x751F;&#x9519;&#x8BEF;,&#x8BF7;&#x4F7F;&#x7528;&#x7BA1;&#x7406;&#x5458;&#x6743;&#x9650;&#x8FD0;&#x884C;&#x8BE5;&#x811A;&#x672C;..&#x4F8B;&#x5982;: Start-Process powershell -Verb runAs....n"
  F_Logging -Level Warning -Msg "- 正在退出执行该脚本......"
  return
}

2.&#x5BFC;&#x51FA;&#x5F53;&#x524D;&#x7CFB;&#x7EDF;&#x7B56;&#x7565;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x540E;&#x9A8C;&#x8BC1;&#x6587;&#x4EF6;&#x662F;&#x5426;&#x5B58;&#x5728;&#x4EE5;&#x53CA;&#x539F;&#x59CB;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x5907;&#x4EFD;&#x3002;
secedit /export /cfg config.cfg /quiet
start-sleep 3
if ( -not(Test-Path -Path config.cfg) ) {
  F_Logging -Level Error -Msg "- &#x5F53;&#x524D;&#x7CFB;&#x7EDF;&#x7B56;&#x7565;&#x914D;&#x7F6E;&#x6587;&#x4EF6; config.cfg &#x4E0D;&#x5B58;&#x5728;,&#x8BF7;&#x68C0;&#x67E5;......"
  F_Logging -Level Warning -Msg "- &#x6B63;&#x5728;&#x9000;&#x51FA;&#x6267;&#x884C;&#x8BE5;&#x811A;&#x672C;......"
  return
} else {
  Copy-Item -Path config.cfg -Destination config.cfg.bak -Force
}
$Config = Get-Content -path config.cfg
$SecConfig = $Config.Clone()

3.&#x8FDB;&#x884C;&#x7CFB;&#x7EDF;&#x7B56;&#x7565;&#x914D;&#x7F6E;&#x5B89;&#x5168;&#x52A0;&#x56FA;
F_SeceditReinforce

4.&#x5F53;&#x7CFB;&#x7EDF;&#x7B56;&#x7565;&#x914D;&#x7F6E;&#x5B89;&#x5168;&#x52A0;&#x56FA;&#x5B8C;&#x6210;&#x540E;&#x5C06;&#x751F;&#x6210;&#x7684;secconfig.cfg&#x5BFC;&#x5165;&#x8FDB;&#x7CFB;&#x7EDF;&#x7B56;&#x7565;&#x4E2D;&#x3002;
secedit /configure /db secconfig.sdb /cfg secconfig.cfg

5.&#x8FDB;&#x884C;&#x7CFB;&#x7EDF;&#x6CE8;&#x518C;&#x8868;&#x76F8;&#x5173;&#x914D;&#x7F6E;&#x5B89;&#x5168;&#x52A0;&#x56FA;
F_SysRegistryReinforce

6.&#x7CFB;&#x7EDF;&#x6269;&#x5C55;&#x76F8;&#x5173;&#x914D;&#x7F6E;&#x5B89;&#x5168;&#x52A0;&#x56FA;
F_ExtentionReinforce

7.&#x7A0B;&#x5E8F;&#x6267;&#x884C;&#x5B8C;&#x6BD5;
$EndTime = Get-date -Format 'yyyy-M-d H:m:s'
F_Logging -Level Info -Msg "- &#x8BE5;&#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#x5B89;&#x5168;&#x52A0;&#x56FA;&#x5DF2;&#x5B8C;&#x6BD5;......n开始时间:${StartTime}&#x5B8C;&#x6210;&#x65F6;&#x95F4;: ${EndTime}"
}
Main
</#></#></#></#></#></#></#></#></#></#></#>

至此,Windows 安全基线配置核查和安全加固脚本分享完毕。

Original: https://www.cnblogs.com/hahaha111122222/p/16451785.html
Author: 哈喽哈喽111111
Title: 完整的WindowsServer服务器系统初始化配置、安全策略加固和基线检查脚本等保2.0适用

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/547397/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • linuxinode详解/线上inode爆满解决方案

    linux inode 详解 / 线上inode爆满解决方案 本文大量参考阮一峰大神博客,整理笔记 &#x4E4B;&#x6240;&#x4EE5;&amp…

    技术杂谈 2023年7月24日
    082
  • BFD双向转发检测

    BFD双向转发检测 https://www.ruijie.com.cn/fw/wt/36476/ BFD:(Bidirectional Forwarding Detection,双…

    技术杂谈 2023年5月30日
    0112
  • 三层架构与MVC &amp; 设计模式的较量

    刚刚学习了三层架构,并且正在实际应用中,但随着学习的深入,又了解到了一个叫MVC 的东西,(早在设计模式中就听到过MVC,仅仅是简单查了一下什么意思.)如今正好把这三个东西放在一起…

    技术杂谈 2023年5月31日
    070
  • [YARN] 2.2 GB of 2.1 GB virtual memory used. Killing container.

    Spark程序在yarn的集群运行,出现 Current usage: 105.9 MB of 1 GB physical memory used; 2.2 GB of 2.1 G…

    技术杂谈 2023年5月30日
    094
  • maven的安装和仓库的种类和彼此关系

    ; ; Maven软件的下载 为了使用Maven管理工具,哦我们首先要到官网去下载他的安装软件,通过百度搜索Mav嗯如下: 点击Download连接,就可以直接进入到Maven软件…

    技术杂谈 2023年6月21日
    0107
  • Goroutines (一)

    Goroutines CSP communicating sequential processes Go 语言中,每一个并发执行单元叫做一个goroutine,语法上仅需要在一个普…

    技术杂谈 2023年7月11日
    059
  • 人生苦短,我用JRebel

    昨天看到团子推送的一篇关于热部署的文章,其中介绍了自研的Sonic插件在公司内部的应用。同时晒出来一张对比图: 团子表示我们的插件要比同类插件优秀哦。不过我定睛一看,好家伙,第一列…

    技术杂谈 2023年7月25日
    073
  • 67.我会是你手边静候的树

    dfds posted @2022-09-28 08:39 随遇而安== 阅读(5 ) 评论() 编辑 Original: https://www.cnblogs.com/55zj…

    技术杂谈 2023年6月21日
    0127
  • AIOps

    AIOps是什么? AIOps是人工智能在IT操作中的应用。它是ITOps的未来,将算法和人工智能结合在一起,为企业所依赖的It系统的状态和性能提供全面的可见性。 简单地说,AIO…

    技术杂谈 2023年5月31日
    083
  • 基于LNMP快速简单搭建wordpress平台

    一、WordPress 简介 WordPress是一种使用PHP语言开发的博客平台,用户可以在支持PHP和MySQL数据库的服务器上架设属于自己的网站。也可以把WordPress当…

    技术杂谈 2023年7月11日
    059
  • 如何使能uboot的debug开关?

    答: 直接在 Original: https://www.cnblogs.com/dakewei/p/14010217.htmlAuthor: JelloTitle: 如何使能ub…

    技术杂谈 2023年5月31日
    0129
  • wsl openssh安装

    1、卸载openssh sudo apt remove openssh-server 2、设置软件源修改/etc/apt/sources.list为下面内容,使用vi时先按下i再粘…

    技术杂谈 2023年6月1日
    085
  • Hadoop(四)C#操作Hbase

    Hbase Hbase是一种NoSql模式的数据库,采用了 列式存储。而采用了列存储天然具备以下优势: 可只查涉及的列,且列可作为索引,相对高效 针对某一列的聚合及其方便 同一列的…

    技术杂谈 2023年7月24日
    074
  • 使用 async-await 实现一个请求失败自动重新请求的函数

    在项目开发中, 需要拉取 GA 数据放到自己的数据库中, 用于做更定制化的数据分析和图表等. 但是因为数据较多, GA 一次性只能取得 10w 条数据, 所以需要多次请求才能获取到…

    技术杂谈 2023年6月21日
    0103
  • Java: native

    解释 native主要用于 方法上 1、一个native方法就是一个Java调用非Java代码的接口。一个native方法是指该方法的实现由非Java语言实现,比如用C或C++实现…

    技术杂谈 2023年7月24日
    089
  • RocketMQ系列二:RocketMQ监控/告警一站式搭建应用

    ​实验简介研究RocketMQ的同学都知道,RocketMQ的生态目前并不是很完善,包括官方的文档资料也有限,官方的Console存在一些Bug,页面的样式有的也有问题,但是正是由…

    技术杂谈 2023年7月11日
    073
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球