当我删除下游服务器上的计算机时遇到问题。 我通过 powershell 使用对象 Microsoft.UpdateServices.Administration.ComputerTargetScope 中的类 .Delete() 来完成此操作。 该计算机已从下游服务器中正确删除,但删除未在主服务器上同步,并且该计算机仍然存在于主服务器上。 我尝试同步双方,但计算机仍然存在于主机上。
这是我的脚本:
#Définition des paramètres d'invocation du script
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true, Position = 1)]
[string]
$UpdateServer,
[Parameter(Mandatory = $true, Position = 2)]
[int]
$Port,
[Parameter()]
[switch]
$UseSSL,
[Parameter()]
[int]
$ExclusionPeriod = 0
)
#Création du dossier de logs
if (-not (Test-Path -Path "$PSScriptRoot\WsusDeleteComputersLogs"))
{
New-Item -Path $PSScriptRoot -Name 'WsusDeleteComputersLogs' -ItemType Directory -Force
}
#Création du fichier de logs qui va restranscrire les output du script
$file = "$PSScriptRoot\WsusDeleteComputersLogs\{0:yyyyMMdd_HHmm}_WSUS_Delete_Computers.log" -f (Get-Date)
#Début de la retranscription pour écrire tous les logs du script dans le fichier ci-dessus
Start-Transcript -Path $file
#Création de variables contenant les chemins des fichiers où seront listées les mises à jours remplacées et rétablies
$outDeletedList = Join-Path -Path "$PSScriptRoot\WsusDeleteComputersLogs" -ChildPath ('{0:yyyyMMdd_HHmm}_DeletedComputers.csv' -f (Get-Date))
#Création de la ligne des titres dans le fichier CSV des mises à jour remplacées et rétablies
Set-Content -Value 'Server; FullDomainName; LastReportStatusTime; In Stock' -Path $outDeletedList
#Importe le module ActiveDirectory pour se connecter à l'AD
Import-Module ActiveDirectory
#Récupération des pcs présents dans l'OU Stock
$OUstock = (Get-ADComputer -SearchBase "OU=Stock,DC=domain,DC=lan" -Filter * -SearchScope Subtree).DNSHostName
#Création d'une variable pour se connecter au serveur WSUS avec ou sans SSL
try
{
if ($UseSSL)
{
Write-Output -InputObject "Connecting to WSUS server $UpdateServer on Port $Port using SSL... "
}
else
{
Write-Output -InputObject "Connecting to WSUS server $UpdateServer on Port $Port... "
}
[reflection.assembly]::LoadWithPartialName('Microsoft.UpdateServices.Administration') | Out-Null
$wsusMaster = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer($UpdateServer, $UseSSL, $Port);
}
catch [System.Exception]
{
Write-Output -InputObject 'Failed to connect.'
Write-Output -InputObject "Error: $($_.Exception.Message)"
Write-Output -InputObject 'Please make sure that WSUS Admin Console is installed on this machine'
Write-Output -InputObject ''
$wsusMaster = $null
}
#Arrête le script si la connexion au serveur a échoué
if ($null -eq $wsusMaster)
{
return
}
Write-Output -InputObject 'Connected.'
#Création d'une variable qui contiendra tous les serveur en aval
try
{
#Récupération de la liste des serveur WSUS en aval du Master
$wsusDownstreamServers = $wsusMaster.GetDownstreamServers()
}
catch [System.Exception]
{
Write-Output -InputObject 'Failed to get Downstream Servers.'
Write-Output -InputObject "Error: $($_.Exception.Message)"
Write-Output -InputObject ''
return
}
#Initie les filtres pour une liste d'ordinateurs dans une variable
$computerScope = New-Object Microsoft.UpdateServices.Administration.ComputerTargetScope
#Indique la date et l'heure actuels
Write-Host "Date du jour : " (Get-Date)
#Définit la plage des dates des derniers rapports des ordinateurs dans la variable initiée ci-dessus
Write-Host "Date limite : "((Get-Date).AddDays(-8))
#Création des variables utilisées dans le script
$countAllComputers = 0
$countOutDatedAll = 0
$countInStockAll = 0
$countDeleted = 0
Foreach($wsusDownstreamserver in $wsusDownstreamServers)
{
$computerScopeIn = New-Object Microsoft.UpdateServices.Administration.ComputerTargetScope
$computerScopeIn.ToLastReportedStatusTime = (Get-Date).AddDays(-8)
Write-Host $wsusDownstreamserver.FullDomainName
try
{
$connectDownstreamserver = (Get-WsusServer -Name $wsusDownstreamserver.FullDomainName -PortNumber "8530")
Write-Host "Connected to : $($wsusDownstreamserver.FullDomainName)"
$computerList = $connectDownstreamserver.GetComputerTargets()
$computerListScope = $connectDownstreamserver.GetComputerTargets($computerScopeIn)
}
catch [System.Exception]
{
Write-Output -InputObject 'Failed to connect.'
Write-Output -InputObject "Error: $($_.Exception.Message)"
Write-Output -InputObject 'Please make sure that WSUS Admin Console is installed on this machine'
Write-Output -InputObject ''
continue
}
Write-Host "Groupe $($wsusDownstreamserver.FullDomainName) : "
Write-Host ""
Foreach($computer in $computerList)
{
$countAllComputers++
if($OUstock -contains $computer.FullDomainName)
{
$countStockAll++
Write-host "L'ordinateur $($computer.FullDomainName) est dans l'OU Stock"
"$($wsusDownstreamserver.FullDomainName); $($computer.FullDomainName); $($computer.LastReportedStatusTime.ToLocalTime()); TRUE" | Out-File $outDeletedList -Append
$computer.Delete()
$countDeleted++
}
}
Foreach($computerScope in $computerListScope)
{
$countOutDatedAll++
Write-host "L'ordinateur $($computerScope.FullDomainName) n'a pas été synchronisé depuis le $($computerScope.LastReportedStatusTime.ToLocalTime())"
"$($wsusDownstreamserver.FullDomainName); $($computerScope.FullDomainName); $($computerScope.LastReportedStatusTime.ToLocalTime()); FALSE" | Out-File $outDeletedList -Append
$computerScope.Delete()
$countDeleted++
}
Write-Host ""
Write-Host "-----"
Write-Host ""
$computerListScope = 0
$computerListScope = 0
}
#Log de sortie contenant les informations de comptage ci-dessus
Write-Output -InputObject 'Summary:'
Write-Output -InputObject '========'
Write-Output -InputObject "All Computers = $($countAllComputers)"
Write-Output -InputObject "All OutDated Computers = $($countOutDatedAll)"
Write-Output -InputObject "All In Stock OU = $($countStockAll)"
Write-Output -InputObject "All Deleted Computers = $($countDeleted)"
Write-Output -InputObject ""
Write-Output -InputObject "---"
Write-Output -InputObject "End"
Stop-Transcript
感谢您的帮助:)
我找到了解决问题的方法。 我必须添加 SQL 命令来删除主机上 SQL 数据库中的计算机,如下所示:
Foreach($computer in $computerList)
{
$countAllComputers++
if($OUStock -contains $computer.FullDomainName)
{
$countInStockAll++
Write-host "L'ordinateur $($computer.FullDomainName) est dans l'OU Stock"
"$($wsusDownstreamserver.FullDomainName); $($computer.FullDomainName); $($computer.LastReportedStatusTime.ToLocalTime()); TRUE" | Out-File $outDeletedList -Append
$computer.Delete()
$countDeleted++
$FullDomainName = $computer.FullDomainName
# Préparation de la requête pour récupérer TargetId et ComputerID
$queryRetrieval = @"
SELECT TargetID, ComputerID FROM [SUSDB].[dbo].[tbComputerTarget] WHERE FullDomainName = '$FullDomainName'
"@
# Exécution de la requête pour récupérer les valeurs
$result = Invoke-Sqlcmd -Query $queryRetrieval -ServerInstance "np:\\.\pipe\MICROSOFT##WID\tsql\query" -Database "SUSDB" -Encrypt Optional
# Vérification et affichage des résultats
if ($result) {
Write-Output "TargetID: $($result.TargetID)"
Write-Output "ComputerID: $($result.ComputerID)"
try{
# Préparation de la requête pour supprimer l'entrée
$queryDeletion = @"
DELETE FROM [SUSDB].[dbo].[tbComputerTarget] WHERE ComputerID = '$($result.ComputerID)'
"@
# Exécution de la requête de suppression
Invoke-Sqlcmd -Query $queryDeletion -ServerInstance "np:\\.\pipe\MICROSOFT##WID\tsql\query" -Database "SUSDB" -Encrypt Optional
Write-Output "Entrée supprimée pour l'ordinateur: $($FullDomainName)"
}
catch{
Write-Output $_.Exception.Message
}
} else {
Write-Output "Aucun enregistrement trouvé pour $FullDomainName"
}
}
}
Foreach($computerScope in $computerListScope)
{
$countOutDatedAll++
Write-host "L'ordinateur $($computerScope.FullDomainName) n'a pas été synchronisé depuis le $($computerScope.LastReportedStatusTime.ToLocalTime())"
"$($wsusDownstreamserver.FullDomainName); $($computerScope.FullDomainName); $($computerScope.LastReportedStatusTime.ToLocalTime()); FALSE" | Out-File $outDeletedList -Append
$computerScope.Delete()
$countDeleted++
$FullDomainName = $computerScope.FullDomainName
# Préparation de la requête pour récupérer TargetId et ComputerID
$queryRetrieval = @"
SELECT TargetID, ComputerID FROM [SUSDB].[dbo].[tbComputerTarget] WHERE FullDomainName = '$FullDomainName'
"@
# Exécution de la requête pour récupérer les valeurs
$result = Invoke-Sqlcmd -Query $queryRetrieval -ServerInstance "np:\\.\pipe\MICROSOFT##WID\tsql\query" -Database "SUSDB" -Encrypt Optional
# Vérification et affichage des résultats
if ($result) {
Write-Output "TargetID: $($result.TargetID)"
Write-Output "ComputerID: $($result.ComputerID)"
try{
# Préparation de la requête pour supprimer l'entrée
$queryDeletion = @"
DELETE FROM [SUSDB].[dbo].[tbComputerTarget] WHERE ComputerID = '$($result.ComputerID)'
"@
# Exécution de la requête de suppression
Invoke-Sqlcmd -Query $queryDeletion -ServerInstance "np:\\.\pipe\MICROSOFT##WID\tsql\query" -Database "SUSDB" -Encrypt Optional
Write-Output "Entrée supprimée pour l'ordinateur: $($FullDomainName)"
}
catch{
Write-Output $_.Exception.Message
}
} else {
Write-Output "Aucun enregistrement trouvé pour $FullDomainName"
}
}
复制此脚本时请注意,脚本中的“@”必须保留在左边距,不要使用制表将其与代码的其余部分对齐。
我不知道我是否处于最佳实践,但它的效果就像我想要的:)