powershell 修复损坏的WU DataStore。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了powershell 修复损坏的WU DataStore。相关的知识,希望对你有一定的参考价值。

<#
.SYNOPSIS
    Repairs a corrupted WU DataStore.
.DESCRIPTION
    Detects and repairs a corrupted WU DataStore.
    Detection is done by testing the eventlog with the specified parameters.
    Repairs are performed by removing and reinitializing the corrupted DataStore.
    The specified eventlog is backed up and cleared in order not to triger the detection again before the repair step.
    The backup of the specified eventlog is stored in 'SystemRoot\Temp' folder.
    Defaults are configured for the ESENT '623' error.
.PARAMETER Action
    Specifies the action to be performed. Available actions are: ('DetectAndRepair', 'Detect', 'Repair','RepairStandalone').
    'DetectAndRepair'  - Performs detection and then performs repairs if necessary.
    'Detect'           - Performs detection and returns the result.
    'Repair'           - Performs repairs and flushes the specified EventLog.
    'RepairStandalone' - Performs repairs only.
.PARAMETER LogName
    Specifies the LogName to search. Default is: 'Application'
.PARAMETER Source
    Specifies the Source to search. Default is: 'ESENT'
.PARAMETER EventID
    Specifies the EventID to search. Default is: '623'
.PARAMETER EntryType
    Specifies the Entry Type to search. Available options are: ('Information','Warning','Error'). Default is: 'Error'.
.PARAMETER LimitDays
    Specifies the number of days from the current date to limit the search to. Default is: 3.
.PARAMETER Threshold
    Specifed the numbers of events after which this functions returns $true. Default is: 3.
.EXAMPLE
    Repair-WUDataStore.ps1 -Action 'Detect' -LogName 'Application' -Source 'ESENT' -EventID '623' -EntryType 'Error' -LimitDays 3 -Threshold 3
.INPUTS
    System.String.
.OUTPUTS
    System.String. This script returns Compliant, Non-Compliant, Remediated or Error Message
.NOTES
    Created by Ioan Popovici
    This script can be called directly.
.LINK
    https://SCCM.Zone/Repair-WUDataStore
.LINK
    https://SCCM.Zone/Repair-WUDataStore-CHANGELOG
.LINK
    https://SCCM.Zone/Repair-WUDataStore-GIT
.LINK
    https://SCCM.Zone/Issues
.COMPONENT
    WindowsUpdate
.FUNCTIONALITY
    Repair
#>

## Set script requirements
#Requires -Version 3.0

##*=============================================
##* VARIABLE DECLARATION
##*=============================================
#region VariableDeclaration

## Get script parameters
Param (
    [Parameter(Mandatory=$true,Position=0)]
    [ValidateNotNullorEmpty()]
    [ValidateSet('DetectAndRepair','Detect','Repair','RepairStandalone')]
    [string]$Action,
    [Parameter(Mandatory=$false,Position=1)]
    [ValidateNotNullorEmpty()]
    [string]$LogName = 'Application',
    [Parameter(Mandatory=$false,Position=2)]
    [ValidateNotNullorEmpty()]
    [string]$Source = 'ESENT',
    [Parameter(Mandatory=$false,Position=3)]
    [ValidateNotNullorEmpty()]
    [string]$EventID = '623' ,
    [Parameter(Mandatory=$false,Position=4)]
    [ValidateNotNullorEmpty()]
    [string]$EntryType = 'Error',
    [Parameter(Mandatory=$false,Position=5)]
    [ValidateNotNullorEmpty()]
    [int]$LimitDays = 3,
    [Parameter(Mandatory=$false,Position=6)]
    [ValidateNotNullorEmpty()]
    [int]$Threshold = 3
)

#endregion
##*=============================================
##* END VARIABLE DECLARATION
##*=============================================

##*=============================================
##* FUNCTION LISTINGS
##*=============================================
#region FunctionListings

