powershell 修复脱机服务期间遇到的错误0x800f082f。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了powershell 修复脱机服务期间遇到的错误0x800f082f。相关的知识,希望对你有一定的参考价值。
<#
.SYNOPSIS
Repairs error 0x800f082f~ encountered during offline servicing.
.DESCRIPTION
Repairs error 0x800f082f~ encountered during offline servicing by setting the
HKLM:\Microsoft\Windows\CurrentVersion\Component Based Servicing\SessionsPending\Exclusive value to 0.
.INPUTS
None.
.OUTPUTS
None.
.EXAMPLE
Repair-ServicingError_800f082f.ps1
.NOTES
Created by Ioan Popovici
Requirements
ADK Windows 10, Windows 8 or higher.
.LINK
https://SCCM.Zone/Update-OfflineWindowsImage
.LINK
https://SCCM.Zone/Repair-ServicingError_800f082f-CHANGELOG
.LINK
https://SCCM.Zone/Repair-ServicingError_800f082f-GIT
.LINK
https://SCCM.Zone/Issues
.COMPONENT
Windows Servicing
.FUNCTIONALITY
Repairs servicing error 0x800f082f~
#>
## Set script requirements
#Requires -Version 3.0
##*=============================================
##* VARIABLE DECLARATION
##*=============================================
#region VariableDeclaration
## Get script path and name
[String]$ScriptPath = [System.IO.Path]::GetDirectoryName($MyInvocation.MyCommand.Definition)
[String]$ScriptName = [System.IO.Path]::GetFileNameWithoutExtension($MyInvocation.MyCommand.Definition)
## Set Paths and Image Index
[String]$MountPath = (Join-Path -Path $ScriptPath -ChildPath '\Mount')
[String]$MountHivePath = (Join-Path -Path $MountPath -ChildPath '\Windows\System32\Config\Software')
[String]$MountHiveKey = 'HKLM:\EXTERNAL\Microsoft\Windows\CurrentVersion\Component Based Servicing\SessionsPending'
[String]$ScratchPath = (Join-Path -Path $ScriptPath -ChildPath '\Scratch')
[String]$LogPath = (Join-Path -Path $ScriptPath -ChildPath 'DISM.log')
## Set Environment Path in order to use the latest DISM and System32. This is set for current session only, no need to remove it afterwards.
$Env:Path = 'C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\DISM;C:\Windows\System32'
#endregion
##*=============================================
##* END VARIABLE DECLARATION
##*=============================================
#endregion
##*=============================================
##* FUNCTION LISTINGS
##*=============================================
#region FunctionListings
#region Function Enable-Privilege
Function Enable-Privilege {
<#
.SYNOPSIS
Enables privileges in a specified access token.
.DESCRIPTION
Enables privileges in a specified access token.
.PARAMETER Privilege
The Privilege to inject, valid options are:
"SeAssignPrimaryTokenPrivilege", "SeAuditPrivilege", "SeBackupPrivilege", "SeChangeNotifyPrivilege", "SeCreateGlobalPrivilege",
"SeCreatePagefilePrivilege", "SeCreatePermanentPrivilege", "SeCreateSymbolicLinkPrivilege", "SeCreateTokenPrivilege",
"SeDebugPrivilege", "SeEnableDelegationPrivilege", "SeImpersonatePrivilege", "SeIncreaseBasePriorityPrivilege",
"SeIncreaseQuotaPrivilege", "SeIncreaseWorkingSetPrivilege", "SeLoadDriverPrivilege","SeLockMemoryPrivilege",
"SeMachineAccountPrivilege", "SeManageVolumePrivilege", "SeProfileSingleProcessPrivilege", "SeRelabelPrivilege",
"SeRemoteShutdownPrivilege", "SeRestorePrivilege", "SeSecurityPrivilege", "SeShutdownPrivilege", "SeSyncAgentPrivilege",
"SeSystemEnvironmentPrivilege", "SeSystemProfilePrivilege", "SeSystemtimePrivilege", "SeTakeOwnershipPrivilege",
"SeTcbPrivilege", "SeTimeZonePrivilege", "SeTrustedCredManAccessPrivilege", "SeUndockPrivilege", "SeUnsolicitedInputPrivilege"
.EXAMPLE
Enable-Privilege -Privilege SeTakeOwnershipPrivilege
.NOTES
This is an internal script function and should typically not be called directly.
.LINK
Credit to Pasquale Lantella:
https://gallery.technet.microsoft.com/Adjusting-Token-Privileges-9b6724fc
#>
Param (
[Parameter(Mandatory=$true,Position=0)]
[Alias('Pr')]
[Array]$Privilege
)
$Definition = @'
using System;
using System.Runtime.InteropServices;
public class AdjPriv {
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr rele);
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);
[DllImport("advapi32.dll", SetLastError = true)]
internal static extern bool LookupPrivilegeValue(string host, string name,
ref long pluid);
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct TokPriv1Luid {
public int Count;
public long Luid;
public int Attr;
}
internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
internal const int TOKEN_QUERY = 0x00000008;
internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
public static bool EnablePrivilege(long processHandle, string privilege) {
bool retVal;
TokPriv1Luid tp;
IntPtr hproc = new IntPtr(processHandle);
IntPtr htok = IntPtr.Zero;
retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
tp.Count = 1;
tp.Luid = 0;
tp.Attr = SE_PRIVILEGE_ENABLED;
retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
return retVal;
}
}
'@
## Get process pandle
$ProcessHandle = (Get-Process -id $pid).Handle
$type = Add-Type $Definition -PassThru
## Inject token
$type[0]::EnablePrivilege($processHandle, $Privilege)
}
#endregion
#endregion
##*=============================================
##* END FUNCTION LISTINGS
##*=============================================
##*=============================================
##* SCRIPT BODY
##*=============================================
#region ScriptBody
## Create Mount directory if it does not exist
If ((Test-Path $MountPath) -eq $False) {
New-Item -Path $MountPath -Type Directory | Out-Null
}
## Create Scratch directory if it does not exist
If ((Test-Path $ScratchPath) -eq $False) {
New-Item -Path $ScratchPath -Type Directory | Out-Null
}
## Check for images
$CheckForImages = Get-ChildItem -Path $ScriptPath -Filter '*.wim'
If (-not $CheckForImages) { Write-Error -Message 'Image not found! Script must be in the same folder as the image.' -ErrorAction 'Stop' }
## Prompt for WIM to service, don't allow null input
Do {
[Array]$ImageFileInfo = Get-ChildItem -Path $ScriptPath -Filter '*.wim' | Select-Object -Property `
@{Label='Name';Expression={($_.Name)}},
@{Label='Size (GB)';Expression={'{0:N2}' -f ($_.Length / 1GB)}},
@{Label='Path';Expression={($_.FullName)}} | Out-GridView -PassThru -Title 'Choose image to service. Do not use multiple selection!'
}
While ($ImageFileInfo.Length -eq 0)
# Set image file name and path, process only the first selection
[String]$ImageFile = ($ImageFileInfo | Select-Object -First 1).Name
[String]$ImagePath = ($ImageFileInfo | Select-Object -First 1).Path
## Prompt for windows version, don't allow null input
Do {
[Array]$ImageIndexInfo = Get-WindowsImage -ImagePath $ImagePath | Select-Object -First 1 -Property `
@{Label='Index';Expression={($_.ImageIndex)}},
@{Label='Name';Expression={($_.ImageName)}},
@{Label='Description';Expression={($_.ImageDescription)}},
@{Label='Size (GB)';Expression={'{0:N2}' -f ($_.ImageSize / 1GB)}} | Out-GridView -PassThru -Title 'Choose Windows version. Do not use multiple selection!'
}
While ($ImageIndexInfo.Length -eq 0)
# Set image name and index, process only the first selection
[String]$ImageName = ($ImageIndexInfo | Select-Object -First 1).Name
[Int]$ImageIndex = ($ImageIndexInfo | Select-Object -First 1).Index
## Set Backup path and Backup WIM file
[String]$BackupImagePath = ($ImagePath -replace '.{3}$')+'bkp'
Write-Host "`n`n`n`n`n`nBacking up $ImagePath to $BackupImagePath ..." -ForegroundColor 'Yellow' -BackgroundColor 'Black'
$Operation = Copy-Item -Path $ImagePath -Destination $BackupImagePath -Force
## Mount WIM
Write-Host "`nMounting Image..." -ForegroundColor 'Yellow' -BackgroundColor 'Black'
$Operation = Mount-WindowsImage -ImagePath $ImagePath -Index $ImageIndex -Path $MountPath -ScratchDirectory $ScratchPath -LogPath $LogPaths
# Display mounted image status
$Operation = Get-WindowsImage -Mounted -ScratchDirectory $ScratchPath -LogPath $LogPath | Out-String
Write-Host "`nMounted Image Info:`n $Operation" -ForegroundColor 'Yellow' -BackgroundColor 'Black'
## Load registry hive
Write-Host "Loading Registry Hive...`n" -ForegroundColor 'Yellow' -BackgroundColor 'Black'
$Operation = Start-Process -FilePath "CMD.EXE" -ArgumentList "/C REG LOAD HKLM\EXTERNAL $MountHivePath" -Wait -WindowStyle Hidden
## Get privileges in order to be able to take ownership of the registry key
Write-Host "Getting Privileges..." -ForegroundColor 'Yellow' -BackgroundColor 'Black'
$Operation = Enable-Privilege -Privilege 'SeTakeOwnershipPrivilege'
If ($Operation) {
Write-Host "Successful!`n" -ForegroundColor 'Yellow' -BackgroundColor 'Black'
}
Else {
Write-Host "Failed!`n" -ForegroundColor 'Red' -BackgroundColor 'Black'
}
# Create new ACL control access rule object
[PsObject]$RegACL = New-Object System.Security.AccessControl.RegistryAccessRule ("Administrators","FullControl","ObjectInherit,ContainerInherit","None","Allow")
# Set the registry key owner variable
[PsObject]$RegOwner = [System.Security.Principal.NTAccount]"Administrators"
# Open key with Read/Write and Take Ownership privileges
[PsObject]$RegKeyCR = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey(
"EXTERNAL\Microsoft\Windows\CurrentVersion\Component Based Servicing\SessionsPending",[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::TakeOwnership
)
# Get a blank ACL since we don't have access
$ACLCR = $RegKeyCR.GetAccessControl([System.Security.AccessControl.AccessControlSections]::None)
# Create owner control access rule
$ACLCR.SetOwner($RegOwner)
# Set Owner using owner control access rule
$RegKeyCR.SetAccessControl($ACLCR)
# Get the ACL for the registry key now that we have access
$ACLCR = $RegKeyCR.GetAccessControl()
# Create the control access rule for the registry key
$ACLCR.SetAccessRule($RegACL)
# Set the permissions on the registry key using the control access rule
$RegKeyCR.SetAccessControl($ACLCR)
# Closing the handle
$RegKeyCR.Close()
## Set the new registry key value
Write-Host "Setting Exclusive Registry Key Value to 0...`n" -ForegroundColor 'Yellow' -BackgroundColor 'Black'
Set-ItemProperty -Path $MountHiveKey -Name 'Exclusive' -Value '0' | Out-Null
## Run garbage collector so we can safely unload the registry hive
[gc]::collect()
## Unload registry hive
Write-Host "Unloading Registry Hive...`n" -ForegroundColor 'Yellow' -BackgroundColor 'Black'
Start-Process -FilePath "CMD.EXE" -ArgumentList "/C REG UNLOAD HKLM\EXTERNAL" -Wait -WindowStyle Hidden
## Unmount and save servicing changes to the image
Write-Host "`nCommitting Changes and Dismounting Image..." -ForegroundColor 'Yellow' -BackgroundColor 'Black'
$Operation = Dismount-WindowsImage -Path $MountPath -ScratchDirectory $ScratchPath -LogPath $LogPath -Save -CheckIntegrity
## Wait for keypress
Write-Host "Press any key to continue ..."
$WaitforKeyPress = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
#endregion
##*=============================================
##* END SCRIPT BODY
##*=============================================
以上是关于powershell 修复脱机服务期间遇到的错误0x800f082f。的主要内容,如果未能解决你的问题,请参考以下文章
如何在 sql*plus 中修复我的假脱机 csv 文件中的格式
由于“无法初始化PowerShell主机”,无法安装nuget包
如何修复“value null Copy-Item Powershell”错误