Powershell Script zum manuellen entfernen von Treibern aus dem Driver Store
Immer wieder muss ich einen fehlerhaften Treiber aus dem System entfernen ohne dass dieser installiert ist, oder im Device Manager auftaucht.
Meist sind es Treiber die einen Bluescreen verursachen könnten wenn sie geladen werden.
Die Treiber sind allerdings mit Administrator Rechten geschützt, die man vorher entfernen muss.
Das ganze händisch über den Explorer zu machen ist sehr mühselig, deshalb habe ich dafür ein kleine Script zusammengestellt, dass das für mich automatisiert:
# Target Driver to remove
$Drivers = Get-ChildItem C:\Windows\System32\DriverStore\FileRepository\ExampleDriver*
Function Remove-File
{
Param(
[String]$File
)
[Int]$Global:AccessAllowed = 0x00000000
[Int]$Global:AccessDenied = 0x00000001
[Int]$Global:AccessAudit = 0x00000002
[Int]$Global:SeOwnerDefaulted = 0x00000001
[Int]$Global:SeGroupDefaulted = 0x00000002
[Int]$Global:SeDaclPresent = 0x00000004
[Int]$Global:SeDaclDefaulted = 0x00000008
[Int]$Global:SeSaclPresent = 0x00000010
[Int]$Global:SeSaclDefaulted = 0x00000020
[Int]$Global:SeDaclAutoInheritReq = 0x00000100
[Int]$Global:SeSaclAutoInheritReq = 0x00000200
[Int]$Global:SeDaclAutoInherited = 0x00000400
[Int]$Global:SeSaclAutoInherited = 0x00000800
[Int]$Global:SeDaclProtected = 0x00001000
[Int]$Global:SeSaclProtected = 0x00004000
[Int]$Global:SeSelfRelative = 0x00008000
[Int]$Global:ObjectInheritAce = 0x00000001
[Int]$Global:ContainerInheritAce = 0x00000002
[Int]$Global:NoPropagateInheritAce = 0x00000004
[Int]$Global:InheritOnlyAce = 0x00000008
[Int]$Global:InheritedAce = 0x00000010
[Int]$Global:SuccessfulAccessAceFlag = 0x00000040
[Int]$Global:FailedAccessAceFlag = 0x00000080
[Int]$Global:FileReadData = 0x00000001
[Int]$Global:FileListDirectory = 0x00000001
[Int]$Global:FileWriteData = 0x00000002
[Int]$Global:FileAddFile = 0x00000002
[Int]$Global:FileAppendData = 0x00000004
[Int]$Global:FileAddSubdirectory = 0x00000004
[Int]$Global:FileReadEa = 0x00000008
[Int]$Global:FileWriteEa = 0x00000010
[Int]$Global:FileExecute = 0x00000020
[Int]$Global:FileTraverse = 0x00000020
[Int]$Global:FileDeleteChild = 0x00000040
[Int]$Global:FileReadAttributes = 0x00000080
[Int]$Global:FileWriteAttributes = 0x00000100
[Int]$Global:Delete = 0x00010000
[Int]$Global:ReadControl = 0x00020000
[Int]$Global:WriteDAC = 0x00040000
[Int]$Global:WriteOwner = 0x00080000
[Int]$Global:Synchronize = 0x00100000
Function New-RecoveryFileOwner(){
Param(
[Parameter(Mandatory=$True)]
[System.Management.ManagementBaseObject]$SecurityDescriptor = $NULL,
[Parameter(Mandatory=$True)]
[System.String]$Domain = '',
[Parameter(Mandatory=$True)]
[System.String]$Name = ''
)
[System.Management.ManagementBaseObject]$TrusteeOld = $NULL
[System.Management.ManagementBaseObject]$TrusteeNew = $NULL
[System.Management.ManagementBaseObject]$AccountNew = $NULL
[System.Management.ManagementBaseObject]$SidNew = $NULL
$TrusteeNew = (New-Object -TypeName System.Management.ManagementClass -ArgumentList 'Win32_Trustee' -ErrorAction Stop).CreateInstance()
$AccountNew = Get-WmiObject -Class 'Win32_Account' -Filter "Name = '$Name' And Domain = '$Domain'" -ErrorAction Stop
$SidNew = New-Object -TypeName System.Management.ManagementObject -ArgumentList "Win32_SID.SID='$($AccountNew.SID)'"
$TrusteeNew.Domain = $SidNew.ReferencedDomainName
$TrusteeNew.Name = $SidNew.AccountName
$TrusteeNew.SID = $SidNew.BinaryRepresentation
$TrusteeNew.SIDLength = $SidNew.SIDLength
$TrusteeNew.SIDString = $SidNew.SID
return $TrusteeNew
}
Function New-RecoveryFileAce(){
Param(
[Parameter(Mandatory=$True)]
[System.Management.ManagementBaseObject]$Trustee = $NULL
)
[System.Management.ManagementBaseObject]$AceNew = $NULL
$AceNew = (New-Object -TypeName System.Management.ManagementClass -ArgumentList 'Win32_ACE' -ErrorAction Stop).CreateInstance()
$AceNew.AccessMask = ($Global:FileReadData -bOr
$Global:FileListDirectory -bOr
$Global:FileWriteData -bOr
$Global:FileAddFile -bOr
$Global:FileAppendData -bOr
$Global:FileAddSubdirectory -bOr
$Global:FileReadEa -bOr
$Global:FileWriteEa -bOr
$Global:FileExecute -bOr
$Global:FileTraverse -bOr
$Global:FileDeleteChild -bOr
$Global:FileReadAttributes -bOr
$Global:FileWriteAttributes -bOr
$Global:Delete -bOr
$Global:ReadControl -bOr
$Global:WriteDAC -bOr
$Global:WriteOwner -bOr
$Global:Synchronize)
$AceNew.AceFlags = 0
$AceNew.AceType = $Global:AccessAllowed
$AceNew.GuidInheritedObjectType = ''
$AceNew.GuidObjectType = ''
$AceNew.Trustee = $TrusteeNew
return $AceNew
}
[String]$Location = ''
[String]$Domain = ''
[String]$Name = ''
[System.Management.ManagementObject]$LogicalFileSecuritySetting = $NULL
[System.Management.ManagementBaseObject]$SecurityDescriptorOld = $NULL
[System.Management.ManagementBaseObject]$SecurityDescriptorNew = $NULL
[System.Management.ManagementBaseObject]$TrusteeOld = $NULL
[System.Management.ManagementBaseObject]$TrusteeNew = $NULL
[System.Management.ManagementBaseObject]$AceNew = $NULL
$File = $File.Replace('\','\\')
$Domain = (([System.Security.Principal.WindowsIdentity]::GetCurrent()).Name).Split('\')[0]
$Name = (([System.Security.Principal.WindowsIdentity]::GetCurrent()).Name).Split('\')[1]
$SecurityDescriptorOld = (New-Object -TypeName System.Management.ManagementClass -ArgumentList 'Win32_SecurityDescriptor' -ErrorAction Stop).CreateInstance()
$SecurityDescriptorNew = (New-Object -TypeName System.Management.ManagementClass -ArgumentList 'Win32_SecurityDescriptor' -ErrorAction Stop).CreateInstance()
$LogicalFileSecuritySetting = Get-WmiObject -Class 'Win32_LogicalFileSecuritySetting' -Filter "Path='$File'" -EnableAllPrivileges
$SecurityDescriptorOld = ($LogicalFileSecuritySetting.GetSecurityDescriptor()).Descriptor
$TrusteeOld = $SecurityDescriptorOld.Owner
$TrusteeNew = New-RecoveryFileOwner -SecurityDescriptor $SecurityDescriptorOld -Domain $Domain -Name $Name
$SecurityDescriptorNew.ControlFlags = 0
$SecurityDescriptorNew.Owner = $TrusteeNew
$SecurityDescriptorNew.Group = $NULL
$SecurityDescriptorNew.DACL = $NULL
$SecurityDescriptorNew.SACL = $NULL
$LogicalFileSecuritySetting.SetSecurityDescriptor($SecurityDescriptorNew)
$AceNew = New-RecoveryFileAce -Trustee $TrusteeNew
$SecurityDescriptorNew.ControlFlags = $Global:SeDaclPresent
$SecurityDescriptorNew.Owner = $NULL
$SecurityDescriptorNew.Group = $NULL
$SecurityDescriptorNew.DACL = @($AceNew)
$SecurityDescriptorNew.SACL = $NULL
$LogicalFileSecuritySetting.SetSecurityDescriptor($SecurityDescriptorNew)
Remove-Item -Path $File -Force -Recurse -ErrorAction Stop
}
foreach($Driver in $Drivers)
{
Remove-File $Driver.FullName
}