#region Function Test-EventLogCompliance
Function Test-EventLogCompliance {
<#
.SYNOPSIS
    Tests the EventLog compliance for specific events.
.DESCRIPTION
    Tests the EventLog compliance by getting events and returing a Non-Compliant statement after a specified treshold is reached.
.PARAMETER LogName
    Specifies the LogName to search.
.PARAMETER Source
    Specifies the Source to search.
.PARAMETER EventID
    Specifies the EventID to search.
.PARAMETER EntryType
    Specifies the Entry Type to search. Available options are: ('Information','Warning','Error'). Default is: 'Error'.
.PARAMETER LimitDays
    Specifies the number of days from the current date to limit the search to.
    Default is: 1.
.PARAMETER Threshold
    Specifed the numbers of events after which this functions returns $true.
.EXAMPLE
    Test-EventLogCompliance -LogName 'Application' -Source 'ESENT' -EventID '623' -EntryType 'Error' -LimitDays 3 -Threshold 3
.INPUTS
    None.
.OUTPUTS
    System.Boolean.
.NOTES
    This function can typically be called directly.
.LINK
    https://SCCM.Zone
.LINK
    https://SCCM.Zone/Git
.COMPONENT
    WindowsUpdate
.FUNCTIONALITY
    Test
#>
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory=$true,Position=0)]
        [ValidateNotNullorEmpty()]
        [string]$LogName,
        [Parameter(Mandatory=$true,Position=1)]
        [ValidateNotNullorEmpty()]
        [string]$Source,
        [Parameter(Mandatory=$true,Position=2)]
        [ValidateNotNullorEmpty()]
        [string]$EventID,
        [Parameter(Mandatory=$false,Position=3)]
        [ValidateSet('Information','Warning','Error')]
        [string]$EntryType = 'Error',
        [Parameter(Mandatory=$false,Position=4)]
        [ValidateNotNullorEmpty()]
        [int]$LimitDays = 1,
        [Parameter(Mandatory=$true,Position=5)]
        [ValidateNotNullorEmpty()]
        [int]$Threshold
    )

    Try {

        ## Set day limit by substracting number of days from the current date
        $After = $((Get-Date).AddDays( - $LimitDays ))

        ## Get events and test treshold
        $Events = Get-EventLog -ComputerName $env:COMPUTERNAME -LogName $LogName -Source $Source -EntryType $EntryType -After $After -ErrorAction 'Stop' | Where-Object { $_.EventID -eq $EventID }

        If ($Events.Count -ge $Threshold) {
            $Compliance = 'Non-Compliant'
        }
        Else {
            $Compliance = 'Compliant'
        }
    }
    Catch {

        ## Set result as 'Compliant' if no matches are found
        If ($($_.Exception.Message) -match 'No matches found') {
            $Compliance =  'Compliant'
        }
        Else {
            $Compliance = "Eventlog [$EventLog] compliance test error. $($_.Exception.Message)"
        }
    }
    Finally {

        ## Return Compliance result
        Write-Output -InputObject $Compliance
    }
}
#endregion

#region Function Backup-EventLog
Function Backup-EventLog {
<#
.SYNOPSIS
    Backs-up an Event Log.
.DESCRIPTION
    Backs-up an Event Log using the BackUpEventLog Cim method.
.PARAMETER LogName
    Specifies the event log to backup.
.PARAMETER BackupPath
    Specifies the Backup Path. Default is: '$Env:SystemRoot\Temp'.
.PARAMETER BackupName
    Specifies the Backup name. Default is: 'yyyy-MM-dd_HH-mm-ss_$Env:ComputerName_$LogName'.
.EXAMPLE
    Backup-EventLog -LogName 'Application' -BackupPath 'C:\SCCMZone' -BackupName '1980-09-09_10-10-00_SCCMZoneBlog_Application'
.INPUTS
    System.String.
.OUTPUTS
    None. This function has no outputs.
.NOTES
    This function can typically be called directly.
.LINK
    https://SCCM.Zone
.LINK
    https://SCCM.Zone/Git
.COMPONENT
    EventLog
.FUNCTIONALITY
    Backup
#>
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory=$true,Position=0)]
        [ValidateNotNullorEmpty()]
        [string]$LogName,
        [Parameter(Mandatory=$false,Position=1)]
        [ValidateNotNullorEmpty()]
        [string]$BackupPath,
        [Parameter(Mandatory=$false,Position=2)]
        [ValidateNotNullorEmpty()]
        [string]$BackupName
    )

    Begin {

        ## Setting variables
        [int]$PowerShellVersion = $PSVersionTable.PSVersion.Major
        [datetime]$Date = $(Get-Date -f 'yyyy-MM-dd_HH-mm-ss')
        #  Setting optional parameters
        If (-not $BackupPath) {
            $BackupPath = $(Join-Path -Path $Env:SystemRoot -ChildPath '\Temp')
        }
        If (-not $BackupFileName) {
            [string]$BackUpFileName = "{0}_{1}_{2}.evtx" -f $Date, $Env:COMPUTERNAME, $LogName
        }
        #  Setting backup arguments
        [hashtable]$BackupArguments = @{ ArchiveFileName = (Join-Path -Path $BackupPath -ChildPath $BackUpFileName) }
    }
    Process {
        Try {

            If ($PowerShellVersion -eq 2) {
                ## Get event log
                $EventLog = Get-WmiObject -Class 'Win32_NtEventLogFile' -Filter "LogFileName = '$LogName'" -ErrorAction 'SilentlyContinue'

                If (-not $EventLog) {
                    Throw 'EventLog not found.'
                }

                ## Backup event log
                $BackUp = $EventLog | Invoke-WmiMethod -Name 'BackupEventLog' -ArgumentList $BackupArguments -ErrorAction 'SilentlyContinue'

                If ($BackUp.ReturnValue -ne 0) {
                    Throw "Backup retuned $($BackUp.ReturnValue)."
                }
            }
            ElseIf ($PowerShellVersion -ge 3) {
                ## Get event log
                $EventLog = Get-CimInstance -ClassName 'Win32_NtEventLogFile' -Filter "LogFileName = '$LogName'" -ErrorAction 'SilentlyContinue'

                If (-not $EventLog) {
                    Throw 'EventLog not found.'
                }

                ## Backup event log
                $BackUp = $EventLog | Invoke-CimMethod -Name 'BackupEventLog' -Arguments $BackupArguments -ErrorAction 'SilentlyContinue'

                If ($BackUp.ReturnValue -ne 0) {
                    Throw "Backup retuned $($BackUp.ReturnValue)."
                }
            }
            Else {
                Throw "PowerShell version [$PowerShellVersion] not supported."
            }
        }
        Catch {
            Write-Output -InputObject "Backup EventLog [$LogName] error. $_"
        }
    }
    End {
    }
}
#endregion

#region Function Repair-WUDataStore
Function Repair-WUDataStore {
<#
.SYNOPSIS
    Repairs a corrupted WU DataStore.
.DESCRIPTION
    Repairs a corrupted WU DataStore by removing and reinitializing the corrupted DataStore.
.EXAMPLE
    Repair-WUDataStore
.INPUTS
    None. This function has no inputs.
.OUTPUTS
    None. This function has no outputs.
.NOTES
    This function can typically be called directly.
.LINK
    https://SCCM.Zone
.LINK
    https://SCCM.Zone/Git
.COMPONENT
    WindowsUpdate
.FUNCTIONALITY
    Repair
#>

    Try {

        #  Setting Paths
        [string]$PathRegsvr = (Join-Path -Path $Env:SystemRoot -ChildPath '\System32\Regsvr32.exe')
        [string]$PathDataStore = (Join-Path -Path $Env:SystemRoot -ChildPath '\SoftwareDistribution\DataStore')

        ## Re-register wuauend.dll
        $null = Start-Process -FilePath $PathRegsvr -ArgumentList '/s Wuaueng.dll' -Wait -ErrorAction 'SilentlyContinue'

        ## Stop the windows update service
        $null = Stop-Service -Name 'wuauserv' -Force -ErrorAction 'SilentlyContinue'

        ## Wait for the windows update service to stop
        #  Setting Loop index to 12 (one minute)
        [int]$Loop = 1
        While ($StatusWuaService -ne 'Stopped') {

            #  Waiting 10 seconds
            $null = Start-Sleep -Seconds 10

            #  Get windows update service status
            [string]$StatusWuaService =  (Get-Service -Name 'wuauserv').Status

            #  Try to kill process if service has not stopped within 4 minutes
            If ($Loop -eq 24) {

                #  Use powershell legacy
                If ($PowerShellVersion -eq 2) {
                    #  Get update service PID
                    [string]$PID = Get-WmiObject -Class 'Win32_Service' -Filter "Name = 'wuauserv'" | Select-Object -ExpandProperty 'ProcessId' -ErrorAction 'SilentlyContinue'
                    #  Kill process if PID is found
                    If ($PID -and $PID -ne '0') {
                        Start-Process -FilePath 'taskkill.exe' -ArgumentList "/f /pid $PID" -Wait -ErrorAction 'SilentlyContinue'
                    }
                }

                #  Use current powershell
                ElseIf ($PowerShellVersion -ge 3) {
                    #  Get update service PID
                    [string]$PID = Get-CimInstance -ClassName 'Win32_Service' -Filter "Name = 'wuauserv'" | Select-Object -ExpandProperty 'ProcessId' -ErrorAction 'SilentlyContinue'
                    #  Kill process if PID is found
                    If ($PID -and $PID -ne '0') {
                        Stop-Process -ID $PID -Force -ErrorAction 'SilentlyContinue'
                    }
                }
            }

            #  Throw error if service has not stopped within 5 minutes
            If ($Loop -ge 30) {
                Throw 'Failed to stop WuaService within 5 minutes.'
            }

            #  Incrementing loop index
            $Loop++
        }

        ## Remove the Windows update DataStore
        Remove-Item -Path $PathDataStore -Recurse -Force -ErrorAction 'Stop' | Out-Null

        ## Start the windows update service
        Start-Service -Name 'wuauserv' -ErrorAction 'SilentlyContinue'

        ## Set result to 'Remediated'
        [string]$RepairWuDatastore = 'Remediated'
    }
    Catch {
        [string]$RepairWuDatastore = "WUDataStore repair error. $($_.Exception.Message)"
    }
    Finally {

        ## Return result
        Write-Output -InputObject $RepairWuDatastore
    }
}
#endregion

#endregion
##*=============================================
##* END FUNCTION LISTINGS
##*=============================================

##*=============================================
##* SCRIPT BODY
##*=============================================
#region ScriptBody

Switch ($Action) {
    'DetectAndRepair' {

        ## Get machine compliance
        [string]$ESENTError623 = Test-EventLogCompliance -LogName $LogName -Source $Source -EventID $EventID -EntryType $EntryType -LimitDays $LimitDays -Threshold $Threshold

        ## Start processing if compliance test returns 'Non-Compliant'
        If ($ESENTError623 -eq 'Non-Compliant') {

            #  Backup EventLog
            $null = Backup-EventLog -LogName $LogName -ErrorAction 'SilentlyContinue'

            Try {

                #  Clear EventLog
                $null = Clear-EventLog -LogName $LogName -ErrorAction 'Stop'

                #  Repair DataStore if clear eventlog is succesful
                Repair-WUDataStore
            }
            Catch {
                Write-Output -InputObject "No repair possible. Clear EventLog [$LogName] error. $($_.Exception.Message)"
            }
        }
        Else {
            Write-Output -InputObject $ESENTError623
        }
    }
    'Detect' {

        ## Get machine compliance and return it
        [string]$ESENTError623 = Test-EventLogCompliance -LogName $LogName -Source $Source -EventID $EventID -EntryType $EntryType -LimitDays $LimitDays -Threshold $Threshold
        Write-Output -InputObject $ESENTError623
    }
    'Repair' {

        ## Backup EventLog
        $null = Backup-EventLog -LogName $LogName -ErrorAction 'SilentlyContinue'

        Try {

            ## Clear EventLog
            $null = Clear-EventLog -LogName $LogName -ErrorAction 'Stop'

            ##  Repair DataStore if clear eventlog is succesful
            Repair-WUDataStore
        }
        Catch {
            Write-Output -InputObject "No repair possible. Clear EventLog [$LogName] error. $($_.Exception.Message)"
        }
    }
    'RepairStandalone' {

        ##  Repair DataStore
        Repair-WUDataStore -ErrorAction 'SilentlyContinue'
    }
}

#endregion
##*=============================================
##* END SCRIPT BODY
##*=============================================

以上是关于powershell 修复损坏的WU DataStore。的主要内容,如果未能解决你的问题,请参考以下文章

怎样修复损坏了的innodb 表

XFS 分区损坏修复方法

如何修复损坏的MySQL数据表

xlsx文件损坏如何修复(xls文件损坏怎么修复)

怎样修复已经损坏的SQL数据库?

大神们很急,这个PPT文档损坏了怎么弄 WPS里修复不好使