├── AnimatePNG ├── Logo.png ├── ShowLogo.exe └── ShowLogo.pdb ├── CIBaseLines ├── Remediate-IsRegistryPOLGood.ps1 └── Test-IsRegistryPOLGood.ps1 ├── Client ├── Fix-MappedDrive20H2Freeze.ps1 ├── Get-CredentialGuardStatus.ps1 ├── Get-InstalledUpdates.ps1 ├── Install-LatestsFUExample.ps1 ├── Set-WifiState.ps1 └── ToggleWifi.gif ├── Create-FireWallRule.ps1 ├── CreateFWRule.png ├── General ├── Brushes-AsParam.ps1 ├── ConvertTo-ScriptBlockWithParamsDemo.ps1 ├── Create-LetterLessSymlink.ps1 ├── Get-RegistryKeyLastWriteTime.ps1 ├── Get-Resolution │ ├── DisplayHelper.ps1 │ └── DisplayHelperWithScale │ │ ├── DisplayHelper.dll │ │ └── DisplayHelperDllWithSetScale.ps1 ├── Get-ThunderboltInfo.ps1 ├── GetOnlCompsWithUserSession.ps1 ├── RunCodeAfterShowDialog │ ├── ShowDialog.ps1 │ ├── assembly │ │ ├── MahApps.Metro.dll │ │ └── System.Windows.Interactivity.dll │ └── bliss.jpg ├── UserSid-Converter.ps1 ├── WaitForDHCP.ps1 └── test-port.ps1 ├── KeyCheck ├── KeyCheck.exe ├── KeyCheck.vshost.exe ├── KeyCheckNoBiosKey.exe ├── MS.ErrorReporting.dll ├── System.Xml.Linq.dll ├── adminui.wqlqueryengine.dll ├── microsoft.configurationmanagement.dll ├── microsoft.configurationmanagement.managementprovider.dll ├── pidgenx.dll.old ├── pidgenx64.dll ├── pidgenx64org.dll ├── pidgenx86.dll ├── pidgenx86org.dll └── pkeys │ ├── 1pkeyconfig.xrm-ms │ ├── 233.xrm-ms │ ├── 5048.xml │ ├── 5112.XML │ ├── 5219.xml │ ├── 5231.2.xml │ ├── 5231.XML │ ├── 5259.xml │ ├── 5270.9 x64.xml │ ├── 5270.9.xml │ ├── 5308.17 x64.xml │ ├── 5308.17.xml │ ├── 5308.60.xml │ ├── 5342.xml │ ├── 5365.8 & 5381.1 & 5384.4.xrm-ms │ ├── 5456.5 x64.xrm-ms │ ├── 5456.5.xrm-ms │ ├── 5472.5.xrm-ms │ ├── 5536 & 5552.xrm-ms │ ├── 5600 & 5728 & 5744.xrm-ms │ ├── 5712.xrm-ms │ ├── 5754.1.xrm-ms │ ├── 5840.xrm-ms │ ├── 6000.xrm-ms │ ├── 6001.xrm-ms │ ├── 6002.xrm-ms │ ├── 6519.xrm-ms │ ├── 6780-6956.xrm-ms │ ├── 6936.xrm-ms │ ├── 7000-7022.xrm-ms │ ├── 7048.xrm-ms │ ├── 7057-7068.xrm-ms │ ├── 7077-7229.xrm-ms │ ├── 7264.xrm-ms │ ├── 7600.xrm-ms │ ├── 7601.xrm-ms │ ├── 9200.xrm-ms │ ├── DELL-DD981F15.XRM-MS │ ├── DELL.xrm-ms │ ├── HP-COMPAQ.xrm-ms │ ├── IBM-LENOVO.xrm-ms │ ├── office14.xrm-ms │ ├── office15.xrm-ms │ ├── pkeyconfig-1.xrm-ms │ ├── pkeyconfig-2.xrm-ms │ └── pkeyconfig-3.xrm-ms ├── OSD ├── Add-BCToLocalWim.ps1 ├── Add-BCToLocalWimWIP.ps1 ├── Download-AppxFromStore.ps1 ├── Download-AppxFromStoreNew.ps1 ├── Get-WiredConnections.ps1 ├── GetStoreURL.ps1 ├── GetStoreURLBeta.png ├── GetStoreURLBeta.ps1 ├── Trigger-HiddenTS.ps1 └── Wrapper.ps1 ├── README.md ├── ScriptUserWrapperPOC ├── Invoke-SCCMScriptUserTarget.ps1 ├── UserWrapper.gif ├── UserWrapper.ps1 └── msgbox3.ps1 └── WindowsUpdate ├── Reset-UpdateStore.ps1 └── Update-AndRestart.ps1 /AnimatePNG/Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/AnimatePNG/Logo.png -------------------------------------------------------------------------------- /AnimatePNG/ShowLogo.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/AnimatePNG/ShowLogo.exe -------------------------------------------------------------------------------- /AnimatePNG/ShowLogo.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/AnimatePNG/ShowLogo.pdb -------------------------------------------------------------------------------- /CIBaseLines/Remediate-IsRegistryPOLGood.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Check for local Policy corruption issue 4 | 5 | .DESCRIPTION 6 | Checks the local policy files for corruption 7 | 8 | #> 9 | 10 | #Main Function which checks the policy files for corruption 11 | Function Test-IsRegistryPOLGood 12 | { 13 | $PathToMachineRegistryPOLFile = "$ENV:Windir\System32\GroupPolicy\Machine\Registry.pol" 14 | $PathToUserRegistryPOLFile = "$ENV:Windir\System32\GroupPolicy\User\Registry.pol" 15 | 16 | 17 | # Test for a Machine policy file - if there isn't one - all good 18 | if(!(Test-Path -Path $PathToMachineRegistryPOLFile -PathType Leaf)) {} 19 | #If there is a .pol file - test it 20 | else{ 21 | try 22 | { 23 | If (((Get-Content -Encoding Byte -Path $PathToMachineRegistryPOLFile -TotalCount 4 -ErrorAction Stop) -join '') -ne '8082101103') 24 | { 25 | try 26 | { 27 | #Delete it, if it's corrupted it is useless anyway 28 | Remove-Item $PathToMachineRegistryPOLFile -Force -ErrorAction Stop 29 | } 30 | catch 31 | { 32 | return $false 33 | } 34 | } 35 | 36 | } 37 | catch 38 | { 39 | return $false 40 | } 41 | } 42 | 43 | # Test for a User policy file - if there isn't one - as you were 44 | if(!(Test-Path -Path $PathToUserRegistryPOLFile -PathType Leaf)) {} 45 | #If there is a .pol file - test it 46 | else { 47 | try 48 | { 49 | If (((Get-Content -Encoding Byte -Path $PathToUserRegistryPOLFile -TotalCount 4 -ErrorAction Stop) -join '') -ne '8082101103') 50 | { 51 | try 52 | { 53 | #Delete it, if it's corrupted it is useless anyway 54 | Remove-Item $PathToUserRegistryPOLFile -Force -ErrorAction Stop 55 | } 56 | catch 57 | { 58 | return $false 59 | } 60 | } 61 | 62 | } 63 | catch 64 | { 65 | return $false 66 | } 67 | } 68 | #if we made it here alles gut 69 | return $true 70 | } 71 | 72 | #Set the default 73 | $Compliance = "Compliant" 74 | 75 | #Then test the policy file using the function above - returns non-compliant if EITHER machine/user policy file is found to be corrupt. 76 | If ((Test-IsRegistryPOLGood) -eq $true) 77 | { 78 | $Compliance = "Compliant" 79 | } 80 | else 81 | { 82 | $Compliance = "Non-Compliant" 83 | } 84 | 85 | # CM doesn't care about the return nor does it rerun the discovery script after the remediation script has been run. 86 | # If the remediation script failes it will still be reported as "Compliant". 87 | # If you want to know if the remediation script failed, you need to catch the errors and use an exit code, e.g. "Exit 1" 88 | 89 | $Compliance 90 | -------------------------------------------------------------------------------- /CIBaseLines/Test-IsRegistryPOLGood.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Check for local Policy corruption issue 4 | 5 | .DESCRIPTION 6 | Checks the local policy files for corruption 7 | 8 | #> 9 | 10 | #Main Function which checks the policy files for corruption 11 | Function Test-IsRegistryPOLGood 12 | { 13 | $PathToMachineRegistryPOLFile = "$ENV:Windir\System32\GroupPolicy\Machine\Registry.pol" 14 | $PathToUserRegistryPOLFile = "$ENV:Windir\System32\GroupPolicy\User\Registry.pol" 15 | 16 | 17 | # Test for a Machine policy file - if there isn't one - all good 18 | if(!(Test-Path -Path $PathToMachineRegistryPOLFile -PathType Leaf)) {} 19 | #If there is a .pol file - test it 20 | else{ 21 | If (((Get-Content -Encoding Byte -Path $PathToMachineRegistryPOLFile -TotalCount 4) -join '') -ne '8082101103'){Return $False} 22 | } 23 | 24 | # Test for a User policy file - if there isn't one - as you were 25 | if(!(Test-Path -Path $PathToUserRegistryPOLFile -PathType Leaf)) {} 26 | #If there is a .pol file - test it 27 | else { 28 | If (((Get-Content -Encoding Byte -Path $PathToUserRegistryPOLFile -TotalCount 4) -join '') -ne '8082101103'){Return $False} 29 | } 30 | #if we made it here alles gut 31 | return $true 32 | } 33 | 34 | #Set the default 35 | $Compliance = "Compliant" 36 | 37 | #Then test the policy file using the function above - returns non-compliant if EITHER machine/user policy file is found to be corrupt. 38 | If ((Test-IsRegistryPOLGood) -eq $true) 39 | { 40 | $Compliance = "Compliant" 41 | } 42 | else 43 | { 44 | $Compliance = "Non-Compliant" 45 | } 46 | $Compliance -------------------------------------------------------------------------------- /Client/Fix-MappedDrive20H2Freeze.ps1: -------------------------------------------------------------------------------- 1 | <###################################################################################################### 2 | # # 3 | # When computers with Win10 20H2 have a mapped network share with certain options # 4 | # and is unable to reach that drive (working offline) any proccess that tries to access # 5 | # or list the drive (Read "My computer", Office templates") will freeze for ~10-15 mins # 6 | # once per reboot. # 7 | # # 8 | # I have no idea why, but I think it has something to do with SMB+Netbios names. # 9 | # Either username (ShortDomainName\User) or the mapping (\\ShortServerName\share) # 10 | # # 11 | # https://docs.microsoft.com/en-us/answers/questions/141745/windows-10-20h2-network-connection.html # 12 | # # 13 | # This is probably one of many possible fixes. # 14 | # Needs to be run in user context followed by a reboot. # 15 | # # 16 | ######################################################################################################> 17 | 18 | Function Fix-MappedDrive20H2Freeze([string]$drvletter) 19 | { 20 | $NetworkKey=Get-item HKCU:\Network 21 | $Subs=$NetworkKey.GetSubKeyNames() 22 | if ($Subs -contains $drvletter) 23 | { 24 | Write-Host "$($drvletter+":") was found" 25 | 26 | #ProviderFlags 0 = not a DFS root (?) 27 | #ProviderFlags 1 = DFS root (?) 28 | 29 | $PropertyName="ProviderFlags" 30 | $PropertyValue= 1 31 | 32 | $SubKey=$NetworkKey.OpenSubKey($drvletter,$true) 33 | $SubKey.SetValue($PropertyName, $PropertyValue,[Microsoft.Win32.RegistryValueKind]::DWord) 34 | if ($SubKey.GetValue($PropertyName) -eq $PropertyValue) 35 | { 36 | Write-Host "Successfully set $PropertyName value to $PropertyValue for $($drvletter+":")" 37 | } 38 | } 39 | else 40 | { 41 | Write-Host "$($drvletter+":") was not found" 42 | } 43 | } 44 | 45 | Fix-MappedDrive20H2Freeze -drvletter "Ltr" -------------------------------------------------------------------------------- /Client/Get-CredentialGuardStatus.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/Client/Get-CredentialGuardStatus.ps1 -------------------------------------------------------------------------------- /Client/Get-InstalledUpdates.ps1: -------------------------------------------------------------------------------- 1 | Param ( 2 | [Parameter(ValueFromPipelineByPropertyName,Mandatory=$false)] 3 | [string[]] $Categories=@(""), 4 | [Parameter(ValueFromPipelineByPropertyName,Mandatory=$false)] 5 | [string[]] $KBFilter="" 6 | ) 7 | 8 | $Session = New-Object -ComObject Microsoft.Update.Session 9 | $Searcher = $Session.CreateUpdateSearcher() 10 | $HistoryCount = $Searcher.GetTotalHistoryCount() 11 | # http://msdn.microsoft.com/en-us/library/windows/desktop/aa386532%28v=vs.85%29.aspx 12 | $Updates=$Searcher.QueryHistory(0,$HistoryCount) 13 | 14 | Function Get-InstalledUpdates([string]$IncludedCategories, $IncludeKB) 15 | { 16 | 17 | #Read-Host 18 | $Installed=0 19 | $All=0 #In order to display more info about the update e.g. $Update[199] while excluding failed installations. 20 | 21 | write-host "-------------------------------------" 22 | Foreach ($Update in $updates) 23 | { 24 | $KB=[regex]::match($Update.Title,"KB(\d+)") 25 | If (($Update.Categories[0].Name -match $IncludedCategories) -and ($Update.Title -match $IncludeKB)) 26 | { 27 | if ($Update.operation -eq 1 -and $Update.resultcode -eq 2) 28 | { 29 | write-host "Index:" $All 30 | write-host "Category:" $Update.Categories[0].Name 31 | write-host "Title:" $Update.Title 32 | write-host "Install Date:" $Update.Date 33 | write-host "UpdateID:" $update.UpdateIdentity.UpdateID 34 | write-host "KB:" $KB 35 | write-host "-------------------------------------" 36 | $Installed++ 37 | } 38 | } 39 | $All++ 40 | } 41 | Write-host "`nTotal number of updates returned by the search:" ($Installed) 42 | return $Installed 43 | } 44 | 45 | Get-InstalledUpdates $Categories $KBFilter 46 | #@("Windows 10","Office 2016") 47 | #@("KB4090007") 48 | 49 | 50 | #$Searcher.QueryHistory(0,$HistoryCount) | ForEach-Object {$_} | Out-File C:\temp\UpdateHistory.log 51 | 52 | -------------------------------------------------------------------------------- /Client/Install-LatestsFUExample.ps1: -------------------------------------------------------------------------------- 1 | FUDir = "C:\FeatureUpgrade" 2 | 3 | if ([System.IO.Directory]::Exists($FUDir) -eq $false) 4 | { 5 | New-Item $FUDir -Type Directory -Force 6 | } 7 | 8 | $WebClient = New-Object System.Net.WebClient 9 | $Url = "https://go.microsoft.com/fwlink/?LinkID=799445" 10 | $File = "$($FUDir)\Win10Upgrade.exe" 11 | $WebClient.DownloadFile($Url,$File) 12 | 13 | #UnComment to execute upgrade 14 | #Start-Process -FilePath $File -ArgumentList "/quietinstall /skipeula /auto upgrade /copylogs $FUDir" 15 | # 16 | -------------------------------------------------------------------------------- /Client/Set-WifiState.ps1: -------------------------------------------------------------------------------- 1 | Param( 2 | 3 | [Parameter(Mandatory=$true)] 4 | [bool] $Enabled 5 | ) 6 | 7 | if ($Enabled -eq $true) 8 | { 9 | $TargetState="On" 10 | } 11 | 12 | If ($Enabled -eq $false) 13 | { 14 | $TargetState="Off" 15 | } 16 | 17 | Add-Type -AssemblyName System.Runtime.WindowsRuntime 18 | $TaskGeneric = ([System.WindowsRuntimeSystemExtensions].GetMethods() | ? { $_.Name -eq 'asTask' -and $_.GetParameters().Count -eq 1 -and $_.GetParameters()[0].ParameterType.Name -eq 'IAsyncOperation`1' })[0] 19 | Function wait($WinRtTask, $ResultType) { 20 | $Task = $TaskGeneric.MakeGenericMethod($ResultType) 21 | $netTask = $Task.Invoke($null, @($WinRtTask)) 22 | $netTask.Wait(-1) | Out-Null 23 | $netTask.Result 24 | } 25 | [Windows.Devices.Radios.Radio,Windows.System.Devices,ContentType=WindowsRuntime] | Out-Null 26 | [Windows.Devices.Radios.RadioAccessStatus,Windows.System.Devices,ContentType=WindowsRuntime] | Out-Null 27 | wait ([Windows.Devices.Radios.Radio]::RequestAccessAsync()) ([Windows.Devices.Radios.RadioAccessStatus]) | Out-Null 28 | $radios = wait ([Windows.Devices.Radios.Radio]::GetRadiosAsync()) ([System.Collections.Generic.IReadOnlyList[Windows.Devices.Radios.Radio]]) 29 | $Wifi = $radios | ? { $_.Kind -eq 'WiFi' } | % {$_.SetStateAsync($TargetState)} 30 | -------------------------------------------------------------------------------- /Client/ToggleWifi.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/Client/ToggleWifi.gif -------------------------------------------------------------------------------- /Create-FireWallRule.ps1: -------------------------------------------------------------------------------- 1 | #Verified in WinPE 10 / Win10 2 | #Defaults to create an incoming rule which allows the TCP protocol on choosen port(s) 3 | 4 | Param ( 5 | [Parameter(ValueFromPipelineByPropertyName,Mandatory=$true)] 6 | [ValidateNotNullOrEmpty()] 7 | [string] $Name, 8 | [Parameter(ValueFromPipelineByPropertyName,Mandatory=$true)] 9 | [string[]] $Ports, 10 | [Parameter(ValueFromPipelineByPropertyName,Mandatory=$false)] 11 | [System.Net.Sockets.ProtocolType] $Protocol=[System.Net.Sockets.ProtocolType]::TCP, 12 | [Parameter(ValueFromPipelineByPropertyName,Mandatory=$false)] 13 | [string] $ApplicationPath, 14 | [Parameter(ValueFromPipelineByPropertyName,Mandatory=$false)] 15 | [ValidateSet('In','Out')] 16 | [string]$Direction="In", 17 | [Parameter(ValueFromPipelineByPropertyName,Mandatory=$false)] 18 | [ValidateSet('Allow','Block')] 19 | [string]$Action="Allow" 20 | 21 | 22 | ) 23 | 24 | $fw=New-Object -ComObject HNetcfg.FWpolicy2 25 | $rule=New-Object -ComObject HNetCfg.FWRule 26 | 27 | if ($ApplicationPath -notin ($null,"")) 28 | { 29 | $rule.ApplicationName=$ApplicationPath 30 | } 31 | 32 | $rule.Direction=switch($Direction){"In" {1} "Out" {2}} 33 | $rule.Name=$Name 34 | $rule.Protocol=$Protocol.Value__ 35 | $rule.LocalPorts=$Ports -join "," 36 | $rule.EdgeTraversal=$false 37 | 38 | switch($Action) 39 | { 40 | 'Allow' {$rule.Action=1} 41 | 'Block' {$rule.Action=0} 42 | } 43 | 44 | $rule.Enabled=$true 45 | $fw.Rules.Add($rule) 46 | -------------------------------------------------------------------------------- /CreateFWRule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/CreateFWRule.png -------------------------------------------------------------------------------- /General/Brushes-AsParam.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | Param 3 | ( 4 | 5 | [Parameter(Mandatory=$false, position=1)] 6 | [System.ConsoleColor]$ConsoleColor 7 | 8 | 9 | 10 | ) 11 | DynamicParam { 12 | Add-Type -AssemblyName System.Drawing, PresentationCore 13 | 14 | $DynColor = 'DynColor' 15 | $AttCol = New-Object System.Collections.ObjectModel.Collection[System.Attribute] 16 | $PSParamAttribute = New-Object System.Management.Automation.ParameterAttribute 17 | $PSParamAttribute.Mandatory = $False 18 | $AttCol.Add($PSParamAttribute) 19 | $RuntimeParamDict = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary 20 | $arrSet = [System.Drawing.Brushes] | Get-Member -Static -MemberType Property | Select -ExpandProperty Name 21 | $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet) 22 | $AttCol.Add($ValidateSetAttribute) 23 | $PSBoundParameters.DynColor= "White" 24 | $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($DynColor, [string], $AttCol) 25 | $RuntimeParamDict.Add($DynColor, $RuntimeParameter) 26 | 27 | return $RuntimeParamDict 28 | } 29 | 30 | 31 | Process 32 | { 33 | Add-Type -AssemblyName System.Windows.Forms 34 | #$ParamColor=$PSBoundParameters.DynColor 35 | 36 | [System.Windows.Forms.Application]::EnableVisualStyles() 37 | 38 | $Form=New-Object system.Windows.Forms.Form 39 | 40 | $Form.ClientSize='400,400' 41 | 42 | $Form.text="Form" 43 | 44 | $Form.TopMost=$false 45 | $Form.BackColor=$PSBoundParameters.DynColor 46 | $Form.ShowDialog() 47 | } 48 | -------------------------------------------------------------------------------- /General/ConvertTo-ScriptBlockWithParamsDemo.ps1: -------------------------------------------------------------------------------- 1 | <########################################################################################################## 2 | 3 | V.0.0.1 Alpha 4 | 5 | Demo of 'ConvertTo-ScriptBlockWithParams' 6 | 7 | Making it easier to pass a param, such as a [switch], to a powershell function while using 8 | "Invoke-Command" to execute it on a remote computer. 9 | 10 | 11 | eg. 12 | Invoke-CommandWithAnyParamsDemo -ComputerName "x" -ShouldForce 13 | Invoke-CommandWithAnyParamsDemo -ShouldForce 14 | Invoke-CommandWithAnyParamsDemo -DemoInt 2 -ComputerName "x" 15 | 16 | 2021-02-26: Initial Alpha release 17 | 18 | 19 | 20 | ##########################################################################################################> 21 | 22 | Function Invoke-CommandWithAnyParamsDemo 23 | { 24 | [CmdletBinding()] 25 | param( 26 | [Parameter(Mandatory=$False)] 27 | [string]$ComputerName, 28 | [Parameter(Mandatory=$False)] 29 | [int]$DemoInt=30, 30 | [Parameter(Mandatory=$False)] 31 | [switch]$ShouldForce=$False 32 | ) 33 | 34 | Function Get-HostName 35 | { 36 | param( 37 | [Parameter(Mandatory=$True, 38 | ParameterSetName="ShutdownType1")] 39 | [Switch]$Restart, 40 | [Parameter(Mandatory=$True, 41 | ParameterSetName="ShutdownType2")] 42 | [Switch]$Shutdown, 43 | [Parameter(Mandatory=$False)] 44 | [Switch]$Force, 45 | [Parameter(Mandatory=$False)] 46 | [int]$Countdown=30, 47 | [Parameter(Mandatory=$False)] 48 | [bool]$BoolTest=$false, 49 | [Parameter(Mandatory=$False)] 50 | [string]$MyTestString="TestString" 51 | ) 52 | 53 | $OsInstallDate=([WMI]'').ConvertToDateTime((Get-WmiObject Win32_OperatingSystem).InstallDate) 54 | 55 | Write-host "Restart: $Restart > Type: $($Restart.GetType().Name)" 56 | write-host "Shutdown: $Shutdown > Type: $($Shutdown.GetType().Name)" 57 | write-host "Force: $Force > Type: $($Force.GetType().Name)" 58 | write-host "CountDown: $Countdown > Type: $($Countdown.GetType().Name)" 59 | write-host "BoolTest: $BoolTest > Type: $($BoolTest.GetType().Name)" 60 | write-host "MyTestString: $MyTestString > Type: $($MyTestString.GetType().Name)" 61 | 62 | $name=hostname 63 | Write-Host "The command was executed on $name" 64 | write-host "OsInstallDate: $($OsInstallDate.ToLocalTime())" 65 | } 66 | 67 | Function ConvertTo-ScriptBlockWithParams 68 | { 69 | param( 70 | [Parameter(Mandatory=$True)] 71 | [String]$FunctionName, 72 | [Parameter(Mandatory=$True)] 73 | [Hashtable]$Parameters 74 | 75 | ) 76 | 77 | try 78 | { 79 | $MyFunction=(get-item Function:$FunctionName) 80 | $params=$Parameters 81 | $ScriptBlock=[ScriptBlock]::Create(".{$($MyFunction.ScriptBlock)} $(&{$args} @params)") 82 | } 83 | 84 | catch{ 85 | Write-host "error getting function" 86 | } 87 | return $ScriptBlock 88 | 89 | } 90 | 91 | ########################### MAIN ########################### 92 | 93 | if (!($ComputerName)) 94 | { 95 | $ComputerName=$env:COMPUTERNAME 96 | } 97 | 98 | $MyFunction=(get-item Function:\Get-HostName) 99 | $GetHostNameParams = @{ 100 | "Restart"='$true' #Please notice only here to show how to override the default without a param 101 | "Countdown"=$DemoInt 102 | "MyTestString"='"Edited string"' #Please notice the '" "' surrounding the string when a space is present 103 | "BoolTest"='$true' 104 | "Force"="`$$($ShouldForce.IsPresent)" 105 | } 106 | 107 | #write-host "`$$($ShouldForce.IsPresent)" 108 | Write-Host -ForegroundColor Cyan "`$GetHostNameParams = @{ 109 | 'Restart'='$true' #Please notice only here to show how to override the default without a param 110 | 'Countdown'=$DemoInt 111 | 'MyTestString'='Edited string' #Please notice the '" "' surrounding the string when a space is present 112 | 'BoolTest'='$true' 113 | 'Force'='$($ShouldForce.IsPresent)' 114 | }" 115 | 116 | 'Invoke-Command -ScriptBlock ${Function:Get-HostName} -ComputerName $ComputerName -ArgumentList $GetHostNameParams' | % {Write-host $_; Invoke-Expression $_} 117 | 'Invoke-Command -ScriptBlock ${Function:Get-HostName} -ComputerName $ComputerName -ArgumentList ("-Restart: $true")' | % {Write-host $_; Invoke-Expression $_} 118 | 'Invoke-Command -ScriptBlock ${Function:Get-HostName} -ComputerName $ComputerName -ArgumentList ("Restart:$true")' | % {Write-host $_; Invoke-Expression $_} 119 | 'Invoke-Command -ScriptBlock ${Function:Get-HostName} -ComputerName $ComputerName -ArgumentList ("Restart"="$true")' | % {Write-host $_; Invoke-Expression $_} 120 | 121 | Write-Host -ForegroundColor Yellow "I must be doing something wrong. This isn't working" 122 | Write-Host -ForegroundColor Yellow "I'm no PoSh guru, took one 'Introduction class' once, so there must be something that I havn't thought of." 123 | Write-Host -ForegroundColor Yellow "That beeing said. If I need it, there's surely more ppl needing it as well." 124 | Write-Host "" 125 | write-host -ForegroundColor Green "Now lets try 'ConvertTo-ScriptBlockWithParams'" 126 | Read-Host -Prompt "Push Enter to continue" 127 | '$GetHostNameSB=(ConvertTo-ScriptBlockWithParams -FunctionName "Get-HostName" -Parameters $GetHostNameParams)' | % {Write-host $_ -ForegroundColor Cyan; Invoke-Expression $_} 128 | #Write-host "################### output of Get-HostName ###################" 129 | #Write-Host "" 130 | 'Invoke-Command -ScriptBlock $GetHostNameSB -ComputerName $ComputerName' | % {Write-host -ForegroundColor Yellow $_;Write-host "################### output of Get-HostName ###################";Write-Host ""; Invoke-Expression $_} 131 | 132 | } -------------------------------------------------------------------------------- /General/Create-LetterLessSymlink.ps1: -------------------------------------------------------------------------------- 1 | Param ( 2 | [Parameter(ValueFromPipelineByPropertyName,Mandatory=$True)] 3 | $PathOfSymlink, 4 | [Parameter(ValueFromPipelineByPropertyName,Mandatory=$True)] 5 | $Target, 6 | [Parameter(ValueFromPipelineByPropertyName,Mandatory=$False)] 7 | [bool] $TargetIsTSVariable=$False 8 | ) 9 | 10 | 11 | Function DrvLetterToGuidPath($Path) 12 | { 13 | $Drive=-join $Path[0] 14 | $VolGuid=(Get-WmiObject win32_Volume | where {$_.DriveLetter -eq ($Drive+":")} | Select-Object -Property deviceID).DeviceID 15 | $GuidPath=($Path.Replace((-join ($Path[0..2])),$VolGuid)) 16 | return $GuidPath 17 | } 18 | 19 | Start-Transcript 20 | 21 | If ($TargetIsTSVariable -eq $true) 22 | { 23 | try 24 | { 25 | $tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment 26 | } 27 | catch 28 | { 29 | Write-host "TSEnv was not found" 30 | Stop-Transcript 31 | exit 32 | } 33 | write-host "Target is TSVariable" 34 | $Target=($tsenv[$Target]) 35 | write-host "TSVariable=$Target" 36 | 37 | 38 | } 39 | 40 | try 41 | { 42 | $attribs=[System.IO.File]::GetAttributes($Target) 43 | if (($attribs -and ($attribs -eq "Directory" )) -eq $false) 44 | { 45 | write-host "Only directories is supported at the moment." 46 | $TargetIsFolder=$False 47 | exit 48 | } 49 | if ([System.IO.Directory]::Exists($PathOfSymlink) -eq $false) 50 | { 51 | $GuidTarget=DrvLetterToGuidPath($Target) 52 | Write-host "Will create symlink:" $PathOfSymlink "pointing to:" $Target 53 | $b=(cmd /c mklink /D $PathOfSymlink $GuidTarget) 54 | write-host $b 55 | } 56 | else 57 | { 58 | Write-host "Place of symlink ($PathOfSymlink) already exist. Aborting..." 59 | } 60 | 61 | 62 | } 63 | catch 64 | { 65 | write-host "Could not locate $target" 66 | Stop-Transcript 67 | exit 68 | } 69 | 70 | 71 | #$GuidTarget=DrvLetterToGuidPath($Target) 72 | #If ($TargetIsFolder) 73 | # { 74 | # Write-host "Place of symlink ($PathOfSymlink) already exist. Aborting..." 75 | # } 76 | -------------------------------------------------------------------------------- /General/Get-RegistryKeyLastWriteTime.ps1: -------------------------------------------------------------------------------- 1 |  param( 2 | [parameter( 3 | ValueFromPipeline=$true, 4 | ValueFromPipelineByPropertyName=$true)] 5 | [Alias("CN","__SERVER","Computer","CNAME")] 6 | [string[]]$ComputerName=$env:ComputerName, 7 | [string]$Key = "HKLM", 8 | [string]$SubKey 9 | ) 10 | 11 | function Get-RegKeyLastWriteTime { 12 | <# 13 | .SYNOPSIS 14 | Retrieves the last write time of the supplied registry key 15 | 16 | .DESCRIPTION 17 | The Registry data that a hive stores in containers are called cells. A cell 18 | can hold a key, a value, a security descriptor, a list of subkeys, or a 19 | list of key values. 20 | 21 | Get-RegKeyLastWriteTime retrieves the LastWriteTime through a pointer to the 22 | FILETIME structure that receives the time at which the enumerated subkey was 23 | last written. Values do not contain a LastWriteTime property, but changes to 24 | child values update the parent keys lpftLastWriteTime. 25 | 26 | The LastWriteTime is updated when a key is created, modified, accessed, or 27 | deleted. 28 | 29 | .PARAMETER ComputerName 30 | Computer name to query 31 | 32 | .PARAMETER Key 33 | Root Key to query 34 | 35 | HKCR - Symbolic link to HKEY_LOCAL_MACHINE \SOFTWARE \Classes. 36 | HKCU - Symbolic link to a key under HKEY_USERS representing a user's profile 37 | hive. 38 | HKLM - Placeholder with no corresponding physical hive. This key contains 39 | other keys that are hives. 40 | HKU - Placeholder that contains the user-profile hives of logged-on 41 | accounts. 42 | HKCC - Symbolic link to the key of the current hardware profile 43 | 44 | .PARAMETER SubKey 45 | Registry Key to query 46 | 47 | .EXAMPLE 48 | Get-RegKeyLastWriteTime -ComputerName testwks -Key HKLM -SubKey Software 49 | 50 | .EXAMPLE 51 | Get-RegKeyLastWriteTime -ComputerName testwks1,testwks2 -SubKey Software 52 | 53 | .EXAMPLE 54 | Get-RegKeyLastWriteTime -SubKey Software\Microsoft 55 | 56 | .EXAMPLE 57 | "testwks1","testwks2" | Get-RegKeyLastWriteTime -SubKey Software\Microsoft ` 58 | \Windows\CurrentVersion 59 | 60 | .NOTES 61 | NAME: Get-RegKeyLastWriteTime 62 | AUTHOR: Shaun Hess 63 | VERSION: 1.0 64 | LASTEDIT: 01JUL2011 65 | LICENSE: Creative Commons Attribution 3.0 Unported License 66 | (http://creativecommons.org/licenses/by/3.0/) 67 | 68 | .LINK 69 | http://www.shaunhess.com 70 | #> 71 | 72 | [CmdletBinding()] 73 | 74 | param( 75 | [parameter( 76 | ValueFromPipeline=$true, 77 | ValueFromPipelineByPropertyName=$true)] 78 | [Alias("CN","__SERVER","Computer","CNAME")] 79 | [string[]]$ComputerName=$env:ComputerName, 80 | [string]$Key = "HKLM", 81 | [string]$SubKey 82 | ) 83 | 84 | BEGIN { 85 | switch ($Key) { 86 | "HKCR" { $searchKey = 0x80000000} #HK Classes Root 87 | "HKCU" { $searchKey = 0x80000001} #HK Current User 88 | "HKLM" { $searchKey = 0x80000002} #HK Local Machine 89 | "HKU" { $searchKey = 0x80000003} #HK Users 90 | "HKCC" { $searchKey = 0x80000005} #HK Current Config 91 | default { 92 | "Invalid Key. Use one of the following options: 93 | HKCR, HKCU, HKLM, HKU, HKCC"} 94 | } 95 | 96 | $KEYQUERYVALUE = 0x1 97 | $KEYREAD = 0x19 98 | $KEYALLACCESS = 0x3F 99 | } 100 | PROCESS { 101 | foreach($computer in $ComputerName) { 102 | 103 | $sig0 = @' 104 | [DllImport("advapi32.dll", SetLastError = true)] 105 | public static extern int RegConnectRegistry( 106 | string lpMachineName, 107 | int hkey, 108 | ref int phkResult); 109 | '@ 110 | $type0 = Add-Type -MemberDefinition $sig0 -Name Win32Utils -Namespace RegConnectRegistry -Using System.Text -PassThru 111 | 112 | $sig1 = @' 113 | [DllImport("advapi32.dll", CharSet = CharSet.Auto)] 114 | public static extern int RegOpenKeyEx( 115 | int hKey, 116 | string subKey, 117 | int ulOptions, 118 | int samDesired, 119 | out int hkResult); 120 | '@ 121 | $type1 = Add-Type -MemberDefinition $sig1 -Name Win32Utils ` 122 | -Namespace RegOpenKeyEx -Using System.Text -PassThru 123 | 124 | $sig2 = @' 125 | [DllImport("advapi32.dll", EntryPoint = "RegEnumKeyEx")] 126 | extern public static int RegEnumKeyEx( 127 | int hkey, 128 | int index, 129 | StringBuilder lpName, 130 | ref int lpcbName, 131 | int reserved, 132 | int lpClass, 133 | int lpcbClass, 134 | out long lpftLastWriteTime); 135 | 136 | 137 | '@ 138 | $type2 = Add-Type -MemberDefinition $sig2 -Name Win32Utils ` 139 | -Namespace RegEnumKeyEx -Using System.Text -PassThru 140 | 141 | $sig3 = @' 142 | [DllImport("advapi32.dll", SetLastError=true)] 143 | public static extern int RegCloseKey( 144 | int hKey); 145 | '@ 146 | $type3 = Add-Type -MemberDefinition $sig3 -Name Win32Utils -Namespace RegCloseKey -Using System.Text -PassThru 147 | 148 | 149 | $hKey = new-object int 150 | $hKeyref = new-object int 151 | $searchKeyRemote = $type0::RegConnectRegistry($computer, $searchKey, [ref]$hKey) 152 | $result = $type1::RegOpenKeyEx($hKey, $SubKey, 0, $KEYREAD, [ref]$hKeyref) 153 | 154 | #initialize variables 155 | $builder = New-Object System.Text.StringBuilder 1024 156 | $index = 0 157 | $length = [int] 1024 158 | $time = New-Object Long 159 | 160 | #234 means more info, 0 means success. Either way, keep reading 161 | while ( 0,234 -contains $type2::RegEnumKeyEx($hKeyref, $index++, $builder, [ref] $length, $null, $null, $null, [ref] $time) ) 162 | { 163 | #create output object 164 | $o = "" | Select Key, LastWriteTime, ComputerName 165 | $o.ComputerName = "$computer" 166 | $o.Key = $builder.ToString() 167 | # TODO Change to use the time api 168 | #Write-host ((Get-Date $time).ToUniversalTime()) 169 | $timezone=[TimeZoneInfo]::Local 170 | $Offset=$timezone.BaseUtcOffset.TotalHours 171 | 172 | $o.LastWriteTime = (Get-Date $time).AddYears(1600).AddHours($Offset) 173 | $o 174 | #reinitialize for next time through the loop 175 | $length = [int] 1024 176 | $builder = New-Object System.Text.StringBuilder 1024 177 | } 178 | 179 | $result = $type3::RegCloseKey($hKey); 180 | write-host $builder 181 | } 182 | } 183 | } # End Get-RegKeyLastWriteTime function 184 | 185 | 186 | write-host $Key $SubKey 187 | Get-RegKeyLastWriteTime -Key $Key -SubKey $SubKey -------------------------------------------------------------------------------- /General/Get-Resolution/DisplayHelperWithScale/DisplayHelper.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/General/Get-Resolution/DisplayHelperWithScale/DisplayHelper.dll -------------------------------------------------------------------------------- /General/Get-Resolution/DisplayHelperWithScale/DisplayHelperDllWithSetScale.ps1: -------------------------------------------------------------------------------- 1 | ################################################################################################################## 2 | # 3 | # 4 | # 5 | # 2020-08-14 6 | # Dll v.1.0.0.2 7 | # * Added support for changing scale per monitor. And some additional output to "Get-Monitors" 8 | # 9 | # 2020-08-13 10 | # Dll v.1.0.0.1 11 | # * Fixes and enables the use of RefreshRate (Hz) with "Set-MonitorResolution". 12 | # 13 | # 14 | # 15 | # 16 | ################################################################################################################## 17 | 18 | 19 | Add-type -Path $PSScriptRoot\DisplayHelper.dll 20 | 21 | Function Get-Monitors 22 | { 23 | $DisplayHelper=[Displayhelper.DisplayInfo]::new() 24 | return $($DisplayHelper.GetDisplayMonitors()) 25 | } 26 | 27 | Function Get-MonitorResolution 28 | { 29 | Param( 30 | [Parameter(Mandatory=$false)] 31 | [switch]$ShowAllResolutions 32 | ) 33 | 34 | DynamicParam 35 | { 36 | try 37 | { 38 | $Monitors='Monitors' 39 | $AttCol = New-Object System.Collections.ObjectModel.Collection[System.Attribute] 40 | $PSParamAttribute = New-Object System.Management.Automation.ParameterAttribute 41 | $PSParamAttribute.Mandatory = $True 42 | $AttCol.Add($PSParamAttribute) 43 | $arrSet=([Displayhelper.DisplayInfo]::new() | % {$_.GetDisplayMonitors()} | Select-Object -Property Name).Name 44 | $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute([string[]]$arrset) 45 | $AttCol.Add($ValidateSetAttribute) 46 | #$PSBoundParameters.Monitors=[string[]]$arrset 47 | $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($Monitors, [string[]], $AttCol) 48 | $RuntimeParamDict = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary 49 | $RuntimeParamDict.Add($Monitors, $RuntimeParameter) 50 | return $RuntimeParamDict 51 | } 52 | catch 53 | { 54 | ##Error 55 | } 56 | 57 | } 58 | Process 59 | { 60 | $DisplayHelper=[Displayhelper.DisplayInfo]::new() 61 | $mons=$($DisplayHelper.GetDisplayMonitors()) 62 | $return=foreach ($monitor in $mons) 63 | { 64 | 65 | if ($monitor.Name -in $PSBoundParameters.Monitors) 66 | { 67 | if ($ShowAllResolutions -eq $false) 68 | { 69 | $monitor | Select-Object -Property Name,Width,Height,LogicalWidth,LogicalHeight,Scale 70 | } 71 | else 72 | { 73 | $current=$monitor | Select-Object -Property Name,Width,Height 74 | $reslist=$monitor.GetResolutionList() 75 | $reslist.Add([Displayhelper.Resolution]::new("Current",$current.Width,$current.Height,32,$monitor.Name)) 76 | #$dict = New-Object 'system.collections.generic.dictionary[[string],[System.Array]]' 77 | $hasht=[hashtable]::new() 78 | $hasht.Add($current.Name,$reslist) 79 | #$hasht 80 | $reslist 81 | 82 | } 83 | } 84 | } 85 | 86 | return ($return) 87 | } 88 | } 89 | 90 | Function Set-MonitorResolution 91 | { 92 | [CmdletBinding()] 93 | Param 94 | 95 | () 96 | 97 | DynamicParam 98 | { 99 | $EC = $ExecutionContext.GetType().InvokeMember('_context', 'NonPublic, Instance, GetField', $null, $ExecutionContext, $null) 100 | $CCP = $EC.GetType().InvokeMember('CurrentCommandProcessor', 'NonPublic, Instance, GetProperty', $null, $EC, $null) 101 | $Binder = $CCP.GetType().InvokeMember('CmdletParameterBinderController', 'NonPublic, Instance, GetProperty', $null, $CCP, $null) 102 | $ValidProperties = 'ParameterNameSpecified', 'ParameterName', 'ArgumentSpecified', 'ArgumentValue' 103 | 104 | $UnboundArguments = $Binder.GetType().InvokeMember('UnboundArguments', 'NonPublic, Instance, GetProperty', $null, $Binder, $null) | ForEach-Object { 105 | 106 | if (-not $ValidProperties) 107 | { 108 | $ValidProperties = $_.GetType().GetProperties('NonPublic, Instance').Name 109 | } 110 | 111 | $Props = [ordered] @{} 112 | 113 | foreach ($PropName in $ValidProperties) 114 | { 115 | try 116 | { 117 | $Props[$PropName] = $_.GetType().InvokeMember($PropName, 'NonPublic, Instance, GetProperty', $null, $_, $null) 118 | } 119 | 120 | catch 121 | { 122 | } 123 | 124 | } 125 | 126 | [PSCustomObject] $Props 127 | 128 | } 129 | 130 | $fakeBoundNamed = @{} 131 | 132 | $fakeBoundUnNamed = New-Object System.Collections.ArrayList 133 | $CurrentParamName = $null 134 | 135 | foreach ($Arg in $UnboundArguments) 136 | { 137 | 138 | if ($Arg.ParameterNameSpecified) 139 | { 140 | if ($CurrentParamName) 141 | { 142 | $fakeBoundNamed[$CurrentParamName] = $true 143 | } 144 | 145 | $CurrentParamName = $Arg.ParameterName 146 | 147 | } 148 | 149 | if ($Arg.ArgumentSpecified) 150 | { 151 | if (-not $CurrentParamName) 152 | { 153 | $fakeBoundUnNamed.Add($Arg.ArgumentValue) | Out-Null 154 | } 155 | 156 | else 157 | { 158 | $fakeBoundNamed[$CurrentParamName] = $Arg.ArgumentValue 159 | $CurrentParamName = $null 160 | } 161 | 162 | } 163 | 164 | } 165 | 166 | $RuntimeParamDict = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary 167 | try 168 | { 169 | 170 | #MonitorName 171 | $MonitorName='MonitorName' 172 | $AttCol = New-Object System.Collections.ObjectModel.Collection[System.Attribute] 173 | $PSParamAttribute = New-Object System.Management.Automation.ParameterAttribute 174 | $PSParamAttribute.Mandatory = $True 175 | $PSParamAttribute.ValueFromPipeline=$True 176 | $AttCol.Add($PSParamAttribute) 177 | $arrSet=([Displayhelper.DisplayInfo]::new() | % {$_.GetDisplayMonitors()} | Select-Object -Property Name).Name 178 | $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute([string[]]$arrset) 179 | $AttCol.Add($ValidateSetAttribute) 180 | $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($MonitorName, [string], $AttCol) 181 | $RuntimeParamDict.Add($MonitorName, $RuntimeParameter) 182 | 183 | 184 | #Use the previous dynamicparam in the next 185 | 186 | if ($fakeBoundNamed.Count -gt 0) 187 | { 188 | $Displ=$fakeBoundNamed["MonitorName"] 189 | $Monitor=(Get-Monitors | Where-Object -Property Name -EQ $Displ) 190 | } 191 | 192 | #Resolution 193 | $Resolution='Resolution' 194 | $AttCol = New-Object System.Collections.ObjectModel.Collection[System.Attribute] 195 | $PSParamAttribute = New-Object System.Management.Automation.ParameterAttribute 196 | $PSParamAttribute.Mandatory = $True 197 | $PSParamAttribute.ValueFromPipeline=$True 198 | $AttCol.Add($PSParamAttribute) 199 | $arrSet=([Displayhelper.DisplayInfo]::new() | % {$_.GetDisplayMonitors()} | Where-Object -Property Name -eq $Displ | % {$_.GetResolutionList()}).Name 200 | $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute([string[]]$arrset) 201 | $AttCol.Add($ValidateSetAttribute) 202 | $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($Resolution, [string], $AttCol) 203 | $RuntimeParamDict.Add($Resolution, $RuntimeParameter) 204 | 205 | if ($fakeBoundNamed.Count -gt 0) 206 | { 207 | if ($fakeBoundNamed["Resolution"]) 208 | { 209 | $ResOfChoice=$fakeBoundNamed["Resolution"] 210 | } 211 | } 212 | 213 | 214 | #RefreshRate 215 | $RefreshRate='RefreshRate' 216 | $AttCol = New-Object System.Collections.ObjectModel.Collection[System.Attribute] 217 | $PSParamAttribute = New-Object System.Management.Automation.ParameterAttribute 218 | $PSParamAttribute.Mandatory = $false 219 | $PSParamAttribute.ValueFromPipeline=$true 220 | $AttCol.Add($PSParamAttribute) 221 | $arrSet=(Get-MonitorResolution -ShowAllResolutions -Monitors $Monitor.Name | Where-Object -Property Name -EQ $ResOfChoice).RefreshRates 222 | $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute([string[]]$arrset) 223 | $AttCol.Add($ValidateSetAttribute) 224 | $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($RefreshRate, [int], $AttCol) 225 | $RuntimeParamDict.Add($RefreshRate, $RuntimeParameter) 226 | 227 | 228 | } 229 | catch 230 | { 231 | ##Error 232 | 233 | } 234 | return $RuntimeParamDict 235 | 236 | } 237 | Process 238 | { 239 | $DisplayHelper=[Displayhelper.DisplayInfo]::new() 240 | $mons=$($DisplayHelper.GetDisplayMonitors()) 241 | $return=foreach ($monitor in $mons) 242 | { 243 | 244 | if ($monitor.Name -in $PSBoundParameters.MonitorName) 245 | { 246 | $reslist=([Displayhelper.DisplayInfo+DisplayMonitor]$monitor).GetResolutionList() 247 | $ChoosenRes=$reslist | Where-Object -Property Name -eq $PSBoundParameters.Resolution 248 | if ($RefreshRate) 249 | { 250 | $var=([Displayhelper.DisplayInfo+DisplayMonitor]$monitor).SetMonitorResolution($ChoosenRes,$PSBoundParameters.RefreshRate) 251 | } 252 | 253 | $var 254 | } 255 | 256 | 257 | } 258 | 259 | return $return 260 | } 261 | } 262 | 263 | Function Get-MonitorScale 264 | { 265 | [CmdletBinding()] 266 | Param 267 | 268 | () 269 | 270 | DynamicParam 271 | { 272 | 273 | $RuntimeParamDict = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary 274 | try 275 | { 276 | 277 | #MonitorName 278 | $MonitorName='MonitorName' 279 | $AttCol = New-Object System.Collections.ObjectModel.Collection[System.Attribute] 280 | $PSParamAttribute = New-Object System.Management.Automation.ParameterAttribute 281 | $PSParamAttribute.Mandatory = $True 282 | $PSParamAttribute.ValueFromPipeline=$True 283 | $AttCol.Add($PSParamAttribute) 284 | $arrSet=([Displayhelper.DisplayInfo]::new() | % {$_.GetDisplayMonitors()} | Select-Object -Property Name).Name 285 | $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute([string[]]$arrset) 286 | $AttCol.Add($ValidateSetAttribute) 287 | $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($MonitorName, [string], $AttCol) 288 | $RuntimeParamDict.Add($MonitorName, $RuntimeParameter) 289 | 290 | } 291 | catch 292 | { 293 | ##Error 294 | } 295 | return $RuntimeParamDict 296 | 297 | } 298 | Process 299 | { 300 | $DisplayHelper=[Displayhelper.DisplayInfo]::new() 301 | $mons=$($DisplayHelper.GetDisplayMonitors()) 302 | $return=foreach ($monitor in $mons) 303 | { 304 | if ($monitor.Name -eq $PSBoundParameters.MonitorName) 305 | { 306 | $ret=$monitor.GetMonitorScaleInfo() 307 | $ret 308 | } 309 | 310 | 311 | } 312 | 313 | return $return 314 | } 315 | } 316 | 317 | Function Set-MonitorScale 318 | { 319 | [CmdletBinding()] 320 | Param 321 | 322 | () 323 | 324 | DynamicParam 325 | { 326 | $EC = $ExecutionContext.GetType().InvokeMember('_context', 'NonPublic, Instance, GetField', $null, $ExecutionContext, $null) 327 | $CCP = $EC.GetType().InvokeMember('CurrentCommandProcessor', 'NonPublic, Instance, GetProperty', $null, $EC, $null) 328 | $Binder = $CCP.GetType().InvokeMember('CmdletParameterBinderController', 'NonPublic, Instance, GetProperty', $null, $CCP, $null) 329 | $ValidProperties = 'ParameterNameSpecified', 'ParameterName', 'ArgumentSpecified', 'ArgumentValue' 330 | 331 | $UnboundArguments = $Binder.GetType().InvokeMember('UnboundArguments', 'NonPublic, Instance, GetProperty', $null, $Binder, $null) | ForEach-Object { 332 | 333 | if (-not $ValidProperties) 334 | { 335 | $ValidProperties = $_.GetType().GetProperties('NonPublic, Instance').Name 336 | } 337 | 338 | $Props = [ordered] @{} 339 | 340 | foreach ($PropName in $ValidProperties) 341 | { 342 | try 343 | { 344 | $Props[$PropName] = $_.GetType().InvokeMember($PropName, 'NonPublic, Instance, GetProperty', $null, $_, $null) 345 | } 346 | 347 | catch 348 | { 349 | } 350 | } 351 | 352 | [PSCustomObject] $Props 353 | } 354 | 355 | $fakeBoundNamed = @{} 356 | 357 | $fakeBoundUnNamed = New-Object System.Collections.ArrayList 358 | $CurrentParamName = $null 359 | 360 | foreach ($Arg in $UnboundArguments) 361 | { 362 | 363 | if ($Arg.ParameterNameSpecified) 364 | { 365 | if ($CurrentParamName) 366 | { 367 | $fakeBoundNamed[$CurrentParamName] = $true 368 | } 369 | 370 | $CurrentParamName = $Arg.ParameterName 371 | } 372 | 373 | if ($Arg.ArgumentSpecified) 374 | { 375 | if (-not $CurrentParamName) 376 | { 377 | $fakeBoundUnNamed.Add($Arg.ArgumentValue) | Out-Null 378 | } 379 | 380 | else 381 | { 382 | $fakeBoundNamed[$CurrentParamName] = $Arg.ArgumentValue 383 | $CurrentParamName = $null 384 | } 385 | } 386 | 387 | } 388 | 389 | $RuntimeParamDict = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary 390 | try 391 | { 392 | 393 | #MonitorName 394 | $MonitorName='MonitorName' 395 | $AttCol = New-Object System.Collections.ObjectModel.Collection[System.Attribute] 396 | $PSParamAttribute = New-Object System.Management.Automation.ParameterAttribute 397 | $PSParamAttribute.Mandatory = $True 398 | $PSParamAttribute.ValueFromPipeline=$True 399 | $AttCol.Add($PSParamAttribute) 400 | $arrSet=([Displayhelper.DisplayInfo]::new() | % {$_.GetDisplayMonitors()} | Select-Object -Property Name).Name 401 | $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute([string[]]$arrset) 402 | $AttCol.Add($ValidateSetAttribute) 403 | $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($MonitorName, [string], $AttCol) 404 | $RuntimeParamDict.Add($MonitorName, $RuntimeParameter) 405 | 406 | if ($fakeBoundNamed.Count -gt 0) 407 | { 408 | $Displ=$fakeBoundNamed["MonitorName"] 409 | $Monitor=(Get-Monitors | Where-Object -Property Name -EQ $Displ) 410 | [int[]] $DPIValues = ( 100, 125, 150, 175, 200, 225, 250, 300, 350, 400, 450, 500 ) 411 | } 412 | 413 | ##MonitorScale 414 | $MonitorScale='MonitorScale' 415 | $AttCol = New-Object System.Collections.ObjectModel.Collection[System.Attribute] 416 | $PSParamAttribute = New-Object System.Management.Automation.ParameterAttribute 417 | $PSParamAttribute.Mandatory = $True 418 | $PSParamAttribute.ValueFromPipeline=$True 419 | $AttCol.Add($PSParamAttribute) 420 | #$arrSet=([Displayhelper.DisplayInfo]::new() | % {$_.GetDisplayMonitors()} | Where-Object -Property Name -eq $Displ | % {$_.GetScaleValueSpan()}) 421 | $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($DPIValues) 422 | $AttCol.Add($ValidateSetAttribute) 423 | 424 | <# 425 | $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute([string[]]$arrset) 426 | $AttCol.Add($ValidateSetAttribute) 427 | #> 428 | 429 | $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($MonitorScale, [int], $AttCol) 430 | $RuntimeParamDict.Add($MonitorScale, $RuntimeParameter) 431 | 432 | } 433 | catch 434 | { 435 | ##Error 436 | 437 | } 438 | return $RuntimeParamDict 439 | 440 | } 441 | Process 442 | { 443 | $DisplayHelper=[Displayhelper.DisplayInfo]::new() 444 | $mons=$($DisplayHelper.GetDisplayMonitors()) 445 | $return=foreach ($monitor in $mons) 446 | { 447 | if ($monitor.Name -eq $PSBoundParameters.MonitorName) 448 | { 449 | $ret=$monitor.SetMonitorScale($PSBoundParameters.MonitorScale) 450 | $ret 451 | } 452 | } 453 | 454 | return $return 455 | } 456 | } -------------------------------------------------------------------------------- /General/GetOnlCompsWithUserSession.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Gets all the online computers that matches the username and Domain variables. 4 | .DESCRIPTION 5 | Work in progress 6 | .EXAMPLE 7 | GetOnlCompsWithUserSession.ps1 -SiteServer cm1 -SiteName cm1 -UserName ad 8 | .EXAMPLE 9 | GetOnlCompsWithUserSession.ps1 -SiteServer cm1 -SiteName cm1 -UserName %lkd% -Domain RemoteDomain 10 | #> 11 | 12 | Param ( 13 | [Parameter(ValueFromPipelineByPropertyName,Mandatory=$True)] 14 | [string] $SiteServer, 15 | [Parameter(ValueFromPipelineByPropertyName,Mandatory=$True)] 16 | [string] $SiteName, 17 | [Parameter(ValueFromPipelineByPropertyName,Mandatory=$True)] 18 | [string] $UserName, 19 | [Parameter(ValueFromPipelineByPropertyName,Mandatory=$False)] 20 | $Domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name # NETBIOSName of remote domain or leave blank for current 21 | ) 22 | 23 | 24 | if ($UserName.Contains('%') -eq $false) 25 | { 26 | write-host "Observe that UserName is accepting Wildcards in the form of '%'" -ForegroundColor DarkYellow 27 | } 28 | $BuildDomainName=$null 29 | if ($Domain.Contains(".") -eq $true) 30 | { 31 | $SplitDomain=$Domain.ToString().Split(".") 32 | 33 | Foreach ($part in $SplitDomain) 34 | { 35 | $BuildDomainName=($BuildDomainName+"dc=$part,") 36 | } 37 | 38 | $BuildDomainName=($BuildDomainName.SubString(0,$BuildDomainName.Length-1)) 39 | 40 | $UserName=$UserNAme.Replace($Domain,(Get-ADDomain $BuildDomainName).NetBIOSName) 41 | $Domain=(Get-ADDomain $BuildDomainName).NetBIOSName 42 | 43 | write-host "Domain:" $Domain 44 | } 45 | 46 | 47 | #write-host $Domain 48 | $namespace = "ROOT\SMS\site_$SiteName" 49 | $classname = "SMS_CombinedDeviceResources" 50 | 51 | $UserName=$UserName.ToLower().Replace(($Domain.ToLower()+"\"),"") 52 | Write-Host "Username:" $UserName 53 | Get-WmiObject -Query "select Name,ResourceID,CNIsOnline,CurrentLogonUser from SMS_CombinedDeviceResources where CurrentLogonUser like '$Domain\\$UserName' and CNIsOnline=1" -ComputerName $SiteServer -Namespace $namespace | select Name, CurrentLogonUser, ResourceID, CNIsOnline 54 | 55 | -------------------------------------------------------------------------------- /General/RunCodeAfterShowDialog/ShowDialog.ps1: -------------------------------------------------------------------------------- 1 | Function Test-URI 2 | { 3 | param ( 4 | [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] 5 | [string]$URIPath, 6 | [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] 7 | [string]$ExpectedContentType 8 | ) 9 | 10 | $UriOut=$null 11 | $Result=[System.Uri]::TryCreate($URIPath, [System.UriKind]::Absolute,[ref] $UriOut) 12 | 13 | if ($Result -eq $true) 14 | { 15 | $WebRes=Invoke-WebRequest -Uri $UriOut -ErrorAction SilentlyContinue 16 | if ($WebRes.BaseResponse.StatusCode -eq "OK" -and $WebRes.BaseResponse.ResponseUri -eq $URIPath -and $WebRes.BaseResponse.ContentType -match $ContentType) 17 | { 18 | return $true 19 | } 20 | } 21 | 22 | return $false 23 | } 24 | 25 | Function ChangeBgColor($Color){ 26 | 27 | #Will only use Invoke to make changes 28 | 29 | if ($([System.Drawing.Color]::$Color)) 30 | { 31 | Write-Host "---------------" 32 | write-host "Color is valid" 33 | $ColorName=([System.Drawing.Color]::$Color).Name 34 | Write-Host "Changing BGColor to $ColorName" 35 | #Write-Host $ColorName 36 | } 37 | else{ 38 | write-host "Invalid Color." 39 | break 40 | } 41 | 42 | $hash.Window.Dispatcher.invoke( 43 | [action]{$Border=$hash.window.FindName("Bord1");$Border.BackGround=$ColorName 44 | }, 45 | "Normal" 46 | ) 47 | } 48 | 49 | 50 | Function ChangeSpinnerColor 51 | { 52 | 53 | #Using Invoke if it's required. 54 | 55 | param ( 56 | [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)] 57 | [string]$Dyncolor 58 | ) 59 | 60 | DynamicParam { 61 | Add-Type -AssemblyName System.Drawing, PresentationCore 62 | $RingColor = 'RingColor' 63 | $AttCol = New-Object System.Collections.ObjectModel.Collection[System.Attribute] 64 | $PSParamAttribute = New-Object System.Management.Automation.ParameterAttribute 65 | $PSParamAttribute.Mandatory = $True 66 | $AttCol.Add($PSParamAttribute) 67 | $RuntimeParamDict = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary 68 | $arrSet = [System.Drawing.Brushes] | Get-Member -Static -MemberType Property | Select -ExpandProperty Name 69 | $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet) 70 | $AttCol.Add($ValidateSetAttribute) 71 | $PSBoundParameters.RingColor= "White" 72 | $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($RingColor, [string], $AttCol) 73 | $RuntimeParamDict.Add($RingColor, $RuntimeParameter) 74 | 75 | return $RuntimeParamDict 76 | } 77 | 78 | Process 79 | { 80 | 81 | write-host "Updating Spinner" 82 | $a=$hash.window.Dispatcher.CheckAccess() 83 | write-host "Spinner needs invoke:" $($a -eq $false) 84 | if ($a -eq $True) 85 | { 86 | write-host "Have access to spinner" 87 | $Spinner=$hash.window.FindName("Ring");$Spinner.Foreground="$($PSBoundParameters.RingColor)" 88 | } 89 | else{ 90 | write-host "Using invoke to update spinner" 91 | $hash.Window.Dispatcher.invoke( 92 | [action]{$Spinner=$hash.window.FindName("Ring");$Spinner.Foreground="$($PSBoundParameters.RingColor)" 93 | }, 94 | "Normal" 95 | ) 96 | } 97 | Write-Host "-----------" 98 | } 99 | 100 | } 101 | 102 | Function SetBackgroundToPic(){ 103 | 104 | #Using Invoke if it's required. 105 | 106 | param ( 107 | [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] 108 | [string]$ImagePath 109 | ) 110 | 111 | 112 | if ($ImagePath.ToLower().StartsWith("http") -eq $false) 113 | { 114 | if (Test-Path $ImagePath) 115 | { 116 | Write-host "Local image Found:" $ImagePath 117 | 118 | } 119 | else 120 | { 121 | write-host "Path is unreachable" 122 | break 123 | } 124 | } 125 | else 126 | { 127 | Write-host "Http image:" $ImagePath 128 | if ($(Test-URI -URIPath $ImagePath -ExpectedContentType "image*") -eq $true) 129 | { 130 | Write-host "URI of image is reachable" 131 | } 132 | else 133 | { 134 | write-host "URI of image is unreachable" 135 | break 136 | } 137 | } 138 | 139 | $acc=$hash.window.Dispatcher.CheckAccess() 140 | If ($acc -eq $false) 141 | { 142 | Write-host "Using invoke to update background: $($acc -eq $false)" 143 | $hash.Window.Dispatcher.invoke( 144 | [action]{ 145 | $ImageBrush=[System.Windows.Media.ImageBrush]::new() 146 | $ImageBrush.Opacity=1 147 | $ImageBrush.Stretch=[System.Windows.Media.Stretch]::UniformToFill 148 | $ImageBrush.ImageSource=[System.Windows.Media.Imaging.BitmapImage]::new([System.Uri]::new($ImagePath, [System.UriKind]::Absolute)) 149 | $t=$hash.window.FindName("Bord1");$t.BackGround=$ImageBrush 150 | }, 151 | "Normal" 152 | 153 | ) 154 | } 155 | else 156 | { 157 | 158 | Write-host "Using invoke to update background: $($acc -eq $false)" 159 | 160 | $ImageBrush=[System.Windows.Media.ImageBrush]::new() 161 | $ImageBrush.Opacity=1 162 | $ImageBrush.Stretch=[System.Windows.Media.Stretch]::UniformToFill 163 | $ImageBrush.ImageSource=[System.Windows.Media.Imaging.BitmapImage]::new([System.Uri]::new($ImagePath, [System.UriKind]::Absolute)) 164 | $t=$hash.window.FindName("Bord1");$t.BackGround=$ImageBrush 165 | } 166 | Write-Host "-----------" 167 | } 168 | 169 | Function ChangeTextBlock() 170 | { 171 | #(On purpose) Only works when called from a thread that already is using $hash.Window.Dispatcher.Invoke 172 | 173 | Param ( 174 | [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] 175 | [string]$BlockName, 176 | [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] 177 | [string]$Text 178 | ) 179 | DynamicParam { 180 | Add-Type -AssemblyName System.Drawing, PresentationCore 181 | 182 | $DynColor = 'DynColor' 183 | $AttCol = New-Object System.Collections.ObjectModel.Collection[System.Attribute] 184 | $PSParamAttribute = New-Object System.Management.Automation.ParameterAttribute 185 | $PSParamAttribute.Mandatory = $True 186 | $AttCol.Add($PSParamAttribute) 187 | $RuntimeParamDict = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary 188 | $arrSet = [System.Drawing.Brushes] | Get-Member -Static -MemberType Property | Select -ExpandProperty Name 189 | $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet) 190 | $AttCol.Add($ValidateSetAttribute) 191 | $PSBoundParameters.DynColor= "White" 192 | $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($DynColor, [string], $AttCol) 193 | $RuntimeParamDict.Add($DynColor, $RuntimeParameter) 194 | 195 | return $RuntimeParamDict 196 | } 197 | 198 | Process 199 | { 200 | Write-Host "Updating Textblock '$($PSBoundParameters.BlockName)'" 201 | $ColorName=([System.Drawing.Color]::$DynColor).Name 202 | $a=$hash.window.Dispatcher.CheckAccess() 203 | write-host "TextBlock Needs invoke:" $($a -eq $false) 204 | $TextBlock=$hash.window.FindName("$BlockName"); $TextBlock.Text=$Text; $TextBlock.Foreground="$($PSBoundParameters.DynColor)" 205 | Write-Host "-----------" 206 | 207 | <# 208 | $hash.Window.Dispatcher.invoke( 209 | [action]{$TextBlock=$hash.window.FindName("$BlockName"); $TextBlock.Text=$Text; $TextBlock.Foreground="$($PSBoundParameters.DynColor)" 210 | }, 211 | "Normal" 212 | ) 213 | #> 214 | } 215 | } 216 | 217 | Function Set-FinalScreen{ 218 | 219 | try 220 | { 221 | ChangeSpinnerColor -RingColor Yellow #Invoke is handled within the function 222 | $d=$hash.Window.Dispatcher.Invoke( 223 | { 224 | ChangeTextBlock -BlockName "TextBlock1" -Text "Thank you for watching" -DynColor Yellow 225 | } 226 | ), 227 | "Normal" 228 | 229 | SetBackgroundToPic -ImagePath 'https://www.groovypost.com/wp-content/uploads/2019/01/computer_update_windows_PC_admin_Featured.jpg' 230 | Start-Sleep -Seconds 6 231 | #$d=$hash.Window.Dispatcher.Invoke( 232 | $hash.Window.Dispatcher.Invoke( 233 | { 234 | SetBackgroundToPic -ImagePath $PSScriptRoot\bliss.jpg 235 | 236 | ChangeTextBlock -BlockName "TextBlock1" -Text "Thank you for watching" -DynColor Black 237 | 238 | ChangeSpinnerColor -RingColor Black #Invoke is handled within the function 239 | 240 | } 241 | ), 242 | "Normal" 243 | } 244 | catch 245 | { 246 | write-host $_ 247 | } 248 | 249 | } 250 | 251 | function Start-SplashScreen{ 252 | $Powershell.Runspace = $script:runspace 253 | $script:handle = $script:Powershell.BeginInvoke() 254 | Start-Sleep -Seconds 1 255 | } 256 | 257 | function Close-SplashScreen (){ 258 | $hash.window.Dispatcher.Invoke("Normal",[action]{ $hash.window.close() }) 259 | $Powershell.EndInvoke($handle) | Out-Null 260 | $runspace.Close() | Out-Null 261 | } 262 | 263 | Function New-Splash 264 | { 265 | Param ( 266 | [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] 267 | [int]$Width, 268 | [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] 269 | [int]$Height 270 | ) 271 | 272 | Add-Type -AssemblyName PresentationFramework, System.Drawing, System.Windows.Forms, WindowsFormsIntegration 273 | 274 | $Load=("$PSScriptRoot\assembly\MahApps.Metro.dll") 275 | [System.Reflection.Assembly]::LoadFrom($Load) |Out-Null 276 | 277 | $script:hash = [hashtable]::Synchronized(@{}) 278 | $script:runspace = [runspacefactory]::CreateRunspace() 279 | $Runspace.ApartmentState = "STA" 280 | $Runspace.ThreadOptions = "ReuseThread" 281 | $Runspace.Open() 282 | $Runspace.SessionStateProxy.SetVariable("hash",$hash) 283 | $Runspace.SessionStateProxy.SetVariable("Width",$Width) 284 | $Runspace.SessionStateProxy.SetVariable("Height",$Height) 285 | 286 | $script:Powershell = [PowerShell]::Create() 287 | 288 | $Script={ 289 | 290 | $WindowHeight= $Height*1.20 291 | $WindowWidth=$Width*1.20 292 | 293 | [XML]$Xaml = @" 294 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | "@ 307 | 308 | $reader = New-Object System.Xml.XmlNodeReader $Xaml 309 | $hash.window = [Windows.Markup.XamlReader]::Load($reader) 310 | $hash.window.AllowsTransparency=$true 311 | $hash.window.WindowStyle = [System.Windows.WindowStyle]::None 312 | $hash.window.ResizeMode = [System.Windows.ResizeMode]::NoResize 313 | $hash.window.Topmost = $True 314 | $hash.window.WindowStartupLocation= [System.Windows.WindowStartupLocation]::CenterScreen 315 | 316 | $Grid=$hash.window.FindName("Main") 317 | $Grid.Height=$Height 318 | $Grid.Width=$Width 319 | 320 | 321 | # Add a progress ring 322 | $ProgressRing = [MahApps.Metro.Controls.ProgressRing]::new() 323 | $ProgressRing.Name="Ring" 324 | $ProgressRing.Foreground="DimGray" 325 | $ProgressRing.Opacity = 1 326 | $ProgressRing.IsActive = $true 327 | $ProgressRing.Margin = "0,0,0,10" 328 | $ProgressRing.Height=90 329 | $ProgressRing.Width=90 330 | 331 | $ProgressRing.VerticalAlignment=[System.Windows.VerticalAlignment]::Center 332 | $Grid.AddChild($ProgressRing) 333 | $ProgressRing.RegisterName("Ring",$ProgressRing) 334 | $ProgressRing.SetValue([System.Windows.Controls.Grid]::RowProperty,1) 335 | $hash.window.Add_Closing({[System.Windows.Forms.Application]::Exit()}) 336 | 337 | $TextBlock = New-Object System.Windows.Controls.TextBlock 338 | $TextBlock.Name="TextBlock1" 339 | $TextBlock.TextAlignment=[System.Windows.TextAlignment]::Center 340 | $TextBlock.Foreground="DimGray" 341 | $TextBlock.Margin = "0,0,0,20" 342 | $TextBlock.FontSize=22 343 | $TextBlock.Text = "Run Code after 'ShowDialog'" 344 | $TextBlock.HorizontalAlignment=[System.Windows.HorizontalAlignment]::Center 345 | $TextBlock.VerticalAlignment=[System.Windows.VerticalAlignment]::Bottom 346 | $Grid.AddChild($TextBlock) 347 | $TextBlock.RegisterName("TextBlock1",$TextBlock) 348 | 349 | $Grid.RegisterName("Grid1",$Grid) 350 | $hash.window.ShowDialog() 351 | $hash.window.Activate() 352 | } 353 | 354 | $Powershell.AddScript($Script) | Out-Null 355 | write-host $Height 356 | write-host "Loading complete" 357 | 358 | } 359 | 360 | ################## POC MAIN ################## 361 | 362 | New-Splash -Width 600 -Height 240 363 | Start-SplashScreen 364 | $arrSet = [System.Drawing.Brushes] | Get-Member -Static -MemberType Property | Select -ExpandProperty Name 365 | $arrSet=$arrSet | Where-Object {$_ -like "A*" -or $_ -like "B*"} 366 | 367 | 368 | foreach ($color in $arrSet) 369 | { 370 | ChangeBgColor -Color $color 371 | $random=Get-Random -Minimum 450 -Maximum 700 372 | Start-Sleep -Milliseconds $random 373 | } 374 | 375 | 376 | Write-Host "---------------" 377 | 378 | 379 | Set-FinalScreen 380 | Start-Sleep -Seconds 10 381 | Close-SplashScreen 382 | write-host "Closed and done" 383 | 384 | 385 | -------------------------------------------------------------------------------- /General/RunCodeAfterShowDialog/assembly/MahApps.Metro.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/General/RunCodeAfterShowDialog/assembly/MahApps.Metro.dll -------------------------------------------------------------------------------- /General/RunCodeAfterShowDialog/assembly/System.Windows.Interactivity.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/General/RunCodeAfterShowDialog/assembly/System.Windows.Interactivity.dll -------------------------------------------------------------------------------- /General/RunCodeAfterShowDialog/bliss.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/General/RunCodeAfterShowDialog/bliss.jpg -------------------------------------------------------------------------------- /General/UserSid-Converter.ps1: -------------------------------------------------------------------------------- 1 | Param 2 | ( 3 | $in 4 | ) 5 | 6 | $NumOfParams = 1 7 | #write-host $PSBoundParameters.Count 8 | If (($PSBoundParameters.values | Measure-Object | Select-Object -ExpandProperty Count) -lt $NumOfParams){Write-Host "Wrong number of arguments." ;Exit } 9 | 10 | If ($in -match "s-*-*-*-") 11 | { 12 | $objSID = New-Object System.Security.Principal.SecurityIdentifier ($in) 13 | $objUser = $objSID.Translate( [System.Security.Principal.NTAccount]) 14 | return $objUser.Value 15 | } 16 | else{ 17 | $AdObj = New-Object System.Security.Principal.NTAccount($in) 18 | $strSID = $AdObj.Translate([System.Security.Principal.SecurityIdentifier]) 19 | return $strSID.Value 20 | } 21 | -------------------------------------------------------------------------------- /General/WaitForDHCP.ps1: -------------------------------------------------------------------------------- 1 | #Done this way in order to work in WinPE 2 | 3 | $ip=[System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties() 4 | while (!($IPv4=$ip.GetUnicastAddresses() | ? Address -ne 127.0.0.1 |? Address -like '*.*.*.*'| ? SuffixOrigin -eq "OriginDhcp")){sleep -Milliseconds 3000} 5 | write-host "DHCP-Address:" $IPv4.Address.ToString() -------------------------------------------------------------------------------- /General/test-port.ps1: -------------------------------------------------------------------------------- 1 | #Used in WinPE due to lack of nslookup 2 | Param ( 3 | [Parameter(ValueFromPipelineByPropertyName,Mandatory=$True)] 4 | [string] $Hostname, 5 | [Parameter(ValueFromPipelineByPropertyName,Mandatory=$true)] 6 | [string] $Port 7 | ) 8 | 9 | function Test-Port($hostname, $port) 10 | { 11 | try { 12 | $ip = [System.Net.Dns]::GetHostAddresses($hostname) | 13 | select-object IPAddressToString -expandproperty IPAddressToString 14 | if($ip.GetType().Name -eq "Object[]") 15 | { 16 | $ip = $ip[0] 17 | } 18 | } catch { 19 | Write-Host "DNS lookup for $hostname failed." 20 | return $false 21 | } 22 | $t = New-Object Net.Sockets.TcpClient 23 | try 24 | { 25 | $t.Connect($ip,$port) 26 | } catch {} 27 | 28 | if($t.Connected) 29 | { 30 | $t.Close() 31 | $msg = "Successfully connected to $hostname on port $port." 32 | } 33 | else 34 | { 35 | $msg = "Failed to connect to $hostname on port $port." 36 | return $false 37 | } 38 | Write-Host $msg 39 | return $true 40 | } 41 | 42 | Test-Port $Hostname $Port -------------------------------------------------------------------------------- /KeyCheck/KeyCheck.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/KeyCheck/KeyCheck.exe -------------------------------------------------------------------------------- /KeyCheck/KeyCheck.vshost.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/KeyCheck/KeyCheck.vshost.exe -------------------------------------------------------------------------------- /KeyCheck/KeyCheckNoBiosKey.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/KeyCheck/KeyCheckNoBiosKey.exe -------------------------------------------------------------------------------- /KeyCheck/MS.ErrorReporting.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/KeyCheck/MS.ErrorReporting.dll -------------------------------------------------------------------------------- /KeyCheck/System.Xml.Linq.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/KeyCheck/System.Xml.Linq.dll -------------------------------------------------------------------------------- /KeyCheck/adminui.wqlqueryengine.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/KeyCheck/adminui.wqlqueryengine.dll -------------------------------------------------------------------------------- /KeyCheck/microsoft.configurationmanagement.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/KeyCheck/microsoft.configurationmanagement.dll -------------------------------------------------------------------------------- /KeyCheck/microsoft.configurationmanagement.managementprovider.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/KeyCheck/microsoft.configurationmanagement.managementprovider.dll -------------------------------------------------------------------------------- /KeyCheck/pidgenx.dll.old: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/KeyCheck/pidgenx.dll.old -------------------------------------------------------------------------------- /KeyCheck/pidgenx64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/KeyCheck/pidgenx64.dll -------------------------------------------------------------------------------- /KeyCheck/pidgenx64org.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/KeyCheck/pidgenx64org.dll -------------------------------------------------------------------------------- /KeyCheck/pidgenx86.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/KeyCheck/pidgenx86.dll -------------------------------------------------------------------------------- /KeyCheck/pidgenx86org.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/KeyCheck/pidgenx86org.dll -------------------------------------------------------------------------------- /KeyCheck/pkeys/5112.XML: -------------------------------------------------------------------------------- 1 | XrML 2.1 License - Product Key ConfigurationrVrjQYThq2cup6hPcNFQe3huWD4=nr5ON0pvFGqSJgLCe6KLntpLQhIPUoW8nIJ89UKXtXKM25JzF/fhtKzfEUUw5FDNxX9nIE9liMBcjhirQWLg4Y8Z5X8WXgde2pq9SE/qcR/8HrgShqaSYoUzgq250zC7q/iIbK0ypQZSv1PqUAo+5UKb0s9rIKvRh4DmrBSLkBU=0XXqaK0a0x8lxj3IAqr0pF/nXcEkDB960VvxQRr1EH6PvWwjw2GnndCN9faiP8edawk/mrANb/HGsm8i8fKi0uFPaOC9+7vjlUGVSCyaRuD/ajfhljmYkSOgsO+tuHRIuj+kYrIzddLNrlHQIiYKZyP97GStOz+BsUeYT4ecGk0=AQAB2005-02-17T20:21:50Zmsft:sl/PKEYCONFIG/SIGNED2.0PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/Pg0KPHBrYzpQcm9kdWN0S2V5Q29uZmlndXJhdGlvbiB4bWxuczpwa2M9Imh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9EUk0vUEtFWS9Db25maWd1cmF0aW9uLzIuMCI+DQoJPHBrYzpDb25maWd1cmF0aW9ucz4NCgkJPHBrYzpDb25maWd1cmF0aW9uPg0KCQkJPHBrYzpBY3RDb25maWdJZD57ZWY4MjUxYjAtNWYxNi00ZmRmLWIzMGEtOWJlMjI4NmQxNTA5fTwvcGtjOkFjdENvbmZpZ0lkPg0KCQkJPHBrYzpSZWZHcm91cElkPjExNjwvcGtjOlJlZkdyb3VwSWQ+DQoJCQk8cGtjOlByb2R1Y3RGYW1pbHk+V2luZG93czwvcGtjOlByb2R1Y3RGYW1pbHk+DQoJCQk8cGtjOlByb2R1Y3RGYW1pbHlDb2RlPkxIUDwvcGtjOlByb2R1Y3RGYW1pbHlDb2RlPg0KCQkJPHBrYzpQcm9kdWN0TmFtZT5Mb25naG9ybiAmbHQ7TWVnYSZndDsgU0tVPC9wa2M6UHJvZHVjdE5hbWU+DQoJCQk8cGtjOlByb2R1Y3RWZXJzaW9uPjYuMDwvcGtjOlByb2R1Y3RWZXJzaW9uPg0KCQkJPHBrYzpQcm9kdWN0VmVyc2lvbkNvZGU+Tk9OPC9wa2M6UHJvZHVjdFZlcnNpb25Db2RlPg0KCQkJPHBrYzpQcm9kdWN0RGVzY3JpcHRpb24+V1BBLCBCMSwgVHJpYWwsIEV2YWwgRGVtbzwvcGtjOlByb2R1Y3REZXNjcmlwdGlvbj4NCgkJCTxwa2M6UHJvZHVjdEtleVR5cGU+UmV0YWlsPC9wa2M6UHJvZHVjdEtleVR5cGU+DQoJCQk8cGtjOklzUmFuZG9taXplZD5mYWxzZTwvcGtjOklzUmFuZG9taXplZD4NCgkJPC9wa2M6Q29uZmlndXJhdGlvbj4NCgk8L3BrYzpDb25maWd1cmF0aW9ucz4NCgk8cGtjOktleVJhbmdlcz4NCgkJPHBrYzpLZXlSYW5nZT4NCgkJCTxwa2M6UmVmQWN0Q29uZmlnSWQ+e2VmODI1MWIwLTVmMTYtNGZkZi1iMzBhLTliZTIyODZkMTUwOX08L3BrYzpSZWZBY3RDb25maWdJZD4NCgkJCTxwa2M6UGFydE51bWJlcj5YMDAtMDAwMDE8L3BrYzpQYXJ0TnVtYmVyPg0KCQkJPHBrYzpJc1ZhbGlkPnRydWU8L3BrYzpJc1ZhbGlkPg0KCQkJPHBrYzpTdGFydD4xMDAwMDAwMDA8L3BrYzpTdGFydD4NCgkJCTxwa2M6RW5kPjEwMTk5OTk5OTwvcGtjOkVuZD4NCgkJPC9wa2M6S2V5UmFuZ2U+DQoJCTxwa2M6S2V5UmFuZ2U+DQoJCQk8cGtjOlJlZkFjdENvbmZpZ0lkPntlZjgyNTFiMC01ZjE2LTRmZGYtYjMwYS05YmUyMjg2ZDE1MDl9PC9wa2M6UmVmQWN0Q29uZmlnSWQ+DQoJCQk8cGtjOlBhcnROdW1iZXI+WDAwLTAwMDAyPC9wa2M6UGFydE51bWJlcj4NCgkJCTxwa2M6SXNWYWxpZD50cnVlPC9wa2M6SXNWYWxpZD4NCgkJCTxwa2M6U3RhcnQ+MTAzMDAwMDAwPC9wa2M6U3RhcnQ+DQoJCQk8cGtjOkVuZD4xMDM5OTk5OTk8L3BrYzpFbmQ+DQoJCTwvcGtjOktleVJhbmdlPg0KCQk8cGtjOktleVJhbmdlPg0KCQkJPHBrYzpSZWZBY3RDb25maWdJZD57ZWY4MjUxYjAtNWYxNi00ZmRmLWIzMGEtOWJlMjI4NmQxNTA5fTwvcGtjOlJlZkFjdENvbmZpZ0lkPg0KCQkJPHBrYzpQYXJ0TnVtYmVyPlgwMC0wMDAwMzwvcGtjOlBhcnROdW1iZXI+DQoJCQk8cGtjOklzVmFsaWQ+dHJ1ZTwvcGtjOklzVmFsaWQ+DQoJCQk8cGtjOlN0YXJ0PjEwNDAwMDAwMDwvcGtjOlN0YXJ0Pg0KCQkJPHBrYzpFbmQ+MTA0MDAwMDAwPC9wa2M6RW5kPg0KCQk8L3BrYzpLZXlSYW5nZT4NCgkJPHBrYzpLZXlSYW5nZT4NCgkJCTxwa2M6UmVmQWN0Q29uZmlnSWQ+e2VmODI1MWIwLTVmMTYtNGZkZi1iMzBhLTliZTIyODZkMTUwOX08L3BrYzpSZWZBY3RDb25maWdJZD4NCgkJCTxwa2M6UGFydE51bWJlcj5YMDAtMDAwMDc8L3BrYzpQYXJ0TnVtYmVyPg0KCQkJPHBrYzpJc1ZhbGlkPnRydWU8L3BrYzpJc1ZhbGlkPg0KCQkJPHBrYzpTdGFydD4xMDUwMDAwMDA8L3BrYzpTdGFydD4NCgkJCTxwa2M6RW5kPjEwNTk5OTk5OTwvcGtjOkVuZD4NCgkJPC9wa2M6S2V5UmFuZ2U+DQoJCTxwa2M6S2V5UmFuZ2U+DQoJCQk8cGtjOlJlZkFjdENvbmZpZ0lkPntlZjgyNTFiMC01ZjE2LTRmZGYtYjMwYS05YmUyMjg2ZDE1MDl9PC9wa2M6UmVmQWN0Q29uZmlnSWQ+DQoJCQk8cGtjOlBhcnROdW1iZXI+WDAwLTAwMDA4PC9wa2M6UGFydE51bWJlcj4NCgkJCTxwa2M6SXNWYWxpZD50cnVlPC9wa2M6SXNWYWxpZD4NCgkJCTxwa2M6U3RhcnQ+MTA2MDAwMDAwPC9wa2M6U3RhcnQ+DQoJCQk8cGtjOkVuZD4xMDY5OTk5OTk8L3BrYzpFbmQ+DQoJCTwvcGtjOktleVJhbmdlPg0KCQk8cGtjOktleVJhbmdlPg0KCQkJPHBrYzpSZWZBY3RDb25maWdJZD57ZWY4MjUxYjAtNWYxNi00ZmRmLWIzMGEtOWJlMjI4NmQxNTA5fTwvcGtjOlJlZkFjdENvbmZpZ0lkPg0KCQkJPHBrYzpQYXJ0TnVtYmVyPlgwMC0wMDAwOTwvcGtjOlBhcnROdW1iZXI+DQoJCQk8cGtjOklzVmFsaWQ+dHJ1ZTwvcGtjOklzVmFsaWQ+DQoJCQk8cGtjOlN0YXJ0PjEwNzAwMDAwMDwvcGtjOlN0YXJ0Pg0KCQkJPHBrYzpFbmQ+MTA3OTk5OTk5PC9wa2M6RW5kPg0KCQk8L3BrYzpLZXlSYW5nZT4NCgkJPHBrYzpLZXlSYW5nZT4NCgkJCTxwa2M6UmVmQWN0Q29uZmlnSWQ+e2VmODI1MWIwLTVmMTYtNGZkZi1iMzBhLTliZTIyODZkMTUwOX08L3BrYzpSZWZBY3RDb25maWdJZD4NCgkJCTxwa2M6UGFydE51bWJlcj5YMDAtMDAwMDU8L3BrYzpQYXJ0TnVtYmVyPg0KCQkJPHBrYzpJc1ZhbGlkPnRydWU8L3BrYzpJc1ZhbGlkPg0KCQkJPHBrYzpTdGFydD4xMTIwMDAwMDA8L3BrYzpTdGFydD4NCgkJCTxwa2M6RW5kPjExNDAwMDAwMDwvcGtjOkVuZD4NCgkJPC9wa2M6S2V5UmFuZ2U+DQoJCTxwa2M6S2V5UmFuZ2U+DQoJCQk8cGtjOlJlZkFjdENvbmZpZ0lkPntlZjgyNTFiMC01ZjE2LTRmZGYtYjMwYS05YmUyMjg2ZDE1MDl9PC9wa2M6UmVmQWN0Q29uZmlnSWQ+DQoJCQk8cGtjOlBhcnROdW1iZXI+WDExLTE0Mjk5PC9wa2M6UGFydE51bWJlcj4NCgkJCTxwa2M6SXNWYWxpZD50cnVlPC9wa2M6SXNWYWxpZD4NCgkJCTxwa2M6U3RhcnQ+MTE3MDAwMDAwPC9wa2M6U3RhcnQ+DQoJCQk8cGtjOkVuZD4xMTg5OTk5OTk8L3BrYzpFbmQ+DQoJCTwvcGtjOktleVJhbmdlPg0KCQk8cGtjOktleVJhbmdlPg0KCQkJPHBrYzpSZWZBY3RDb25maWdJZD57ZWY4MjUxYjAtNWYxNi00ZmRmLWIzMGEtOWJlMjI4NmQxNTA5fTwvcGtjOlJlZkFjdENvbmZpZ0lkPg0KCQkJPHBrYzpQYXJ0TnVtYmVyPlgxMS0xNDMwMDwvcGtjOlBhcnROdW1iZXI+DQoJCQk8cGtjOklzVmFsaWQ+dHJ1ZTwvcGtjOklzVmFsaWQ+DQoJCQk8cGtjOlN0YXJ0PjExOTAwMDAwMDwvcGtjOlN0YXJ0Pg0KCQkJPHBrYzpFbmQ+MTIwOTk5OTk5PC9wa2M6RW5kPg0KCQk8L3BrYzpLZXlSYW5nZT4NCgkJPHBrYzpLZXlSYW5nZT4NCgkJCTxwa2M6UmVmQWN0Q29uZmlnSWQ+e2VmODI1MWIwLTVmMTYtNGZkZi1iMzBhLTliZTIyODZkMTUwOX08L3BrYzpSZWZBY3RDb25maWdJZD4NCgkJCTxwa2M6UGFydE51bWJlcj5YMTEtMTQzMDE8L3BrYzpQYXJ0TnVtYmVyPg0KCQkJPHBrYzpJc1ZhbGlkPnRydWU8L3BrYzpJc1ZhbGlkPg0KCQkJPHBrYzpTdGFydD4xMjEwMDAwMDA8L3BrYzpTdGFydD4NCgkJCTxwa2M6RW5kPjEyMjk5OTk5OTwvcGtjOkVuZD4NCgkJPC9wa2M6S2V5UmFuZ2U+DQoJCTxwa2M6S2V5UmFuZ2U+DQoJCQk8cGtjOlJlZkFjdENvbmZpZ0lkPntlZjgyNTFiMC01ZjE2LTRmZGYtYjMwYS05YmUyMjg2ZDE1MDl9PC9wa2M6UmVmQWN0Q29uZmlnSWQ+DQoJCQk8cGtjOlBhcnROdW1iZXI+WDExLTE0MzAyPC9wa2M6UGFydE51bWJlcj4NCgkJCTxwa2M6SXNWYWxpZD50cnVlPC9wa2M6SXNWYWxpZD4NCgkJCTxwa2M6U3RhcnQ+MTIzMDAwMDAwPC9wa2M6U3RhcnQ+DQoJCQk8cGtjOkVuZD4xMjMwMDAxMDA8L3BrYzpFbmQ+DQoJCTwvcGtjOktleVJhbmdlPg0KCQk8cGtjOktleVJhbmdlPg0KCQkJPHBrYzpSZWZBY3RDb25maWdJZD57ZWY4MjUxYjAtNWYxNi00ZmRmLWIzMGEtOWJlMjI4NmQxNTA5fTwvcGtjOlJlZkFjdENvbmZpZ0lkPg0KCQkJPHBrYzpQYXJ0TnVtYmVyPlgxMS0xNDMwMjwvcGtjOlBhcnROdW1iZXI+DQoJCQk8cGtjOklzVmFsaWQ+dHJ1ZTwvcGtjOklzVmFsaWQ+DQoJCQk8cGtjOlN0YXJ0PjEyMzAwMDIwMDwvcGtjOlN0YXJ0Pg0KCQkJPHBrYzpFbmQ+MTI0OTk5OTk5PC9wa2M6RW5kPg0KCQk8L3BrYzpLZXlSYW5nZT4NCgk8L3BrYzpLZXlSYW5nZXM+DQoJPHBrYzpQdWJsaWNLZXlzPg0KCQk8cGtjOlB1YmxpY0tleT4NCgkJCTxwa2M6R3JvdXBJZD4xMTY8L3BrYzpHcm91cElkPg0KCQkJPHBrYzpBbGdvcml0aG1JZD5tc2Z0OnJtL2FsZ29yaXRobS9wa2V5Lzk4NjwvcGtjOkFsZ29yaXRobUlkPg0KCQkJPHBrYzpQdWJsaWNLZXlWYWx1ZT41QUVBQUFrQUFBRFd2ZDJSeEh3eEFSQUFBQUFmQUFBQVBnQUFBQW9BQUFBVUFBQUFTWFhTYnNwRyt0ZTJRS0ZPRUo5aWlQcmtad1JJSzRlQXpxKytMRFlzQVR4TW5FNHJnS0o5QUJEZUJqS3hBQWhjK2JNYm9nTG10NlhxbDMxY2tvUWNpUUVBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBSkhEMEl3SE45MTFTdUY1eXc3dWhPci9WNCtFT0tSMmVtTytpM2lHcjZuM3FGaDhEWGFVRUg2cXpWUGJ1OUtUdXlrelZIWHJURm1GZWhzcWtwQmJ2Q1F3NFZCQXNra3ZvbGdHRG02REtLU2pLazFwdlNDZG5HREZpT1dvMG5HL1docm5nOWFCVFlLRElMdEN2em1oc20xczhnVzIybWVPcFVnUUdZL2hnQWxmOWFLdzlmR3M2MXA4bm9BVXdySHk5bTRuOVdBbVArTDJEU1JMTnk1V3FvdjF1b2xobzcrbk1WbC95SFdYQ1I0d24rbHk1a0JpOWtJTXVyVXJLSW1JaHpwc0xYc3ZBR1RPb2hXY1c1SnFSMVFXRWQvcFdHdFRTb2cxV3hDaHdkU1c0T042V1IvVnl6Y3B4d3dOMFhwaDQ2R3hsYnlwQnVhUHB0WjkwQ1VvQWdnPT08L3BrYzpQdWJsaWNLZXlWYWx1ZT4NCgkJPC9wa2M6UHVibGljS2V5Pg0KCTwvcGtjOlB1YmxpY0tleXM+DQo8L3BrYzpQcm9kdWN0S2V5Q29uZmlndXJhdGlvbj4= -------------------------------------------------------------------------------- /KeyCheck/pkeys/5219.xml: -------------------------------------------------------------------------------- 1 | XrML 2.1 License - Product Key ConfigurationSxQjvuuqWV8KdN+8KfK1HMIjE3o=ZsdkxZDjTAMeRAXanzo9s185Y1QbjwCJ/ZK0Y3b1q8yymWKWvyIUq0y2rSHAkLqYPr3UXyt6T00m0lXusedXvtfco436RL5UM75maGFsvb3v3GUP5X2OX2hDdD6EpMb7uv9Xn4F5U4th21TiRh0iFD8y9blPZn8wOxOFX8S3dQs=0XXqaK0a0x8lxj3IAqr0pF/nXcEkDB960VvxQRr1EH6PvWwjw2GnndCN9faiP8edawk/mrANb/HGsm8i8fKi0uFPaOC9+7vjlUGVSCyaRuD/ajfhljmYkSOgsO+tuHRIuj+kYrIzddLNrlHQIiYKZyP97GStOz+BsUeYT4ecGk0=AQABmsft:sl/PKEYCONFIG/SIGNED2.0PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/Pg0KPHBrYzpQcm9kdWN0S2V5Q29uZmlndXJhdGlvbiB4bWxuczpwa2M9Imh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9EUk0vUEtFWS9Db25maWd1cmF0aW9uLzIuMCI+DQoJPHBrYzpDb25maWd1cmF0aW9ucz4NCgkJPHBrYzpDb25maWd1cmF0aW9uPg0KCQkJPHBrYzpBY3RDb25maWdJZD57M2EzNTEyNTktY2Q3NC00ZTZlLTllODUtODIwNjg3YmJkMzM3fTwvcGtjOkFjdENvbmZpZ0lkPg0KCQkJPHBrYzpSZWZHcm91cElkPjExNjwvcGtjOlJlZkdyb3VwSWQ+DQoJCQk8cGtjOkVkaXRpb25JZD5TdGFydGVyPC9wa2M6RWRpdGlvbklkPg0KCQkJPHBrYzpQcm9kdWN0RGVzY3JpcHRpb24+TG9uZ2hvcm4gU3RhcnRlciBFZGl0aW9uPC9wa2M6UHJvZHVjdERlc2NyaXB0aW9uPg0KCQkJPHBrYzpQcm9kdWN0S2V5VHlwZT5SZXRhaWw8L3BrYzpQcm9kdWN0S2V5VHlwZT4NCgkJCTxwa2M6SXNSYW5kb21pemVkPmZhbHNlPC9wa2M6SXNSYW5kb21pemVkPg0KCQk8L3BrYzpDb25maWd1cmF0aW9uPg0KCQk8cGtjOkNvbmZpZ3VyYXRpb24+DQoJCQk8cGtjOkFjdENvbmZpZ0lkPntjMGJlODZkNS1jMTJlLTQ2NTgtODgwYy0zMDc5YTJiNzBhNDJ9PC9wa2M6QWN0Q29uZmlnSWQ+DQoJCQk8cGtjOlJlZkdyb3VwSWQ+MTE2PC9wa2M6UmVmR3JvdXBJZD4NCgkJCTxwa2M6RWRpdGlvbklkPkhvbWVCYXNpYzwvcGtjOkVkaXRpb25JZD4NCgkJCTxwa2M6UHJvZHVjdERlc2NyaXB0aW9uPkxvbmdob3JuIEhvbWUgQmFzaWM8L3BrYzpQcm9kdWN0RGVzY3JpcHRpb24+DQoJCQk8cGtjOlByb2R1Y3RLZXlUeXBlPlJldGFpbDwvcGtjOlByb2R1Y3RLZXlUeXBlPg0KCQkJPHBrYzpJc1JhbmRvbWl6ZWQ+ZmFsc2U8L3BrYzpJc1JhbmRvbWl6ZWQ+DQoJCTwvcGtjOkNvbmZpZ3VyYXRpb24+DQoJCTxwa2M6Q29uZmlndXJhdGlvbj4NCgkJCTxwa2M6QWN0Q29uZmlnSWQ+ezZhNDI2ZWVkLTQ0MGUtNGRjYy04NjYxLTJiMDczMWVmNzY0Zn08L3BrYzpBY3RDb25maWdJZD4NCgkJCTxwa2M6UmVmR3JvdXBJZD4xMTY8L3BrYzpSZWZHcm91cElkPg0KCQkJPHBrYzpFZGl0aW9uSWQ+SG9tZVByZW1pdW08L3BrYzpFZGl0aW9uSWQ+DQoJCQk8cGtjOlByb2R1Y3REZXNjcmlwdGlvbj5Mb25naG9ybiBIb21lIFByZW1pdW08L3BrYzpQcm9kdWN0RGVzY3JpcHRpb24+DQoJCQk8cGtjOlByb2R1Y3RLZXlUeXBlPlJldGFpbDwvcGtjOlByb2R1Y3RLZXlUeXBlPg0KCQkJPHBrYzpJc1JhbmRvbWl6ZWQ+ZmFsc2U8L3BrYzpJc1JhbmRvbWl6ZWQ+DQoJCTwvcGtjOkNvbmZpZ3VyYXRpb24+DQoJCTxwa2M6Q29uZmlndXJhdGlvbj4NCgkJCTxwa2M6QWN0Q29uZmlnSWQ+e2VmODI1MWIwLTVmMTYtNGZkZi1iMzBhLTliZTIyODZkMTUwOX08L3BrYzpBY3RDb25maWdJZD4NCgkJCTxwa2M6UmVmR3JvdXBJZD4xMTY8L3BrYzpSZWZHcm91cElkPg0KCQkJPHBrYzpFZGl0aW9uSWQ+VWx0aW1hdGU8L3BrYzpFZGl0aW9uSWQ+DQoJCQk8cGtjOlByb2R1Y3REZXNjcmlwdGlvbj5Mb25naG9ybiBVbHRpbWF0ZTwvcGtjOlByb2R1Y3REZXNjcmlwdGlvbj4NCgkJCTxwa2M6UHJvZHVjdEtleVR5cGU+UmV0YWlsPC9wa2M6UHJvZHVjdEtleVR5cGU+DQoJCQk8cGtjOklzUmFuZG9taXplZD5mYWxzZTwvcGtjOklzUmFuZG9taXplZD4NCgkJPC9wa2M6Q29uZmlndXJhdGlvbj4NCgkJPHBrYzpDb25maWd1cmF0aW9uPg0KCQkJPHBrYzpBY3RDb25maWdJZD57Mjc3Zjk3YzctZmZkZS00N2RhLWI3YzQtNjQ1MWJkMDBmMmVjfTwvcGtjOkFjdENvbmZpZ0lkPg0KCQkJPHBrYzpSZWZHcm91cElkPjExNjwvcGtjOlJlZkdyb3VwSWQ+DQoJCQk8cGtjOkVkaXRpb25JZD5Qcm9TdGFuZGFyZDwvcGtjOkVkaXRpb25JZD4NCgkJCTxwa2M6UHJvZHVjdERlc2NyaXB0aW9uPkxvbmdob3JuIFBybyBTdGFuZGFyZC9TQlM8L3BrYzpQcm9kdWN0RGVzY3JpcHRpb24+DQoJCQk8cGtjOlByb2R1Y3RLZXlUeXBlPlJldGFpbDwvcGtjOlByb2R1Y3RLZXlUeXBlPg0KCQkJPHBrYzpJc1JhbmRvbWl6ZWQ+ZmFsc2U8L3BrYzpJc1JhbmRvbWl6ZWQ+DQoJCTwvcGtjOkNvbmZpZ3VyYXRpb24+DQoJCTxwa2M6Q29uZmlndXJhdGlvbj4NCgkJCTxwa2M6QWN0Q29uZmlnSWQ+e2M5ZGE1ZDEzLTcwYTUtNDAyMy1hYjFlLWVlOTQxNWMyYzQ3Nn08L3BrYzpBY3RDb25maWdJZD4NCgkJCTxwa2M6UmVmR3JvdXBJZD4xMTY8L3BrYzpSZWZHcm91cElkPg0KCQkJPHBrYzpFZGl0aW9uSWQ+U2VydmVyRW50ZXJwcmlzZTwvcGtjOkVkaXRpb25JZD4NCgkJCTxwa2M6UHJvZHVjdERlc2NyaXB0aW9uPkxvbmdob3JuIEVudGVycHJpc2UgU2VydmVyPC9wa2M6UHJvZHVjdERlc2NyaXB0aW9uPg0KCQkJPHBrYzpQcm9kdWN0S2V5VHlwZT5SZXRhaWw8L3BrYzpQcm9kdWN0S2V5VHlwZT4NCgkJCTxwa2M6SXNSYW5kb21pemVkPmZhbHNlPC9wa2M6SXNSYW5kb21pemVkPg0KCQk8L3BrYzpDb25maWd1cmF0aW9uPg0KCQk8cGtjOkNvbmZpZ3VyYXRpb24+DQoJCQk8cGtjOkFjdENvbmZpZ0lkPntiZTZmNmQ0YS00Mzc4LTRjNTgtOTc1Ni0zNDlhZmE2ODE4YWN9PC9wa2M6QWN0Q29uZmlnSWQ+DQoJCQk8cGtjOlJlZkdyb3VwSWQ+MTE2PC9wa2M6UmVmR3JvdXBJZD4NCgkJCTxwa2M6RWRpdGlvbklkPm4vYTwvcGtjOkVkaXRpb25JZD4NCgkJCTxwa2M6UHJvZHVjdERlc2NyaXB0aW9uPkxIIFBybyBTdGQvU0JTL0VudCAtIFZMIEJpbmRpbmcgU2VydmljZTwvcGtjOlByb2R1Y3REZXNjcmlwdGlvbj4NCgkJCTxwa2M6UHJvZHVjdEtleVR5cGU+QlNJRDwvcGtjOlByb2R1Y3RLZXlUeXBlPg0KCQkJPHBrYzpJc1JhbmRvbWl6ZWQ+ZmFsc2U8L3BrYzpJc1JhbmRvbWl6ZWQ+DQoJCTwvcGtjOkNvbmZpZ3VyYXRpb24+DQoJCTxwa2M6Q29uZmlndXJhdGlvbj4NCgkJCTxwa2M6QWN0Q29uZmlnSWQ+ezk5ZmY5YjI2LTAxNmEtNDlkMy05ODJlLWZjNDkyZjM1MmU1N308L3BrYzpBY3RDb25maWdJZD4NCgkJCTxwa2M6UmVmR3JvdXBJZD4xMTY8L3BrYzpSZWZHcm91cElkPg0KCQkJPHBrYzpFZGl0aW9uSWQ+UHJvU3RhbmRhcmQ8L3BrYzpFZGl0aW9uSWQ+DQoJCQk8cGtjOlByb2R1Y3REZXNjcmlwdGlvbj5MSCBQcm8gU3RkL1NCUy9FbnQgLSBWTEdlbmVyaWM8L3BrYzpQcm9kdWN0RGVzY3JpcHRpb24+DQoJCQk8cGtjOlByb2R1Y3RLZXlUeXBlPlZvbHVtZTwvcGtjOlByb2R1Y3RLZXlUeXBlPg0KCQkJPHBrYzpJc1JhbmRvbWl6ZWQ+ZmFsc2U8L3BrYzpJc1JhbmRvbWl6ZWQ+DQoJCTwvcGtjOkNvbmZpZ3VyYXRpb24+DQoJCTxwa2M6Q29uZmlndXJhdGlvbj4NCgkJCTxwa2M6QWN0Q29uZmlnSWQ+e2E1ODI5YjI3LTUxMTEtNDViNS04Zjk2LTU4ZjU5YzdjOGUwNn08L3BrYzpBY3RDb25maWdJZD4NCgkJCTxwa2M6UmVmR3JvdXBJZD4xMTY8L3BrYzpSZWZHcm91cElkPg0KCQkJPHBrYzpFZGl0aW9uSWQ+UHJvRW50ZXJwcmlzZTwvcGtjOkVkaXRpb25JZD4NCgkJCTxwa2M6UHJvZHVjdERlc2NyaXB0aW9uPkxIIFBybyBTdGQvU0JTL0VudCAtIERNQUs8L3BrYzpQcm9kdWN0RGVzY3JpcHRpb24+DQoJCQk8cGtjOlByb2R1Y3RLZXlUeXBlPlZvbHVtZTwvcGtjOlByb2R1Y3RLZXlUeXBlPg0KCQkJPHBrYzpJc1JhbmRvbWl6ZWQ+ZmFsc2U8L3BrYzpJc1JhbmRvbWl6ZWQ+DQoJCTwvcGtjOkNvbmZpZ3VyYXRpb24+DQoJCTxwa2M6Q29uZmlndXJhdGlvbj4NCgkJCTxwa2M6QWN0Q29uZmlnSWQ+e2FmNzQzYzlhLWUyOTgtNDE5ZS1hYzQxLWExZmYyMmZmNTU4Yn08L3BrYzpBY3RDb25maWdJZD4NCgkJCTxwa2M6UmVmR3JvdXBJZD4xMTY8L3BrYzpSZWZHcm91cElkPg0KCQkJPHBrYzpFZGl0aW9uSWQ+U3RhcnRlcjwvcGtjOkVkaXRpb25JZD4NCgkJCTxwa2M6UHJvZHVjdERlc2NyaXB0aW9uPkxvbmdob3JuIFN0YXJ0ZXIgRGlnaXRhbCBCb29zdCAtIE9FTTwvcGtjOlByb2R1Y3REZXNjcmlwdGlvbj4NCgkJCTxwa2M6UHJvZHVjdEtleVR5cGU+T0VNPC9wa2M6UHJvZHVjdEtleVR5cGU+DQoJCQk8cGtjOklzUmFuZG9taXplZD5mYWxzZTwvcGtjOklzUmFuZG9taXplZD4NCgkJPC9wa2M6Q29uZmlndXJhdGlvbj4NCgkJPHBrYzpDb25maWd1cmF0aW9uPg0KCQkJPHBrYzpBY3RDb25maWdJZD57YTAxMDNlM2EtOTliZC00MWIxLTg0YzUtNzdjOTg4NTZkNTM4fTwvcGtjOkFjdENvbmZpZ0lkPg0KCQkJPHBrYzpSZWZHcm91cElkPjExNjwvcGtjOlJlZkdyb3VwSWQ+DQoJCQk8cGtjOkVkaXRpb25JZD5Ib21lQmFzaWM8L3BrYzpFZGl0aW9uSWQ+DQoJCQk8cGtjOlByb2R1Y3REZXNjcmlwdGlvbj5Mb25naG9ybiBIb21lIEJhc2ljIC0gT0VNPC9wa2M6UHJvZHVjdERlc2NyaXB0aW9uPg0KCQkJPHBrYzpQcm9kdWN0S2V5VHlwZT5PRU08L3BrYzpQcm9kdWN0S2V5VHlwZT4NCgkJCTxwa2M6SXNSYW5kb21pemVkPmZhbHNlPC9wa2M6SXNSYW5kb21pemVkPg0KCQk8L3BrYzpDb25maWd1cmF0aW9uPg0KCQk8cGtjOkNvbmZpZ3VyYXRpb24+DQoJCQk8cGtjOkFjdENvbmZpZ0lkPns1YTliMDI1My00MWQ5LTQ4MTgtOTRjYS0yNDE1M2EzMzNiYjR9PC9wa2M6QWN0Q29uZmlnSWQ+DQoJCQk8cGtjOlJlZkdyb3VwSWQ+MTE2PC9wa2M6UmVmR3JvdXBJZD4NCgkJCTxwa2M6RWRpdGlvbklkPkhvbWVQcmVtaXVtPC9wa2M6RWRpdGlvbklkPg0KCQkJPHBrYzpQcm9kdWN0RGVzY3JpcHRpb24+TG9uZ2hvcm4gSG9tZSBQcmVtaXVtIC0gT0VNPC9wa2M6UHJvZHVjdERlc2NyaXB0aW9uPg0KCQkJPHBrYzpQcm9kdWN0S2V5VHlwZT5PRU08L3BrYzpQcm9kdWN0S2V5VHlwZT4NCgkJCTxwa2M6SXNSYW5kb21pemVkPmZhbHNlPC9wa2M6SXNSYW5kb21pemVkPg0KCQk8L3BrYzpDb25maWd1cmF0aW9uPg0KCQk8cGtjOkNvbmZpZ3VyYXRpb24+DQoJCQk8cGtjOkFjdENvbmZpZ0lkPns5MjJlOTQwOS1lZTQ1LTQ2NjAtYmE0ZS1hMTc5MmM3YTE5N2F9PC9wa2M6QWN0Q29uZmlnSWQ+DQoJCQk8cGtjOlJlZkdyb3VwSWQ+MTE2PC9wa2M6UmVmR3JvdXBJZD4NCgkJCTxwa2M6RWRpdGlvbklkPlVsdGltYXRlPC9wa2M6RWRpdGlvbklkPg0KCQkJPHBrYzpQcm9kdWN0RGVzY3JpcHRpb24+TG9uZ2hvcm4gVWx0aW1hdGUgLSBPRU08L3BrYzpQcm9kdWN0RGVzY3JpcHRpb24+DQoJCQk8cGtjOlByb2R1Y3RLZXlUeXBlPk9FTTwvcGtjOlByb2R1Y3RLZXlUeXBlPg0KCQkJPHBrYzpJc1JhbmRvbWl6ZWQ+ZmFsc2U8L3BrYzpJc1JhbmRvbWl6ZWQ+DQoJCTwvcGtjOkNvbmZpZ3VyYXRpb24+DQoJCTxwa2M6Q29uZmlndXJhdGlvbj4NCgkJCTxwa2M6QWN0Q29uZmlnSWQ+ezRiYzMyZTJmLTc2YTgtNDFlMi05M2YzLWJkYTdhZDAxMmIzZn08L3BrYzpBY3RDb25maWdJZD4NCgkJCTxwa2M6UmVmR3JvdXBJZD4xMTY8L3BrYzpSZWZHcm91cElkPg0KCQkJPHBrYzpFZGl0aW9uSWQ+UHJvU3RhbmRhcmQ8L3BrYzpFZGl0aW9uSWQ+DQoJCQk8cGtjOlByb2R1Y3REZXNjcmlwdGlvbj5Mb25naG9ybiBQcm8gU3RhbmRhcmQvU0JTIC0gT0VNPC9wa2M6UHJvZHVjdERlc2NyaXB0aW9uPg0KCQkJPHBrYzpQcm9kdWN0S2V5VHlwZT5PRU08L3BrYzpQcm9kdWN0S2V5VHlwZT4NCgkJCTxwa2M6SXNSYW5kb21pemVkPmZhbHNlPC9wa2M6SXNSYW5kb21pemVkPg0KCQk8L3BrYzpDb25maWd1cmF0aW9uPg0KCQk8cGtjOkNvbmZpZ3VyYXRpb24+DQoJCQk8cGtjOkFjdENvbmZpZ0lkPntiOWE2OGM4My0xNmUwLTQ1NDctYTNkNS1lYTRhZDg5OWI2M2V9PC9wa2M6QWN0Q29uZmlnSWQ+DQoJCQk8cGtjOlJlZkdyb3VwSWQ+MTE2PC9wa2M6UmVmR3JvdXBJZD4NCgkJCTxwa2M6RWRpdGlvbklkPlByb1NCUzwvcGtjOkVkaXRpb25JZD4NCgkJCTxwa2M6UHJvZHVjdERlc2NyaXB0aW9uPkxvbmdob3JuIEVudGVycHJpc2UgU2VydmVyIC0gT0VNPC9wa2M6UHJvZHVjdERlc2NyaXB0aW9uPg0KCQkJPHBrYzpQcm9kdWN0S2V5VHlwZT5PRU08L3BrYzpQcm9kdWN0S2V5VHlwZT4NCgkJCTxwa2M6SXNSYW5kb21pemVkPmZhbHNlPC9wa2M6SXNSYW5kb21pemVkPg0KCQk8L3BrYzpDb25maWd1cmF0aW9uPg0KCTwvcGtjOkNvbmZpZ3VyYXRpb25zPg0KCTxwa2M6S2V5UmFuZ2VzPg0KCQk8cGtjOktleVJhbmdlPg0KCQkJPHBrYzpSZWZBY3RDb25maWdJZD57M2EzNTEyNTktY2Q3NC00ZTZlLTllODUtODIwNjg3YmJkMzM3fTwvcGtjOlJlZkFjdENvbmZpZ0lkPg0KCQkJPHBrYzpQYXJ0TnVtYmVyPlgxMS0zODAyMjwvcGtjOlBhcnROdW1iZXI+DQoJCQk8cGtjOklzVmFsaWQ+dHJ1ZTwvcGtjOklzVmFsaWQ+DQoJCQk8cGtjOlN0YXJ0PjEyNzQwMDAwMDwvcGtjOlN0YXJ0Pg0KCQkJPHBrYzpFbmQ+MTI3NTk5OTk5PC9wa2M6RW5kPg0KCQk8L3BrYzpLZXlSYW5nZT4NCgkJPHBrYzpLZXlSYW5nZT4NCgkJCTxwa2M6UmVmQWN0Q29uZmlnSWQ+e2MwYmU4NmQ1LWMxMmUtNDY1OC04ODBjLTMwNzlhMmI3MGE0Mn08L3BrYzpSZWZBY3RDb25maWdJZD4NCgkJCTxwa2M6UGFydE51bWJlcj5YMTEtMzgwMjM8L3BrYzpQYXJ0TnVtYmVyPg0KCQkJPHBrYzpJc1ZhbGlkPnRydWU8L3BrYzpJc1ZhbGlkPg0KCQkJPHBrYzpTdGFydD4xMjcyMDAwMDA8L3BrYzpTdGFydD4NCgkJCTxwa2M6RW5kPjEyNzM5OTk5OTwvcGtjOkVuZD4NCgkJPC9wa2M6S2V5UmFuZ2U+DQoJCTxwa2M6S2V5UmFuZ2U+DQoJCQk8cGtjOlJlZkFjdENvbmZpZ0lkPntlZjgyNTFiMC01ZjE2LTRmZGYtYjMwYS05YmUyMjg2ZDE1MDl9PC9wa2M6UmVmQWN0Q29uZmlnSWQ+DQoJCQk8cGtjOlBhcnROdW1iZXI+WDExLTM4MDI0PC9wa2M6UGFydE51bWJlcj4NCgkJCTxwa2M6SXNWYWxpZD50cnVlPC9wa2M6SXNWYWxpZD4NCgkJCTxwa2M6U3RhcnQ+MTI3MDAwMDAwPC9wa2M6U3RhcnQ+DQoJCQk8cGtjOkVuZD4xMjcxOTk5OTk8L3BrYzpFbmQ+DQoJCTwvcGtjOktleVJhbmdlPg0KCQk8cGtjOktleVJhbmdlPg0KCQkJPHBrYzpSZWZBY3RDb25maWdJZD57YzlkYTVkMTMtNzBhNS00MDIzLWFiMWUtZWU5NDE1YzJjNDc2fTwvcGtjOlJlZkFjdENvbmZpZ0lkPg0KCQkJPHBrYzpQYXJ0TnVtYmVyPlgxMS0zODAyNTwvcGtjOlBhcnROdW1iZXI+DQoJCQk8cGtjOklzVmFsaWQ+dHJ1ZTwvcGtjOklzVmFsaWQ+DQoJCQk8cGtjOlN0YXJ0PjEyNzYwMDAwMDwvcGtjOlN0YXJ0Pg0KCQkJPHBrYzpFbmQ+MTI3Nzk5OTk5PC9wa2M6RW5kPg0KCQk8L3BrYzpLZXlSYW5nZT4NCgkJPHBrYzpLZXlSYW5nZT4NCgkJCTxwa2M6UmVmQWN0Q29uZmlnSWQ+e2VmODI1MWIwLTVmMTYtNGZkZi1iMzBhLTliZTIyODZkMTUwOX08L3BrYzpSZWZBY3RDb25maWdJZD4NCgkJCTxwa2M6UGFydE51bWJlcj5YMTEtMzgwMjQ8L3BrYzpQYXJ0TnVtYmVyPg0KCQkJPHBrYzpJc1ZhbGlkPnRydWU8L3BrYzpJc1ZhbGlkPg0KCQkJPHBrYzpTdGFydD4xMDAwMDcwNDk8L3BrYzpTdGFydD4NCgkJCTxwa2M6RW5kPjEwMDAwNzA0OTwvcGtjOkVuZD4NCgkJPC9wa2M6S2V5UmFuZ2U+DQoJCTxwa2M6S2V5UmFuZ2U+DQoJCQk8cGtjOlJlZkFjdENvbmZpZ0lkPntlZjgyNTFiMC01ZjE2LTRmZGYtYjMwYS05YmUyMjg2ZDE1MDl9PC9wa2M6UmVmQWN0Q29uZmlnSWQ+DQoJCQk8cGtjOlBhcnROdW1iZXI+WDExLTQzODgwPC9wa2M6UGFydE51bWJlcj4NCgkJCTxwa2M6SXNWYWxpZD50cnVlPC9wa2M6SXNWYWxpZD4NCgkJCTxwa2M6U3RhcnQ+MTA2MDAwMDAwPC9wa2M6U3RhcnQ+DQoJCQk8cGtjOkVuZD4xMDY5OTk5OTk8L3BrYzpFbmQ+DQoJCTwvcGtjOktleVJhbmdlPg0KCQk8cGtjOktleVJhbmdlPg0KCQkJPHBrYzpSZWZBY3RDb25maWdJZD57YzBiZTg2ZDUtYzEyZS00NjU4LTg4MGMtMzA3OWEyYjcwYTQyfTwvcGtjOlJlZkFjdENvbmZpZ0lkPg0KCQkJPHBrYzpQYXJ0TnVtYmVyPlgxMS00Mzg3OTwvcGtjOlBhcnROdW1iZXI+DQoJCQk8cGtjOklzVmFsaWQ+dHJ1ZTwvcGtjOklzVmFsaWQ+DQoJCQk8cGtjOlN0YXJ0PjEwNTAwMDAwMDwvcGtjOlN0YXJ0Pg0KCQkJPHBrYzpFbmQ+MTA1OTk5OTk5PC9wa2M6RW5kPg0KCQk8L3BrYzpLZXlSYW5nZT4NCgkJPHBrYzpLZXlSYW5nZT4NCgkJCTxwa2M6UmVmQWN0Q29uZmlnSWQ+ezNhMzUxMjU5LWNkNzQtNGU2ZS05ZTg1LTgyMDY4N2JiZDMzN308L3BrYzpSZWZBY3RDb25maWdJZD4NCgkJCTxwa2M6UGFydE51bWJlcj5YMTEtNDM4Nzg8L3BrYzpQYXJ0TnVtYmVyPg0KCQkJPHBrYzpJc1ZhbGlkPnRydWU8L3BrYzpJc1ZhbGlkPg0KCQkJPHBrYzpTdGFydD4xMDQwMDAwMDA8L3BrYzpTdGFydD4NCgkJCTxwa2M6RW5kPjEwNDk5OTk5OTwvcGtjOkVuZD4NCgkJPC9wa2M6S2V5UmFuZ2U+DQoJCTxwa2M6S2V5UmFuZ2U+DQoJCQk8cGtjOlJlZkFjdENvbmZpZ0lkPntjOWRhNWQxMy03MGE1LTQwMjMtYWIxZS1lZTk0MTVjMmM0NzZ9PC9wa2M6UmVmQWN0Q29uZmlnSWQ+DQoJCQk8cGtjOlBhcnROdW1iZXI+WDExLTQzODgxPC9wa2M6UGFydE51bWJlcj4NCgkJCTxwa2M6SXNWYWxpZD50cnVlPC9wa2M6SXNWYWxpZD4NCgkJCTxwa2M6U3RhcnQ+MTA3MDAwMDAwPC9wa2M6U3RhcnQ+DQoJCQk8cGtjOkVuZD4xMDc5OTk5OTk8L3BrYzpFbmQ+DQoJCTwvcGtjOktleVJhbmdlPg0KCQk8cGtjOktleVJhbmdlPg0KCQkJPHBrYzpSZWZBY3RDb25maWdJZD57NmE0MjZlZWQtNDQwZS00ZGNjLTg2NjEtMmIwNzMxZWY3NjRmfTwvcGtjOlJlZkFjdENvbmZpZ0lkPg0KCQkJPHBrYzpQYXJ0TnVtYmVyPlgxMS00NjUzNDwvcGtjOlBhcnROdW1iZXI+DQoJCQk8cGtjOklzVmFsaWQ+dHJ1ZTwvcGtjOklzVmFsaWQ+DQoJCQk8cGtjOlN0YXJ0PjEwMjIwMDAwMDwvcGtjOlN0YXJ0Pg0KCQkJPHBrYzpFbmQ+MTAyMjk5OTk5PC9wa2M6RW5kPg0KCQk8L3BrYzpLZXlSYW5nZT4NCgkJPHBrYzpLZXlSYW5nZT4NCgkJCTxwa2M6UmVmQWN0Q29uZmlnSWQ+ezI3N2Y5N2M3LWZmZGUtNDdkYS1iN2M0LTY0NTFiZDAwZjJlY308L3BrYzpSZWZBY3RDb25maWdJZD4NCgkJCTxwa2M6UGFydE51bWJlcj5YMTEtNDY1MzU8L3BrYzpQYXJ0TnVtYmVyPg0KCQkJPHBrYzpJc1ZhbGlkPnRydWU8L3BrYzpJc1ZhbGlkPg0KCQkJPHBrYzpTdGFydD4xMDIxMDAwMDA8L3BrYzpTdGFydD4NCgkJCTxwa2M6RW5kPjEwMjE5OTk5OTwvcGtjOkVuZD4NCgkJPC9wa2M6S2V5UmFuZ2U+DQoJCTxwa2M6S2V5UmFuZ2U+DQoJCQk8cGtjOlJlZkFjdENvbmZpZ0lkPns2YTQyNmVlZC00NDBlLTRkY2MtODY2MS0yYjA3MzFlZjc2NGZ9PC9wa2M6UmVmQWN0Q29uZmlnSWQ+DQoJCQk8cGtjOlBhcnROdW1iZXI+WDExLTQ2NTM2PC9wa2M6UGFydE51bWJlcj4NCgkJCTxwa2M6SXNWYWxpZD50cnVlPC9wa2M6SXNWYWxpZD4NCgkJCTxwa2M6U3RhcnQ+MTAyMDAwMDAwPC9wa2M6U3RhcnQ+DQoJCQk8cGtjOkVuZD4xMDIwOTk5OTk8L3BrYzpFbmQ+DQoJCTwvcGtjOktleVJhbmdlPg0KCQk8cGtjOktleVJhbmdlPg0KCQkJPHBrYzpSZWZBY3RDb25maWdJZD57Mjc3Zjk3YzctZmZkZS00N2RhLWI3YzQtNjQ1MWJkMDBmMmVjfTwvcGtjOlJlZkFjdENvbmZpZ0lkPg0KCQkJPHBrYzpQYXJ0TnVtYmVyPlgxMS00NjUzNzwvcGtjOlBhcnROdW1iZXI+DQoJCQk8cGtjOklzVmFsaWQ+dHJ1ZTwvcGtjOklzVmFsaWQ+DQoJCQk8cGtjOlN0YXJ0PjExMTkwMDAwMDwvcGtjOlN0YXJ0Pg0KCQkJPHBrYzpFbmQ+MTExOTk5OTk5PC9wa2M6RW5kPg0KCQk8L3BrYzpLZXlSYW5nZT4NCgkJPHBrYzpLZXlSYW5nZT4NCgkJCTxwa2M6UmVmQWN0Q29uZmlnSWQ+e2JlNmY2ZDRhLTQzNzgtNGM1OC05NzU2LTM0OWFmYTY4MThhY308L3BrYzpSZWZBY3RDb25maWdJZD4NCgkJCTxwa2M6UGFydE51bWJlcj5YMTEtNDY1NDA8L3BrYzpQYXJ0TnVtYmVyPg0KCQkJPHBrYzpJc1ZhbGlkPnRydWU8L3BrYzpJc1ZhbGlkPg0KCQkJPHBrYzpTdGFydD4xMTE4MDAwMDA8L3BrYzpTdGFydD4NCgkJCTxwa2M6RW5kPjExMTg5OTk5OTwvcGtjOkVuZD4NCgkJPC9wa2M6S2V5UmFuZ2U+DQoJCTxwa2M6S2V5UmFuZ2U+DQoJCQk8cGtjOlJlZkFjdENvbmZpZ0lkPns5OWZmOWIyNi0wMTZhLTQ5ZDMtOTgyZS1mYzQ5MmYzNTJlNTd9PC9wa2M6UmVmQWN0Q29uZmlnSWQ+DQoJCQk8cGtjOlBhcnROdW1iZXI+WDExLTQ2NTQxPC9wa2M6UGFydE51bWJlcj4NCgkJCTxwa2M6SXNWYWxpZD50cnVlPC9wa2M6SXNWYWxpZD4NCgkJCTxwa2M6U3RhcnQ+MTExNzAwMDAwPC9wa2M6U3RhcnQ+DQoJCQk8cGtjOkVuZD4xMTE3OTk5OTk8L3BrYzpFbmQ+DQoJCTwvcGtjOktleVJhbmdlPg0KCQk8cGtjOktleVJhbmdlPg0KCQkJPHBrYzpSZWZBY3RDb25maWdJZD57YTU4MjliMjctNTExMS00NWI1LThmOTYtNThmNTljN2M4ZTA2fTwvcGtjOlJlZkFjdENvbmZpZ0lkPg0KCQkJPHBrYzpQYXJ0TnVtYmVyPlgxMS00NjU0MjwvcGtjOlBhcnROdW1iZXI+DQoJCQk8cGtjOklzVmFsaWQ+dHJ1ZTwvcGtjOklzVmFsaWQ+DQoJCQk8cGtjOlN0YXJ0PjExMTYwMDAwMDwvcGtjOlN0YXJ0Pg0KCQkJPHBrYzpFbmQ+MTExNjk5OTk5PC9wa2M6RW5kPg0KCQk8L3BrYzpLZXlSYW5nZT4NCgkJPHBrYzpLZXlSYW5nZT4NCgkJCTxwa2M6UmVmQWN0Q29uZmlnSWQ+e2FmNzQzYzlhLWUyOTgtNDE5ZS1hYzQxLWExZmYyMmZmNTU4Yn08L3BrYzpSZWZBY3RDb25maWdJZD4NCgkJCTxwa2M6UGFydE51bWJlcj5YMTEtNDY1NDM8L3BrYzpQYXJ0TnVtYmVyPg0KCQkJPHBrYzpJc1ZhbGlkPnRydWU8L3BrYzpJc1ZhbGlkPg0KCQkJPHBrYzpTdGFydD4xMTEzMDAwMDA8L3BrYzpTdGFydD4NCgkJCTxwa2M6RW5kPjExMTM5OTk5OTwvcGtjOkVuZD4NCgkJPC9wa2M6S2V5UmFuZ2U+DQoJCTxwa2M6S2V5UmFuZ2U+DQoJCQk8cGtjOlJlZkFjdENvbmZpZ0lkPnthMDEwM2UzYS05OWJkLTQxYjEtODRjNS03N2M5ODg1NmQ1Mzh9PC9wa2M6UmVmQWN0Q29uZmlnSWQ+DQoJCQk8cGtjOlBhcnROdW1iZXI+WDExLTQ2NTQ0PC9wa2M6UGFydE51bWJlcj4NCgkJCTxwa2M6SXNWYWxpZD50cnVlPC9wa2M6SXNWYWxpZD4NCgkJCTxwa2M6U3RhcnQ+MTExNDAwMDAwPC9wa2M6U3RhcnQ+DQoJCQk8cGtjOkVuZD4xMTE0OTk5OTk8L3BrYzpFbmQ+DQoJCTwvcGtjOktleVJhbmdlPg0KCQk8cGtjOktleVJhbmdlPg0KCQkJPHBrYzpSZWZBY3RDb25maWdJZD57NWE5YjAyNTMtNDFkOS00ODE4LTk0Y2EtMjQxNTNhMzMzYmI0fTwvcGtjOlJlZkFjdENvbmZpZ0lkPg0KCQkJPHBrYzpQYXJ0TnVtYmVyPlgxMS00NjU0NTwvcGtjOlBhcnROdW1iZXI+DQoJCQk8cGtjOklzVmFsaWQ+dHJ1ZTwvcGtjOklzVmFsaWQ+DQoJCQk8cGtjOlN0YXJ0PjExMTIwMDAwMDwvcGtjOlN0YXJ0Pg0KCQkJPHBrYzpFbmQ+MTExMjk5OTk5PC9wa2M6RW5kPg0KCQk8L3BrYzpLZXlSYW5nZT4NCgkJPHBrYzpLZXlSYW5nZT4NCgkJCTxwa2M6UmVmQWN0Q29uZmlnSWQ+ezkyMmU5NDA5LWVlNDUtNDY2MC1iYTRlLWExNzkyYzdhMTk3YX08L3BrYzpSZWZBY3RDb25maWdJZD4NCgkJCTxwa2M6UGFydE51bWJlcj5YMTEtNDY1NDY8L3BrYzpQYXJ0TnVtYmVyPg0KCQkJPHBrYzpJc1ZhbGlkPnRydWU8L3BrYzpJc1ZhbGlkPg0KCQkJPHBrYzpTdGFydD4xMTExMDAwMDA8L3BrYzpTdGFydD4NCgkJCTxwa2M6RW5kPjExMTE5OTk5OTwvcGtjOkVuZD4NCgkJPC9wa2M6S2V5UmFuZ2U+DQoJCTxwa2M6S2V5UmFuZ2U+DQoJCQk8cGtjOlJlZkFjdENvbmZpZ0lkPns0YmMzMmUyZi03NmE4LTQxZTItOTNmMy1iZGE3YWQwMTJiM2Z9PC9wa2M6UmVmQWN0Q29uZmlnSWQ+DQoJCQk8cGtjOlBhcnROdW1iZXI+WDExLTQ2NTUxPC9wa2M6UGFydE51bWJlcj4NCgkJCTxwa2M6SXNWYWxpZD50cnVlPC9wa2M6SXNWYWxpZD4NCgkJCTxwa2M6U3RhcnQ+MTExNTAwMDAwPC9wa2M6U3RhcnQ+DQoJCQk8cGtjOkVuZD4xMTE1OTk5OTk8L3BrYzpFbmQ+DQoJCTwvcGtjOktleVJhbmdlPg0KCQk8cGtjOktleVJhbmdlPg0KCQkJPHBrYzpSZWZBY3RDb25maWdJZD57YjlhNjhjODMtMTZlMC00NTQ3LWEzZDUtZWE0YWQ4OTliNjNlfTwvcGtjOlJlZkFjdENvbmZpZ0lkPg0KCQkJPHBrYzpQYXJ0TnVtYmVyPlgxMS00NjU1MjwvcGtjOlBhcnROdW1iZXI+DQoJCQk8cGtjOklzVmFsaWQ+dHJ1ZTwvcGtjOklzVmFsaWQ+DQoJCQk8cGtjOlN0YXJ0PjExMTAwMDAwMDwvcGtjOlN0YXJ0Pg0KCQkJPHBrYzpFbmQ+MTExMDk5OTk5PC9wa2M6RW5kPg0KCQk8L3BrYzpLZXlSYW5nZT4NCgk8L3BrYzpLZXlSYW5nZXM+DQoJPHBrYzpQdWJsaWNLZXlzPg0KCQk8cGtjOlB1YmxpY0tleT4NCgkJCTxwa2M6R3JvdXBJZD4xMTY8L3BrYzpHcm91cElkPg0KCQkJPHBrYzpBbGdvcml0aG1JZD5tc2Z0OnJtL2FsZ29yaXRobS9wa2V5Lzk4NjwvcGtjOkFsZ29yaXRobUlkPg0KCQkJPHBrYzpQdWJsaWNLZXlWYWx1ZT41QUVBQUFrQUFBRFd2ZDJSeEh3eEFSQUFBQUFmQUFBQVBnQUFBQW9BQUFBVUFBQUFTWFhTYnNwRyt0ZTJRS0ZPRUo5aWlQcmtad1JJSzRlQXpxKytMRFlzQVR4TW5FNHJnS0o5QUJEZUJqS3hBQWhjK2JNYm9nTG10NlhxbDMxY2tvUWNpUUVBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBSkhEMEl3SE45MTFTdUY1eXc3dWhPci9WNCtFT0tSMmVtTytpM2lHcjZuM3FGaDhEWGFVRUg2cXpWUGJ1OUtUdXlrelZIWHJURm1GZWhzcWtwQmJ2Q1F3NFZCQXNra3ZvbGdHRG02REtLU2pLazFwdlNDZG5HREZpT1dvMG5HL1docm5nOWFCVFlLRElMdEN2em1oc20xczhnVzIybWVPcFVnUUdZL2hnQWxmOWFLdzlmR3M2MXA4bm9BVXdySHk5bTRuOVdBbVArTDJEU1JMTnk1V3FvdjF1b2xobzcrbk1WbC95SFdYQ1I0d24rbHk1a0JpOWtJTXVyVXJLSW1JaHpwc0xYc3ZBR1RPb2hXY1c1SnFSMVFXRWQvcFdHdFRTb2cxV3hDaHdkU1c0T042V1IvVnl6Y3B4d3dOMFhwaDQ2R3hsYnlwQnVhUHB0WjkwQ1VvQWdnPT08L3BrYzpQdWJsaWNLZXlWYWx1ZT4NCgkJPC9wa2M6UHVibGljS2V5Pg0KCTwvcGtjOlB1YmxpY0tleXM+DQo8L3BrYzpQcm9kdWN0S2V5Q29uZmlndXJhdGlvbj4NCg== -------------------------------------------------------------------------------- /KeyCheck/pkeys/DELL-DD981F15.XRM-MS: -------------------------------------------------------------------------------- 1 | OEM CertificatekgAAAAAAAgBERUxMICABAAEAf/bBBb5cV2Olimjzbo8G+q+0n2iCI+xQQFpzf+zkB8vcJRqc4+NmEeClmAbFgAr6QpOGmOfVG9TXOqQL7uJ9vl9bFQyr0CHev+m1bqRXuYwM0ro6aTB2lHGiZNdM2IW/36VqyNxF1U2MuIwFL/wuI8QpxW8/KWxtV3kOtnXtIZU=mylUeSOamDoBwptofZ7FKoCePHk=OQojHOugcB3VvUc7xRonmHv/DP136N/mKul3wR7gXg9OgmlSlm2Gjm59QO9xt7LvWDjdNWUNwNudww9+Ay1wjly0fGXRcMBO1rObJgAbGMC7ejtxMETpNZ8Ukzn9nhsnBJAUtzvynXSFqJQvboe45dNN6FBh9uaEj4zPiUKlk2c3B9GwFZi0554cC/tgF7mA8Bb+Hsa7e2jMrRN5KIjxD5diRNZr7XRzH0RLm/S9+sKtl9SkVQ5b3bIZhfAqVJ4hsCFpvyaVKW/XYbc4wOxf6r377ONOQD3NJX4nqELg3S4GCUG7xyKHFL2/QVqygiGr+CRCxJfZxf2feucbSWOgMQ==sotZn+w9juKPf7bMO9rNFriB+10v/t9bo/XWG+rzoDbw/uF4INZ5rGRIitiITY/bI4rANkv4Z5hG/8VxGMbqvqcaXJqnRFda7XAjgm1z9wkgX1R/d2tXLUUUQP0J1XuSbgzR89T/lpnc5q2Cdvy7Gv2pZvAzSeLOponXc8J3zOFr0IUXBGprXKnemVk1iJBFnyQGlWG3UoSpdlF0ichBQwPx/PgoTbcZsA7Gg62BGwPx/uDA3ZgwowrPlRwfLVAO6qE9xPJqRZdRFfPHbdQjp1YAq27wc6cTz5sPSTB1pJ4L9MD+NpvHj2OMZV5+LJ+bxZbTqhPcrzCp7ckkyD7Hzw==AQAB2006-03-16T20:17:30Z{55c92734-d682-4d71-983e-d6ec3f16059f}msft:sl/PPDmsft:sl/OEMCERT2.0http://licensing.microsoft.com -------------------------------------------------------------------------------- /KeyCheck/pkeys/DELL.xrm-ms: -------------------------------------------------------------------------------- 1 | OEM CertificatekgAAAAAAAgBERUxMICABAAEAf/bBBb5cV2Olimjzbo8G+q+0n2iCI+xQQFpzf+zkB8vcJRqc4+NmEeClmAbFgAr6QpOGmOfVG9TXOqQL7uJ9vl9bFQyr0CHev+m1bqRXuYwM0ro6aTB2lHGiZNdM2IW/36VqyNxF1U2MuIwFL/wuI8QpxW8/KWxtV3kOtnXtIZU=mylUeSOamDoBwptofZ7FKoCePHk=OQojHOugcB3VvUc7xRonmHv/DP136N/mKul3wR7gXg9OgmlSlm2Gjm59QO9xt7LvWDjdNWUNwNudww9+Ay1wjly0fGXRcMBO1rObJgAbGMC7ejtxMETpNZ8Ukzn9nhsnBJAUtzvynXSFqJQvboe45dNN6FBh9uaEj4zPiUKlk2c3B9GwFZi0554cC/tgF7mA8Bb+Hsa7e2jMrRN5KIjxD5diRNZr7XRzH0RLm/S9+sKtl9SkVQ5b3bIZhfAqVJ4hsCFpvyaVKW/XYbc4wOxf6r377ONOQD3NJX4nqELg3S4GCUG7xyKHFL2/QVqygiGr+CRCxJfZxf2feucbSWOgMQ==sotZn+w9juKPf7bMO9rNFriB+10v/t9bo/XWG+rzoDbw/uF4INZ5rGRIitiITY/bI4rANkv4Z5hG/8VxGMbqvqcaXJqnRFda7XAjgm1z9wkgX1R/d2tXLUUUQP0J1XuSbgzR89T/lpnc5q2Cdvy7Gv2pZvAzSeLOponXc8J3zOFr0IUXBGprXKnemVk1iJBFnyQGlWG3UoSpdlF0ichBQwPx/PgoTbcZsA7Gg62BGwPx/uDA3ZgwowrPlRwfLVAO6qE9xPJqRZdRFfPHbdQjp1YAq27wc6cTz5sPSTB1pJ4L9MD+NpvHj2OMZV5+LJ+bxZbTqhPcrzCp7ckkyD7Hzw==AQAB2006-03-16T20:17:30Z{55c92734-d682-4d71-983e-d6ec3f16059f}msft:sl/PPDmsft:sl/OEMCERT2.0http://licensing.microsoft.com -------------------------------------------------------------------------------- /KeyCheck/pkeys/HP-COMPAQ.xrm-ms: -------------------------------------------------------------------------------- 1 | OEM CertificatekgAAAAAAAgBIUFFPRU0BAAEAW6tgVrxYHujB0qFc5U+7/R2pjJS0rggR3BNZ03/2PocxuZV0ENo7pFu1GYJ8OdcNfCKsHCqE6QqIbfqx4tjoIZbhLmiav0RFPjyOmZDeNzhXC5IVvN7/8gd+tUCMUTrDAkj2ExJy+0J45keIVMew8JOe+wS3uLiQ3tvtMuH7VKY=ZMBOl6OQX4KZ/UK1tvc/m/7Itx4=HKKhCJWiCHoSiDU9/BC7jv2S95tLXG4WfK8t4Oz+jnGuh8wDTXrL1TfTenLprfglRAaloShHCrGKxq4K0j/+jHVL1vpvMKczO3jccFl8A5p+RL2lLMc539C2qTY7dTjxs99/6spTZJEBuUE25Yxg1WbqXfmSlW9PVgARafO1Yl5ilLlv1NB95+JVLVAfg2gjmI6HWoJ3GS+/JBT5OhMCrqwOU9oIjlYyD0TIsx2EukD1e2rh4aE26A2w8JwMtJtdUxnhHMP4ogbcSjLFc0NfwnNJCkiAr25rjAcPmoTLOUp3TXsLY5PcT4wbq0QEHNA8Tpwto0uPhPW1ZZs+Usl6AA==sotZn+w9juKPf7bMO9rNFriB+10v/t9bo/XWG+rzoDbw/uF4INZ5rGRIitiITY/bI4rANkv4Z5hG/8VxGMbqvqcaXJqnRFda7XAjgm1z9wkgX1R/d2tXLUUUQP0J1XuSbgzR89T/lpnc5q2Cdvy7Gv2pZvAzSeLOponXc8J3zOFr0IUXBGprXKnemVk1iJBFnyQGlWG3UoSpdlF0ichBQwPx/PgoTbcZsA7Gg62BGwPx/uDA3ZgwowrPlRwfLVAO6qE9xPJqRZdRFfPHbdQjp1YAq27wc6cTz5sPSTB1pJ4L9MD+NpvHj2OMZV5+LJ+bxZbTqhPcrzCp7ckkyD7Hzw==AQAB2006-07-11T10:42:48Z{55c92734-d682-4d71-983e-d6ec3f16059f}msft:sl/PPDmsft:sl/OEMCERT2.0http://licensing.microsoft.com -------------------------------------------------------------------------------- /KeyCheck/pkeys/IBM-LENOVO.xrm-ms: -------------------------------------------------------------------------------- 1 | OEM CertificatekgAAAAAAAgBMRU5PVk8BAAEAaRZKn7FLOvuAIKqvxPk+wYBJ7mplJnIezb9fL5bWwAqS9Qa1ALI7KQLiTI3C8rxBd5xw8PMbCdJjWtyog/heyRWV+fr93AW3TWd/LbOEMyDh0Xkqp2p30bYgKnZCxdXptkNAVUTDyTeZX0GXcPPR9gfsexopocHxkf1Ihm4+zss=/A8xsgOKXrGblQhnUX2SSdRgNy4=kuLkCnKyqITqBlnU61GvfScsbnvg/A6NI/OTQYJZla++WLQhCj9ogu+Pn4YYGAB3gfUy/bQmFKAS86n0SylBHPNNvFoXbn8k3ak3ndOaFaT+d+vs1vdTU6WWaOsZ6rD9xXSWoFDMjDyueNJ6mUoTWGWYSVJZYOpk8UWnMaz4yH9UsjrQ5ifdvosgLmlKvoJc4mEntDfl56rluCsyP3t2WUp69OREDAuhXqE8mD6Ib3v4boMTrLZmHt2ldCZ3rZK/amtNjTItPPoXrFk6fNU9F0W2qNX19yXpzrwpaKwKcQ7QKy0kUjRkyg7j7gTgfAdR/aHh/eunoDFuJIltETZG4A==sotZn+w9juKPf7bMO9rNFriB+10v/t9bo/XWG+rzoDbw/uF4INZ5rGRIitiITY/bI4rANkv4Z5hG/8VxGMbqvqcaXJqnRFda7XAjgm1z9wkgX1R/d2tXLUUUQP0J1XuSbgzR89T/lpnc5q2Cdvy7Gv2pZvAzSeLOponXc8J3zOFr0IUXBGprXKnemVk1iJBFnyQGlWG3UoSpdlF0ichBQwPx/PgoTbcZsA7Gg62BGwPx/uDA3ZgwowrPlRwfLVAO6qE9xPJqRZdRFfPHbdQjp1YAq27wc6cTz5sPSTB1pJ4L9MD+NpvHj2OMZV5+LJ+bxZbTqhPcrzCp7ckkyD7Hzw==AQAB2006-06-17T18:22:30Z{55c92734-d682-4d71-983e-d6ec3f16059f}msft:sl/PPDmsft:sl/OEMCERT2.0http://licensing.microsoft.com -------------------------------------------------------------------------------- /KeyCheck/pkeys/pkeyconfig-2.xrm-ms: -------------------------------------------------------------------------------- 1 | XrML 2.1 License - Product Key ConfigurationsNb6oo8/P8aSr0fd4weCFJQhxH0=hwX8SqmvLFzbFUX4dH4R7zytfVGjkZQRvdNaXEJuzbdK6n7s6aMFpusflnj25PvrVEuhOiH1+XpvXGEsp/ytCaTQnf9KeW6xgx5zB8Orj5FCMdYm4DTc4piHUDquSWlQBDAKWLc6yyzJkAn2WgIVldQWnBJqgb3Fxexu2FWGpwLoFdQYMYs0T7lEeBWgmUUMMFL2XRfmIF5VSaz8wZCr++GjXIFGd6BlaOc/c/UZZYIaV12nuyeBNQjDL9CrkDSLcFquzuyZdBrFmuYC64p6OuDZ3qHK+v5VFGghFrC0S/wFNq0r5QIJfNWcQntUPOeu2j92vIcc9QeiYAgERdW6SA==1N+QaYteSIjGmRMzTkxCE+5oiPoLk2Fq+RA9GLnl+dHOcyxt2a/0HvUdagaL/NwDquzOef4JOMMuVavd4PtWQiO/aBLvxVv7yIhUhhB6PEsw59mhbVlT/Z5OGkp6gfzH9ezZ+qHHFHo0cloAAu5QGUeuYCPLheVK7X3+syHE1qXagfRa5m0xG+770FyPeMKazK+keeQ/goW+nt2wTM9Pofj4yTGCbn6Fc6EpKdyHmzrzQDc5FjZemXP2PbGjS6iPC7l3+Ut5JPL66ZUZzCs5qRc+/wRODknUWAcqURJWP79knfPhf3/dvbytHpr64wFfpBNDSbNVubol0E8oTa/NYw==AQAB2016-01-01T00:00:00Zmsft:sl/PKEYCONFIG/SIGNEDmsft:sl/PKEYCONFIG/SIGNED2.0PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjxQcm9kdWN0S2V5Q29uZmlndXJhdGlvbiB4bWxucz0iaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL0RSTS9QS0VZL0NvbmZpZ3VyYXRpb24vMi4wIj4NCjxDb25maWd1cmF0aW9ucz4NCjxDb25maWd1cmF0aW9uPg0KPEFjdENvbmZpZ0lkPntkNjk5MmFhYy0yOWU3LTQ1MmEtYmYxMC1iYmZiOGNjYWJlNTl9PC9BY3RDb25maWdJZD4NCjxSZWZHcm91cElkPjIwNjwvUmVmR3JvdXBJZD4NCjxFZGl0aW9uSWQ+U2VydmVyRGF0YWNlbnRlcjtTZXJ2ZXJTdGFuZGFyZDwvRWRpdGlvbklkPg0KPFByb2R1Y3REZXNjcmlwdGlvbj5XaW5kb3dzIFNlcnZlciAyMDE2IFJUTSBTZXJ2ZXJEYXRhY2VudGVyO1NlcnZlclN0YW5kYXJkIFZvbHVtZTpDU1ZMSzwvUHJvZHVjdERlc2NyaXB0aW9uPg0KPFByb2R1Y3RLZXlUeXBlPlZvbHVtZTpDU1ZMSzwvUHJvZHVjdEtleVR5cGU+DQo8SXNSYW5kb21pemVkPmZhbHNlPC9Jc1JhbmRvbWl6ZWQ+DQo8L0NvbmZpZ3VyYXRpb24+DQo8Q29uZmlndXJhdGlvbj4NCjxBY3RDb25maWdJZD57M2MyZGE5YTUtMWM2ZS00NWQxLTg1NWYtZmRiZWY1MzY2NzZmfTwvQWN0Q29uZmlnSWQ+DQo8UmVmR3JvdXBJZD4yMDY8L1JlZkdyb3VwSWQ+DQo8RWRpdGlvbklkPlNlcnZlckRhdGFjZW50ZXI7U2VydmVyU3RhbmRhcmQ8L0VkaXRpb25JZD4NCjxQcm9kdWN0RGVzY3JpcHRpb24+V2luZG93cyBTZXJ2ZXIgMjAxNiBSVE0gU2VydmVyRGF0YWNlbnRlcjtTZXJ2ZXJTdGFuZGFyZCBWb2x1bWU6Q1NWTEsgVkwgQWRkaXRpb25hbCBMYWI8L1Byb2R1Y3REZXNjcmlwdGlvbj4NCjxQcm9kdWN0S2V5VHlwZT5Wb2x1bWU6Q1NWTEs8L1Byb2R1Y3RLZXlUeXBlPg0KPElzUmFuZG9taXplZD5mYWxzZTwvSXNSYW5kb21pemVkPg0KPC9Db25maWd1cmF0aW9uPg0KPENvbmZpZ3VyYXRpb24+DQo8QWN0Q29uZmlnSWQ+ezA3MjRjYjdkLTM0MzctNGNiNy05M2NiLTgzMDM3NWQwMDc5ZH08L0FjdENvbmZpZ0lkPg0KPFJlZkdyb3VwSWQ+MjA2PC9SZWZHcm91cElkPg0KPEVkaXRpb25JZD5FbnRlcnByaXNlO0VudGVycHJpc2VOO1Byb2Zlc3Npb25hbDtQcm9mZXNzaW9uYWxOO0VudGVycHJpc2VTO0VudGVycHJpc2VTTjtFZHVjYXRpb247RWR1Y2F0aW9uTjwvRWRpdGlvbklkPg0KPFByb2R1Y3REZXNjcmlwdGlvbj5XaW4gMTAgUlRNIEVudGVycHJpc2U7RW50ZXJwcmlzZU47UHJvZmVzc2lvbmFsO1Byb2Zlc3Npb25hbE47RW50ZXJwcmlzZVM7RW50ZXJwcmlzZVNOO0VkdWNhdGlvbjtFZHVjYXRpb25OIFZvbHVtZTpDU1ZMSzwvUHJvZHVjdERlc2NyaXB0aW9uPg0KPFByb2R1Y3RLZXlUeXBlPlZvbHVtZTpDU1ZMSzwvUHJvZHVjdEtleVR5cGU+DQo8SXNSYW5kb21pemVkPmZhbHNlPC9Jc1JhbmRvbWl6ZWQ+DQo8L0NvbmZpZ3VyYXRpb24+DQo8Q29uZmlndXJhdGlvbj4NCjxBY3RDb25maWdJZD57N2E4MDI1MjYtNGM5NC00YmQxLWJhMTQtODM1YTFhY2EyMTIwfTwvQWN0Q29uZmlnSWQ+DQo8UmVmR3JvdXBJZD4yMDY8L1JlZkdyb3VwSWQ+DQo8RWRpdGlvbklkPkVudGVycHJpc2U7RW50ZXJwcmlzZU47UHJvZmVzc2lvbmFsO1Byb2Zlc3Npb25hbE47RW50ZXJwcmlzZVM7RW50ZXJwcmlzZVNOO0VkdWNhdGlvbjtFZHVjYXRpb25OPC9FZGl0aW9uSWQ+DQo8UHJvZHVjdERlc2NyaXB0aW9uPldpbiAxMCBSVE0gRW50ZXJwcmlzZTtFbnRlcnByaXNlTjtQcm9mZXNzaW9uYWw7UHJvZmVzc2lvbmFsTjtFbnRlcnByaXNlUztFbnRlcnByaXNlU047RWR1Y2F0aW9uO0VkdWNhdGlvbk4gVm9sdW1lOkNTVkxLIFZMIEFkZGl0aW9uYWwgTGFiPC9Qcm9kdWN0RGVzY3JpcHRpb24+DQo8UHJvZHVjdEtleVR5cGU+Vm9sdW1lOkNTVkxLPC9Qcm9kdWN0S2V5VHlwZT4NCjxJc1JhbmRvbWl6ZWQ+ZmFsc2U8L0lzUmFuZG9taXplZD4NCjwvQ29uZmlndXJhdGlvbj4NCjxDb25maWd1cmF0aW9uPg0KPEFjdENvbmZpZ0lkPnszMGE0MmM4Ni1iN2EwLTRhMzQtOGM5MC1mZjE3N2NiMmFjYjd9PC9BY3RDb25maWdJZD4NCjxSZWZHcm91cElkPjIwNjwvUmVmR3JvdXBJZD4NCjxFZGl0aW9uSWQ+RW50ZXJwcmlzZTtFbnRlcnByaXNlTjtQcm9mZXNzaW9uYWw7UHJvZmVzc2lvbmFsTjtFbnRlcnByaXNlUztFbnRlcnByaXNlU047RWR1Y2F0aW9uO0VkdWNhdGlvbk48L0VkaXRpb25JZD4NCjxQcm9kdWN0RGVzY3JpcHRpb24+V2luIDEwIFJUTSBFbnRlcnByaXNlO0VudGVycHJpc2VOO1Byb2Zlc3Npb25hbDtQcm9mZXNzaW9uYWxOO0VudGVycHJpc2VTO0VudGVycHJpc2VTTjtFZHVjYXRpb247RWR1Y2F0aW9uTiBWb2x1bWU6Q1NWTEs8L1Byb2R1Y3REZXNjcmlwdGlvbj4NCjxQcm9kdWN0S2V5VHlwZT5Wb2x1bWU6Q1NWTEs8L1Byb2R1Y3RLZXlUeXBlPg0KPElzUmFuZG9taXplZD5mYWxzZTwvSXNSYW5kb21pemVkPg0KPC9Db25maWd1cmF0aW9uPg0KPENvbmZpZ3VyYXRpb24+DQo8QWN0Q29uZmlnSWQ+e2Q1NTJiZWZiLTQ4Y2MtNDMyNy04ZjM5LTQ3ZDJkOTRmOTg3Y308L0FjdENvbmZpZ0lkPg0KPFJlZkdyb3VwSWQ+MjA2PC9SZWZHcm91cElkPg0KPEVkaXRpb25JZD5FbnRlcnByaXNlO0VudGVycHJpc2VOO1Byb2Zlc3Npb25hbDtQcm9mZXNzaW9uYWxOO0VudGVycHJpc2VTO0VudGVycHJpc2VTTjtFZHVjYXRpb247RWR1Y2F0aW9uTjwvRWRpdGlvbklkPg0KPFByb2R1Y3REZXNjcmlwdGlvbj5XaW4gMTAgUlRNIEVudGVycHJpc2U7RW50ZXJwcmlzZU47UHJvZmVzc2lvbmFsO1Byb2Zlc3Npb25hbE47RW50ZXJwcmlzZVM7RW50ZXJwcmlzZVNOO0VkdWNhdGlvbjtFZHVjYXRpb25OIFZvbHVtZTpDU1ZMSyBWTCBBZGRpdGlvbmFsIExhYjwvUHJvZHVjdERlc2NyaXB0aW9uPg0KPFByb2R1Y3RLZXlUeXBlPlZvbHVtZTpDU1ZMSzwvUHJvZHVjdEtleVR5cGU+DQo8SXNSYW5kb21pemVkPmZhbHNlPC9Jc1JhbmRvbWl6ZWQ+DQo8L0NvbmZpZ3VyYXRpb24+DQo8L0NvbmZpZ3VyYXRpb25zPg0KPEtleVJhbmdlcz4NCjxLZXlSYW5nZT4NCjxSZWZBY3RDb25maWdJZD57ZDY5OTJhYWMtMjllNy00NTJhLWJmMTAtYmJmYjhjY2FiZTU5fTwvUmVmQWN0Q29uZmlnSWQ+DQo8UGFydE51bWJlcj5bUlMxXVgyMS0wMzExOTwvUGFydE51bWJlcj4NCjxFdWxhVHlwZT5Wb2x1bWU8L0V1bGFUeXBlPg0KPElzVmFsaWQ+dHJ1ZTwvSXNWYWxpZD4NCjxTdGFydD40OTEwMDAwMDA8L1N0YXJ0Pg0KPEVuZD41MzA5OTk5OTk8L0VuZD4NCjwvS2V5UmFuZ2U+DQo8S2V5UmFuZ2U+DQo8UmVmQWN0Q29uZmlnSWQ+e2Q2OTkyYWFjLTI5ZTctNDUyYS1iZjEwLWJiZmI4Y2NhYmU1OX08L1JlZkFjdENvbmZpZ0lkPg0KPFBhcnROdW1iZXI+W1JTMV1YMjEtMDMxMjA8L1BhcnROdW1iZXI+DQo8RXVsYVR5cGU+Vm9sdW1lPC9FdWxhVHlwZT4NCjxJc1ZhbGlkPnRydWU8L0lzVmFsaWQ+DQo8U3RhcnQ+NDcxMDAwMDAwPC9TdGFydD4NCjxFbmQ+NDkwOTk5OTk5PC9FbmQ+DQo8L0tleVJhbmdlPg0KPEtleVJhbmdlPg0KPFJlZkFjdENvbmZpZ0lkPntkNjk5MmFhYy0yOWU3LTQ1MmEtYmYxMC1iYmZiOGNjYWJlNTl9PC9SZWZBY3RDb25maWdJZD4NCjxQYXJ0TnVtYmVyPltSUzFdWDIxLTAzMTIxPC9QYXJ0TnVtYmVyPg0KPEV1bGFUeXBlPlZvbHVtZTwvRXVsYVR5cGU+DQo8SXNWYWxpZD50cnVlPC9Jc1ZhbGlkPg0KPFN0YXJ0PjEwMTAwMDA8L1N0YXJ0Pg0KPEVuZD4xNTA5OTk5PC9FbmQ+DQo8L0tleVJhbmdlPg0KPEtleVJhbmdlPg0KPFJlZkFjdENvbmZpZ0lkPnszYzJkYTlhNS0xYzZlLTQ1ZDEtODU1Zi1mZGJlZjUzNjY3NmZ9PC9SZWZBY3RDb25maWdJZD4NCjxQYXJ0TnVtYmVyPltSUzFdWDIxLTAzMTIyPC9QYXJ0TnVtYmVyPg0KPEV1bGFUeXBlPlZvbHVtZTwvRXVsYVR5cGU+DQo8SXNWYWxpZD50cnVlPC9Jc1ZhbGlkPg0KPFN0YXJ0PjE1MTAwMDA8L1N0YXJ0Pg0KPEVuZD4yMDA5OTk5PC9FbmQ+DQo8L0tleVJhbmdlPg0KPEtleVJhbmdlPg0KPFJlZkFjdENvbmZpZ0lkPnswNzI0Y2I3ZC0zNDM3LTRjYjctOTNjYi04MzAzNzVkMDA3OWR9PC9SZWZBY3RDb25maWdJZD4NCjxQYXJ0TnVtYmVyPltUSF1YMjAtMDA4NTk8L1BhcnROdW1iZXI+DQo8RXVsYVR5cGU+Vm9sdW1lPC9FdWxhVHlwZT4NCjxJc1ZhbGlkPnRydWU8L0lzVmFsaWQ+DQo8U3RhcnQ+MzkwMDAwMDAwPC9TdGFydD4NCjxFbmQ+NDA0OTk5OTk5PC9FbmQ+DQo8L0tleVJhbmdlPg0KPEtleVJhbmdlPg0KPFJlZkFjdENvbmZpZ0lkPnswNzI0Y2I3ZC0zNDM3LTRjYjctOTNjYi04MzAzNzVkMDA3OWR9PC9SZWZBY3RDb25maWdJZD4NCjxQYXJ0TnVtYmVyPltUSF1YMjAtMDA4NjA8L1BhcnROdW1iZXI+DQo8RXVsYVR5cGU+Vm9sdW1lPC9FdWxhVHlwZT4NCjxJc1ZhbGlkPnRydWU8L0lzVmFsaWQ+DQo8U3RhcnQ+MTkyNTAwMDAwPC9TdGFydD4NCjxFbmQ+MTkzMTk5OTk5PC9FbmQ+DQo8L0tleVJhbmdlPg0KPEtleVJhbmdlPg0KPFJlZkFjdENvbmZpZ0lkPnswNzI0Y2I3ZC0zNDM3LTRjYjctOTNjYi04MzAzNzVkMDA3OWR9PC9SZWZBY3RDb25maWdJZD4NCjxQYXJ0TnVtYmVyPltUSF1YMjAtMDA4NjE8L1BhcnROdW1iZXI+DQo8RXVsYVR5cGU+Vm9sdW1lPC9FdWxhVHlwZT4NCjxJc1ZhbGlkPnRydWU8L0lzVmFsaWQ+DQo8U3RhcnQ+MTAwMjQwMDA8L1N0YXJ0Pg0KPEVuZD4xMDAyODk5OTwvRW5kPg0KPC9LZXlSYW5nZT4NCjxLZXlSYW5nZT4NCjxSZWZBY3RDb25maWdJZD57N2E4MDI1MjYtNGM5NC00YmQxLWJhMTQtODM1YTFhY2EyMTIwfTwvUmVmQWN0Q29uZmlnSWQ+DQo8UGFydE51bWJlcj5bVEhdWDIwLTAwODYyPC9QYXJ0TnVtYmVyPg0KPEV1bGFUeXBlPlZvbHVtZTwvRXVsYVR5cGU+DQo8SXNWYWxpZD50cnVlPC9Jc1ZhbGlkPg0KPFN0YXJ0PjEwNzAwMDAwPC9TdGFydD4NCjxFbmQ+MTA3OTk5OTk8L0VuZD4NCjwvS2V5UmFuZ2U+DQo8S2V5UmFuZ2U+DQo8UmVmQWN0Q29uZmlnSWQ+ezMwYTQyYzg2LWI3YTAtNGEzNC04YzkwLWZmMTc3Y2IyYWNiN308L1JlZkFjdENvbmZpZ0lkPg0KPFBhcnROdW1iZXI+W1JTMV1YMjEtMDM0MDA8L1BhcnROdW1iZXI+DQo8RXVsYVR5cGU+Vm9sdW1lPC9FdWxhVHlwZT4NCjxJc1ZhbGlkPnRydWU8L0lzVmFsaWQ+DQo8U3RhcnQ+NTMxMDAwMDAwPC9TdGFydD4NCjxFbmQ+NTQ1OTk5OTk5PC9FbmQ+DQo8L0tleVJhbmdlPg0KPEtleVJhbmdlPg0KPFJlZkFjdENvbmZpZ0lkPnszMGE0MmM4Ni1iN2EwLTRhMzQtOGM5MC1mZjE3N2NiMmFjYjd9PC9SZWZBY3RDb25maWdJZD4NCjxQYXJ0TnVtYmVyPltSUzFdWDIxLTAzNDAxPC9QYXJ0TnVtYmVyPg0KPEV1bGFUeXBlPlZvbHVtZTwvRXVsYVR5cGU+DQo8SXNWYWxpZD50cnVlPC9Jc1ZhbGlkPg0KPFN0YXJ0PjIxMTUwMDA8L1N0YXJ0Pg0KPEVuZD4yODE0OTk5PC9FbmQ+DQo8L0tleVJhbmdlPg0KPEtleVJhbmdlPg0KPFJlZkFjdENvbmZpZ0lkPnszMGE0MmM4Ni1iN2EwLTRhMzQtOGM5MC1mZjE3N2NiMmFjYjd9PC9SZWZBY3RDb25maWdJZD4NCjxQYXJ0TnVtYmVyPltSUzFdWDIxLTAzNDAyPC9QYXJ0TnVtYmVyPg0KPEV1bGFUeXBlPlZvbHVtZTwvRXVsYVR5cGU+DQo8SXNWYWxpZD50cnVlPC9Jc1ZhbGlkPg0KPFN0YXJ0PjIwMTAwMDA8L1N0YXJ0Pg0KPEVuZD4yMDE0OTk5PC9FbmQ+DQo8L0tleVJhbmdlPg0KPEtleVJhbmdlPg0KPFJlZkFjdENvbmZpZ0lkPntkNTUyYmVmYi00OGNjLTQzMjctOGYzOS00N2QyZDk0Zjk4N2N9PC9SZWZBY3RDb25maWdJZD4NCjxQYXJ0TnVtYmVyPltSUzFdWDIxLTAzNDAzPC9QYXJ0TnVtYmVyPg0KPEV1bGFUeXBlPlZvbHVtZTwvRXVsYVR5cGU+DQo8SXNWYWxpZD50cnVlPC9Jc1ZhbGlkPg0KPFN0YXJ0PjIwMTUwMDA8L1N0YXJ0Pg0KPEVuZD4yMTE0OTk5PC9FbmQ+DQo8L0tleVJhbmdlPg0KPC9LZXlSYW5nZXM+DQo8UHVibGljS2V5cz4NCjxQdWJsaWNLZXk+DQo8R3JvdXBJZD4yMDY8L0dyb3VwSWQ+DQo8QWxnb3JpdGhtSWQ+bXNmdDpybS9hbGdvcml0aG0vcGtleS8yMDA1PC9BbGdvcml0aG1JZD4NCjxQdWJsaWNLZXlWYWx1ZT5kMlpWUkFBQkFBRXpBUUFBTXlJUkFBQUJBQUVBRGc0REFBQUFBZ0FBQUFBQUFBQUFBQUFBQUFBQUFBNEFBQUFwQUFBQXlBQUFBQjhBQUFBakFRTUlEdzhQSHdNREF3TURCejlsUmxRa1pReUNPNG9kbTR5eksrOTVyUUgzUmhnN2loMmJqTE1yQkFFQUFRSUFBUUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQURhRk5UZmJtMEVwTUEvMHg5TkFVM213Q0lnY1hXWS9nd21hRnNTQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUE1bTh2NXEzc1NQMDJZMDFrQUdJaG90VTE4VUFjSHpiZTFUSXdEdlRGbXF0a29DVEpNbW8rdkNCQyt6T2k0M1lXQjlBRXByR1FNYW00NjRnU2VGdVg3Nm5wT2Y2QkUyUTBBRXF1T0xHcmFsUm9adkhqbVBnVnI3UXB3QWJNZGJUVWdteHFpVWYwWjFoZTdHV2w4Tm1RclZaVDJXTS9PMVh1VnIza0tXRVJVUmppNnRRTXlheHRYcjQ5c0NKbnc5dFNueXpDUmdyL3ZydVJIaWQ0djhHVUlsQ1MxZzNPTURBRVl2WWZhU1Nmd1lXYm12enVrV2hMVXhFMmVnU1crbmJ6bGthQlBvaS82RHI4K1JheHNwcGhOUkZIU3ZkSDNuOG45TVcxY2N5TkFpNnZ4Z2hXczI3RThiRDNqYndSU1lobU9DVjl1SFpkVmpmcFVWRW1BU0VnTW56bEpwUXVwSEdUWVNwWjA0YVBxeEVvQ3FsYXFQcmhrbFBhVVJnaEZKTDh5ZnptWU1GMjNhWDVHQTZGUm1zaElMN3ZnT2ZSZWQ2TVRYWkN0dlArVmsxeWVmeWd5NDc1WG5Xb2VZanNKbklWS1lrWm53dThMM2xjeTg1UDhkZzAzbVhDNmg0eFdubkJuNEhRR3dzV2xWQ2NTalYvUUd0aHloRVMybUx1dDhJK2hqYmdiRnorc0dQQnpESFdDSVh3ekRNd2k5d2lyZ3ZjcFk3UEVmclI4NEkvRmpEaUJxclFMc2NtS1ZZTEFuNXQwRFV2TzY5NWRyeDBBK3RuQ2xSQlREVGpBWUp5clNITUQ0NktKYUkxZDZ5MW54Y2xubGhsamFReFFsa3lZdmZzaGVHSEUxMkhkTW13MTgxV3p4RS9pQ2F0NDRUVzBVQkM1YWxpNGE4Ykcrb3VxU1Fua1owTUpibnVjZGJHZGtjVzFwekNONFpSeVRDcXBKS1RhWFRiNjRJUEJyNS9MTDk1c05pQWFVY2lNajNqcDdGQjBkN05DRnAvVHBxaEE1cEJRTVI0cmdXZEZhKzVTUUExUE1iVTdVUTdWNmZVTzFKbDBnVHUvRjBIYzNQenBmMC92OXZSN01xVENwMHBFbSthUzdsb3Q2SG5WZzc1OHJlWkw0MTBGSGxSVU1uU0VIVENVWkRpaTFnVEdaYVNaOEg3aTRYNnBHNUQzTkZOVktERkFrL2c5dnBqL0ozc211eXh3VWVpMzZRU3MyWEp0QzBtbXdLeU5NZGo5SDRCYllOT3pqNTg1bUlXR0t0OHJ1TThwK21qUE1yQ1FZVVU1VTZZYTgzV1JqdDh3ZzBoRjBBQVRER1RwNlp2WHRTSlFRSjRrS3ROb2RpRFpSa1FkWC9HVVJ5bDlkcGxuVHZIRnUyRnRXUUFmQkUyT2JYVEFMcVBSRWZRNEFLanRZWmtkN1F6SU1kRTNPT0FFckdKNG5UVG14S2pIdjFIN2dwU3UzNnpHVUE1SXlZTnZpbXFENkRJT2h5eXNQL0ZCaS8vZi8vK2dTZUhsenNLM1JRb2p0NXpqb2dSa3YrMWoxUXlQTTlURzg3TEdiRjg2ajBvdW5nY2I2b0VkZitLQVk1YzJlNzFzdkw3NFFkMHNwZWhpMGdSR1U3QmxFMkxMMjlsK2JBcGM5aDg0YTlEUE5Eam14c0F3Vmg2NEoydU5hMlZady96UUQzaWp2cmNFdERlNlFwcnVMTFRVNUlmY09yb3hxbU5SbUpER01MWE1CRDU0VjAwaWNjRERVOFF0ZHhTa0N2WjNaVTIyTnBYV2FDTDc0R0VSQWtKVjBqbUxFWlZZbVNNc01uMWpsdzMxR0E0b0VwcWtQVnd6ajFvcTZ0UDh2bnZuaFRRZzVBRUY0TE5Ca21HRmNNNGNhSVRNa21XSFFRcFlQcnRsVm00VlI0aUJkZDRXQmtXdUU4TVQzZFl1OUNWVS95RzBTL083K3VPU0JncjBGbGxhdytEK0kvSzRlRG52Ym54U3dWU1duWjY5WUpTNXJKbldRSTNpa0hiUkEzQjdrSC9LUHY2Y2ZJRzV6b0huQUdLd2V1ZDRFeHltVHBTcytrNlJvMEplVHpZL3hFeHVwT0FKY3pxV2dxVk54dHhnWUs1OXFkWjRFZ0V4Z0dKK3JneCtxdjhGak5tNDlheFhJaVFKMUVUNmxtSFBCWDhqQmZxKy83Y3NqNHNxdENXb0ZqeW5jNDJxcXFCUndpRlhxc3FOMmNnbEsxV1dsRmc9PTwvUHVibGljS2V5VmFsdWU+DQo8L1B1YmxpY0tleT4NCjwvUHVibGljS2V5cz4NCjwvUHJvZHVjdEtleUNvbmZpZ3VyYXRpb24+DQo= -------------------------------------------------------------------------------- /OSD/Add-BCToLocalWim.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Add-BCToLocalWim.ps1 4 | - Adds branch cache support to WinPE without having to change the central boot images. 5 | Can be executed in a Task Sequence. 6 | 7 | 8 | $WimRootDir 9 | - The Root of where to look for a folder with the name of the boot image's buildnumber. 10 | These folders should contain an "install.wim" from a Win 10-ISO with the specific buildnumber. 11 | Can be a mapped drive or an UNC-Path. 12 | 13 | Eg. -WimRootDir \\dp1\Win10Wims 14 | Boot image is 1809 (Has the buildnumber 17763) 15 | 16 | The script then tries to find \\dp1\Win10Wims\17763\Install.wim 17 | 18 | 19 | Version 0.1 - 20191020 - Initial POC 20 | 21 | Mattias Cedervall 22 | 23 | For details: https://someguy100.wixsite.com/sccm802dot1x/blog/add-branchcache-support-to-winpe-without-modifying-any-central-boot-image 24 | 25 | #> 26 | 27 | Param( 28 | [Parameter(Mandatory=$True)] 29 | [String] $WimRootDir, 30 | [Parameter(ParameterSetName="SKU")] 31 | [String] $SKU="Ent" 32 | ) 33 | 34 | 35 | #Controls the index used when mounting Install.wim 36 | 37 | switch ($SKU) 38 | { 39 | "Ent" {$index=3} 40 | "Edu" {$index=1} 41 | } 42 | 43 | 44 | function PSobjectFromOutput ([String[]]$strArray, [int]$StartLine) 45 | { 46 | $PSCustomObject=New-object PSobject 47 | foreach ($line in $strArray[$StartLine..$strArray.Count].Trim()) 48 | { 49 | if ($line -match ":") 50 | { 51 | $split=$line.split(":") 52 | $PSCustomObject | Add-Member -NotePropertyName $split[0].Trim() -NotePropertyValue $split[1].Trim() 53 | } 54 | } 55 | return $PSCustomObject 56 | } 57 | 58 | 59 | ################ MAIN ##################### 60 | 61 | $tsenv=New-Object -ComObject Microsoft.Sms.TSEnvironment 62 | $LogDir=$tsenv.Value("_SMSTSLogPath") 63 | Start-Transcript -Path $LogDir\Add-BCToLocalWim.log -Append 64 | 65 | #If running in FullOS we need to know where OSDDownloadContent.exe is located 66 | 67 | $TSM=Get-Process -Name TSManager 68 | $BinDir=($TSM.Path).ToLower().Replace($TSM.Description.ToLower(),"") 69 | 70 | 71 | #Makes references to these folders easier and available if the TS-Editor 72 | 73 | $DataDir=$tsenv.Value("_SMSTSMDataPath") 74 | $TSImageID=$tsenv.Value("_SMSTSBootImageID") 75 | $WinPEGenDir=$TSEnv.Value("WinPEGen01") 76 | 77 | 78 | #Code stolen *cough* I mean borrowed from @NickolajA (SCConfigMgr)'s Invoke-CMApplyDriverPackage.ps1 79 | #https://github.com/SCConfigMgr/ConfigMgr/blob/master/Operating%20System%20Deployment/Drivers/Invoke-CMApplyDriverPackage.ps1 80 | 81 | #It's more comfortable to edit the boot-image before it is staged for the first time and the BCD is written. 82 | 83 | $tsenv.Value("OSDDownloadDownloadPackages")=$TSImageID 84 | $tsenv.Value("OSDDownloadDestinationPath")=$DataDir 85 | $tsenv.Value("OSDDownloadDestinationLocationType")="TSCache" 86 | $TSEnv.Value("OSDDownloadDestinationVariable") ="ImageDir" 87 | 88 | 89 | #Forces the download of the bootimage bound to the TS. 90 | 91 | $Proc=Start-process ($($BinDir)+"OSDDownloadContent.exe") -Wait -PassThru -NoNewWindow 92 | 93 | 94 | #Gets the directory of the downloaded Wim. 95 | 96 | $ImageDir=$TSEnv.Value("ImageDir01") 97 | 98 | $TSEnv.Value("OSDDownloadDownloadPackages") = [System.String]::Empty 99 | $TSEnv.Value("OSDDownloadDestinationPath")=[System.String]::Empty 100 | $TSEnv.Value("OSDDownloadDestinationLocationType") = [System.String]::Empty 101 | $TSEnv.Value("OSDDownloadDestinationVariable") =[System.String]::Empty 102 | 103 | 104 | #Gets the FullPath of the wim-file located in 'ImageDir01' 105 | 106 | $ImageLocalPath=(Get-Item -Path "$imageDir\*" -Filter *.wim).FullName 107 | 108 | 109 | #There's a better way of getting this info, see the function PSobjectFromOutput. Just havn't had time to implement it yet. 110 | 111 | $ImageInfo=Dism.exe /Get-WimInfo /WimFile:"$ImageLocalPath" /index:1 112 | $Arch="x86" 113 | 114 | 115 | #I've made this in order to support multiple WinPE-versions without changing this script all too much. 116 | #Gets the Architecture of the bootimage so we know what version of WinPEGen to run. 117 | 118 | #It also gets the buildnumber of the bootimage and tries to match it to a folder of the same name located in the $WimRootDir. 119 | #When you switch ADK, all you need to do is to create a folder below $WimRootDir with the new buildnumber and to copy a Win10-install.wim file of the same version to that folder. 120 | 121 | $FullVersion=($ImageInfo | Select-String "Version ").ToString().Split(":")[1].Trim() 122 | $BuildNumber=([Version]$FullVersion).Build 123 | 124 | if ($ImageInfo.Contains("Architecture : x64")) 125 | { 126 | $Arch="x64" 127 | } 128 | 129 | 130 | #WinPEGen mounts images in the "tmp"-folder. 131 | #X:\Temp hasn't got too much available space and I do trust SCCM to have choosen a HDD with far more. 132 | 133 | $NewTmpFolder=$DataDir.Substring(0,3)+"TempMount" 134 | if ([System.IO.Directory]::Exists($NewTmpFolder) -eq $False) 135 | { 136 | $TmpFolder=New-Item -Type Directory -Path $NewTmpFolder 137 | } 138 | 139 | Write-host "Boot Image info" 140 | write-host "Build: $BuildNumber" 141 | Write-host "Architecture: $Arch" 142 | Write-host "Starting WinPEGen" 143 | 144 | 145 | #A Good place to force an error if a Win10-source for the current build isn't found. 146 | 147 | if ([System.IO.Directory]::Exists("$WimRootDir\$BuildNumber")) 148 | { 149 | Write-host "Detected Win10 Wim-path:$WimRootDir\$BuildNumber" 150 | } 151 | 152 | 153 | #Write outputs to the console. 154 | 155 | write-host "CommandLine: $WinPEGenDir\$Arch\WinPEGen.exe" $WimRootDir\$BuildNumber\install.wim $index $ImageLocalPath 1 156 | 157 | 158 | #Save the hash in order to check if the wim was changed. 159 | 160 | $PreEditHash=(Get-FileHash "$ImageLocalPath").Hash 161 | 162 | 163 | #Changes the tmp variable, launches WinPEGen and restores tmp once we're done. 164 | 165 | $OldTmpEnv=[System.Environment]::GetEnvironmentVariable("tmp") 166 | $NewTmpEnv=[System.Environment]::SetEnvironmentVariable("tmp",$NewTmpFolder) 167 | 168 | 169 | #Don't know who Bob is, but he's next in line. ^^ 170 | 171 | & "$WinPEGenDir\$Arch\WinPEGen.exe" "$WimRootDir\$BuildNumber\install.wim" $index "$ImageLocalPath" 1 172 | [System.Environment]::SetEnvironmentVariable("tmp", $OldTmpEnv) 173 | Start-Sleep -s 2 174 | 175 | #Check if the bootimage has been changed. 176 | 177 | $NewHash=(Get-FileHash "$ImageLocalPath").Hash 178 | 179 | if ($PreEditHash -ne $NewHash) 180 | { 181 | $TSEnv.Value("BCGood2Go") = "True" 182 | } 183 | Stop-Transcript 184 | -------------------------------------------------------------------------------- /OSD/Add-BCToLocalWimWIP.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Version: 0.3 4 | 5 | Add-BCToLocalWim.ps1 6 | - Adds branch cache support to WinPE without having to change the central boot images. 7 | Can be executed in a Task Sequence. 8 | 9 | 10 | $WimRootDir 11 | - The Root of where to look for a folder with the name of the boot image's buildnumber. 12 | These folders should contain an "install.wim" from a Win 10-ISO with the specific buildnumber. 13 | Can be a mapped drive or an UNC-Path. 14 | 15 | Eg. -WimRootDir \\dp1\Win10Wims 16 | Boot image is 1809 (Has the buildnumber 17763) 17 | 18 | The script then tries to find \\dp1\Win10Wims\17763\Install.wim 19 | 20 | Version 0.3 - 20191129 - added verification of paths, added ProgressUI error dialog and output from WinPEGen 21 | Version 0.2 - 20191025 - Added if's, some additional logging and made a psobject out of the dism output. 22 | Version 0.1 - 20191020 - Initial POC 23 | 24 | Mattias Cedervall 25 | 26 | #> 27 | 28 | Param( 29 | [Parameter(Mandatory=$True)] 30 | [String] $WimRootDir, 31 | [Parameter(ParameterSetName="SKU")] 32 | [String] $SKU="Ent", 33 | [Parameter(Mandatory=$False)] 34 | [Switch] $PEGenOutToLog 35 | ) 36 | 37 | #Controls the index used when mounting Install.wim 38 | 39 | switch ($SKU) 40 | { 41 | "Ent" {$index=3} 42 | "Edu" {$index=1} 43 | } 44 | 45 | 46 | 47 | function AbortWithExitCode ($ExtCode,$Msg) 48 | { 49 | $tsProgressUI=New-Object -ComObject Microsoft.Sms.TSProgressUI 50 | $tsProgressUI.ShowErrorDialog($TSEnv["_SMSTSOrgName"],$TSEnv["_SMSTSPackageName"],$TSEnv["_SMSTSPackageName"],$Msg,[string]$ExtCode,180,0,$TSEnv["_SMSTSCurrentActionName"]) 51 | #$TSEnv.Value("TSDisableProgressUI")="True" 52 | Stop-Transcript 53 | Exit $ExtCode 54 | } 55 | 56 | function PSobjectFromOutput ([String[]]$strArray, [int]$StartLine, [String]$Pattern) 57 | { 58 | $PSCustomObject=New-object PSobject 59 | foreach ($line in $strArray[$StartLine..$strArray.Count].Trim()) 60 | { 61 | if ($line -like $Pattern) 62 | { 63 | $split=$line.Split(":",2) 64 | $PSCustomObject | Add-Member -NotePropertyName $split[0].Trim() -NotePropertyValue $split[1].Trim() 65 | } 66 | } 67 | return $PSCustomObject 68 | } 69 | 70 | function VerifyPath ($Path,$Name) 71 | { 72 | if ($Path -in ($null,"")) 73 | { 74 | AbortWithExitCode 1 "$Name - Path is null`/empty" 75 | return 76 | } 77 | $Result=Test-path "$Path" 78 | if ($Result -eq $False) 79 | { 80 | AbortWithExitCode 5 "$Name - $Path was not found" 81 | } 82 | else 83 | { 84 | write-host "$Name - path was found" 85 | } 86 | } 87 | ################ MAIN ##################### 88 | 89 | $tsenv=New-Object -ComObject Microsoft.Sms.TSEnvironment 90 | $LogDir=$tsenv.Value("_SMSTSLogPath") 91 | Start-Transcript -Path $LogDir\Add-BCToLocalWim.log -Append -Force 92 | 93 | #If running in FullOS we need to know where OSDDownloadContent.exe is located 94 | 95 | $TSM=Get-Process -Name TSManager 96 | $BinDir=($TSM.Path).ToLower().Replace($TSM.Description.ToLower(),"") 97 | 98 | 99 | #Makes references to these folders easier and available if the TS-Editor 100 | 101 | $DataDir=$tsenv.Value("_SMSTSMDataPath") 102 | $TSImageID=$tsenv.Value("_SMSTSBootImageID") 103 | $WinPEGenDir=$TSEnv.Value("WinPEGen01") 104 | 105 | 106 | #Code stolen *cough* I mean borrowed from @NickolajA (SCConfigMgr)'s Invoke-CMApplyDriverPackage.ps1 107 | #https://github.com/SCConfigMgr/ConfigMgr/blob/master/Operating%20System%20Deployment/Drivers/Invoke-CMApplyDriverPackage.ps1 108 | 109 | #It's more comfortable to edit the boot-image before it is staged for the first time and the BCD is written. 110 | 111 | $tsenv.Value("OSDDownloadDownloadPackages")=$TSImageID 112 | $tsenv.Value("OSDDownloadDestinationPath")=$DataDir 113 | $tsenv.Value("OSDDownloadDestinationLocationType")="TSCache" 114 | $TSEnv.Value("OSDDownloadDestinationVariable") ="ImageDir" 115 | 116 | 117 | #Forces the download of the bootimage bound to the TS. 118 | 119 | $Proc=start-Process ($($BinDir)+"OSDDownloadContent.exe") -Wait -PassThru -NoNewWindow 120 | write-host "Download Exit Code:" $Proc.ExitCode.ToString() 121 | 122 | if ($Proc.ExitCode -ne 0) 123 | { 124 | write-host "Download Failed" 125 | AbortWithExitCode $Proc.ExitCode "Error while downloading boot image." 126 | } 127 | 128 | #Gets the directory of the downloaded Wim. 129 | 130 | $ImageDir=$TSEnv.Value("ImageDir01") 131 | 132 | $TSEnv.Value("OSDDownloadDownloadPackages") = [System.String]::Empty 133 | $TSEnv.Value("OSDDownloadDestinationPath")=[System.String]::Empty 134 | $TSEnv.Value("OSDDownloadDestinationLocationType") = [System.String]::Empty 135 | $TSEnv.Value("OSDDownloadDestinationVariable") =[System.String]::Empty 136 | 137 | 138 | #Gets the FullPath of the wim-file located in 'ImageDir01' 139 | 140 | $ImageLocalPath=(Get-Item -Path "$imageDir\*" -Filter *.wim).FullName 141 | 142 | VerifyPath "$ImageLocalPath" "Boot Wimfile" 143 | 144 | $ImageInfo=Dism.exe /Get-WimInfo /WimFile:"$ImageLocalPath" /index:1 145 | 146 | $ImageInfo2=PSobjectFromOutput $ImageInfo 3 "* : *" 147 | 148 | $Arch=$ImageInfo2.Architecture 149 | $FullVersion=$ImageInfo2.Version 150 | #$Arch="x86" 151 | 152 | 153 | #I've made this in order to support multiple WinPE-versions without changing this script all too much. 154 | #Gets the Architecture of the bootimage so we know what version of WinPEGen to run. 155 | 156 | #It also gets the buildnumber of the bootimage and tries to match it to a folder of the same name located in the $WimRootDir. 157 | #When you switch ADK, all you need to do is to create a folder below $WimRootDir with the new buildnumber and to copy a Win10-install.wim file of the same version to that folder. 158 | 159 | 160 | #$FullVersion=($ImageInfo | Select-String "Version ").ToString().Split(":")[1].Trim() 161 | $BuildNumber=([Version]$FullVersion).Build 162 | 163 | <# 164 | if ($ImageInfo.Contains("Architecture : x64")) 165 | { 166 | $Arch="x64" 167 | } 168 | #> 169 | 170 | #WinPEGen mounts images in the "tmp"-folder. 171 | #X:\Temp hasn't got too much available space and I do trust SCCM to have choosen a HDD with far more. 172 | 173 | $NewTmpFolder=$DataDir.Substring(0,3)+"TempMount" 174 | if ([System.IO.Directory]::Exists($NewTmpFolder) -eq $False) 175 | { 176 | $TmpFolder=New-Item -Type Directory -Path $NewTmpFolder 177 | } 178 | 179 | Write-host "Boot Image info" 180 | write-host "Build: $BuildNumber" 181 | Write-host "Architecture: $Arch" 182 | 183 | 184 | #A Good place to force an error if a Win10-source for the current build isn't found. 185 | 186 | 187 | 188 | $Win10Wim="$WimRootDir\$BuildNumber\install.wim" 189 | write-host "Win10 Wim Path: $Win10Wim" 190 | VerifyPath "$Win10Wim" "Win10 Wimfile" 191 | 192 | VerifyPath "$WinPEGenDir\$Arch\WinPEGen.exe" "WinPEGen Path" 193 | 194 | 195 | #Extra check 196 | $RunPEGen=$false 197 | if (([System.IO.File]::Exists("$WimRootDir\$BuildNumber\install.wim")) -and ([System.IO.File]::Exists($ImageLocalPath))) 198 | { 199 | Write-host "Detected Win10 Wim-path:$WimRootDir\$BuildNumber\install.wim" 200 | $RunPEGen=$true 201 | } 202 | 203 | 204 | if ($RunPEGen -eq $true) 205 | { 206 | write-host "Starting WinPEGen" 207 | #Write output to the console. 208 | 209 | #Save the hash in order to check if the wim was changed. 210 | 211 | $PreEditHash=(Get-FileHash "$ImageLocalPath").Hash 212 | 213 | 214 | #Changes the tmp variable, launches WinPEGen and restores tmp once we're done. 215 | 216 | $OldTmpEnv=[System.Environment]::GetEnvironmentVariable("tmp") 217 | $NewTmpEnv=[System.Environment]::SetEnvironmentVariable("tmp",$NewTmpFolder) 218 | 219 | 220 | #Don't know who Bob is, but he's next in line. ^^ 221 | #$index=7 222 | 223 | write-host "CommandLine: $WinPEGenDir\$Arch\WinPEGen.exe" $WimRootDir\$BuildNumber\install.wim $index $ImageLocalPath 1 224 | $PEGenOut=& "$WinPEGenDir\$Arch\WinPEGen.exe" "$WimRootDir\$BuildNumber\install.wim" $index "$ImageLocalPath" 1 225 | $lastexit=$LASTEXITCODE 226 | Write-host "LASTEXITCODE after WinPEGen:" $lastexit 227 | 228 | #write the output of WinPEGen to the log. 229 | 230 | if ($PEGenOutToLog) 231 | { 232 | Write-output $PEGenOut 233 | } 234 | 235 | [System.Environment]::SetEnvironmentVariable("tmp", $OldTmpEnv) 236 | Start-Sleep -s 2 237 | 238 | #Restore the tmp variable before exiting 239 | if ($lastexit -ne 0) 240 | { 241 | write-host $PEGenOut[($PEGenOut.Count-3)..($PEGenOut.Count-1)] 242 | AbortWithExitCode $lastexit "WinPEGen message: $($PEGenOut[($PEGenOut.Count-3)..($PEGenOut.Count-1)])" 243 | } 244 | 245 | #Check if the bootimage has been changed. 246 | 247 | $NewHash=(Get-FileHash "$ImageLocalPath").Hash 248 | 249 | if ($PreEditHash -ne $NewHash) 250 | { 251 | $TSEnv.Value("BCGood2Go") = "True" 252 | } 253 | else 254 | { 255 | AbortWithExitCode 10 "The Boot image was unchanged.`r`n Start the script with '-PEGenOutToLog' and check $LogDir\Add-BCToLocalWim.log for more details." 256 | } 257 | } 258 | else 259 | { 260 | $text="Couldn't find the files needed for WinPEGen." 261 | Write-host $text 262 | AbortWithExitCode 666 $text 263 | 264 | } 265 | Stop-Transcript 266 | -------------------------------------------------------------------------------- /OSD/Download-AppxFromStore.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Update 2020-02-18 4 | Thanks @BruceDawson0xB for pointing out the flaw in the regex pattern. if %tmp% began with a lowercase char the script would fail. 5 | 6 | Update 2020-02-14 7 | Thanks @jarwidmark for letting me know that this had Office as a dependency and for testing the workaround. 8 | -The script now works even if you don't have Office installed. 9 | 10 | Downloads any free app and its dependencies from the Microsoft store. 11 | 12 | Drivers are starting to implement store apps to be fully functional. 13 | The analogue 3.5mm headphone connector not working on some models without the app. 14 | The driver package from the manufacturer only contains a batch file which opens the store in your web browser. 15 | And I can't find the app in the business store... 16 | 17 | Also heard of a similar case with the thunderbolt app. 18 | 19 | If the manufacturers would include these in their driver packages I wouldn't have to do this. 20 | But I can see why they don't.. 21 | 22 | There's this "small" issue with deploying .Appx and AppxBundles during an OSD. 23 | But that script will be done and uploaded in a cuple of days or so. :) 24 | 25 | 26 | The real heroes here are the ppl behind this site: 27 | https://store.rg-adguard.net 28 | 29 | I'm just poking their API. 30 | 31 | -StoreURL Examples: 32 | 33 | -StoreURL https://www.microsoft.com/store/apps/9n6f0jv38ph1 34 | -StoreURL https://www.microsoft.com/en-us/p/thunderbolt-control-center/9n6f0jv38ph1 35 | #> 36 | 37 | Param ( 38 | [Parameter(Mandatory=$True)] 39 | [string] $StoreURL, 40 | [Parameter(Mandatory=$False)] 41 | $SavePathRoot="%tmp%" 42 | ) 43 | 44 | # 45 | 46 | if ($StoreURL.EndsWith("/")) 47 | { 48 | #write-host "Ends with '/'" 49 | $StoreURL=$StoreURL.Remove($StoreUrl.Length-1,1) 50 | } 51 | 52 | $wchttp=[System.Net.WebClient]::new() 53 | $URI = "https://store.rg-adguard.net/api/GetFiles" 54 | $myParameters = "type=url&url=$($StoreURL)" 55 | #&ring=Retail&lang=sv-SE" 56 | 57 | $wchttp.Headers[[System.Net.HttpRequestHeader]::ContentType]="application/x-www-form-urlencoded" 58 | $HtmlResult = $wchttp.UploadString($URI, $myParameters) 59 | 60 | $Start=$HtmlResult.IndexOf("

The links were successfully received from the Microsoft Store server.

") 61 | #write-host $start 62 | 63 | if ($Start -eq -1) 64 | { 65 | write-host "Could not get the links, please check the StoreURL." 66 | exit 67 | } 68 | 69 | $TableEnd=($HtmlResult.LastIndexOf("")+8) 70 | 71 | 72 | $SemiCleaned=$HtmlResult.Substring($start,$TableEnd-$start) 73 | 74 | #https://stackoverflow.com/questions/46307976/unable-to-use-ihtmldocument2 75 | $newHtml=New-Object -ComObject "HTMLFile" 76 | try { 77 | # This works in PowerShell with Office installed 78 | $newHtml.IHTMLDocument2_write($SemiCleaned) 79 | } 80 | catch { 81 | # This works when Office is not installed 82 | $src = [System.Text.Encoding]::Unicode.GetBytes($SemiCleaned) 83 | $newHtml.write($src) 84 | } 85 | 86 | $ToDownload=$newHtml.getElementsByTagName("a") | Select-Object textContent, href 87 | 88 | $SavePathRoot=$([System.Environment]::ExpandEnvironmentVariables("$SavePathRoot")) 89 | 90 | $LastFrontSlash=$StoreURL.LastIndexOf("/") 91 | $ProductID=$StoreURL.Substring($LastFrontSlash+1,$StoreURL.Length-$LastFrontSlash-1) 92 | 93 | # OldRegEx Failed when the %tmp% started with a lowercase char 94 | #if ([regex]::IsMatch("$SavePathRoot\$ProductID","([,!@?#$%^&*()\[\]]+|\\\.\.|\\\\\.|\.\.\\\|\.\\\|\.\.\/|\.\/|\/\.\.|\/\.|;|(? 37 | 38 | Param ( 39 | [Parameter(Mandatory=$True)] 40 | [string] $StoreURL, 41 | [Parameter(Mandatory=$False)] 42 | $SavePathRoot="%tmp%" 43 | ) 44 | 45 | # 46 | 47 | #$StoreURL="https://www.microsoft.com/store/apps/9n6f0jv38ph1" 48 | if ($StoreURL.EndsWith("/")) 49 | { 50 | #write-host "Ends with '/'" 51 | $StoreURL=$StoreURL.Remove($StoreUrl.Length-1,1) 52 | } 53 | 54 | $wchttp=[System.Net.WebClient]::new() 55 | $URI = "https://store.rg-adguard.net/api/GetFiles" 56 | $myParameters = "type=url&url=$($StoreURL)" 57 | #&ring=Retail&lang=sv-SE" 58 | 59 | $wchttp.Headers[[System.Net.HttpRequestHeader]::ContentType]="application/x-www-form-urlencoded" 60 | $HtmlResult = $wchttp.UploadString($URI, $myParameters) 61 | 62 | $Start=$HtmlResult.IndexOf("

The links were successfully received from the Microsoft Store server.

") 63 | #write-host $start 64 | 65 | if ($Start -eq -1) 66 | { 67 | write-host "Could not get the links, please check the StoreURL." 68 | exit 69 | } 70 | 71 | $TableEnd=($HtmlResult.LastIndexOf("")+8) 72 | 73 | 74 | $SemiCleaned=$HtmlResult.Substring($start,$TableEnd-$start) 75 | 76 | #https://stackoverflow.com/questions/46307976/unable-to-use-ihtmldocument2 77 | $newHtml=New-Object -ComObject "HTMLFile" 78 | try { 79 | # This works in PowerShell with Office installed 80 | $newHtml.IHTMLDocument2_write($SemiCleaned) 81 | } 82 | catch { 83 | # This works when Office is not installed 84 | $src = [System.Text.Encoding]::Unicode.GetBytes($SemiCleaned) 85 | $newHtml.write($src) 86 | } 87 | 88 | $ToDownload=$newHtml.getElementsByTagName("a") | Select-Object textContent, href,innerText 89 | 90 | $SavePathRoot=$([System.Environment]::ExpandEnvironmentVariables("$SavePathRoot")) 91 | 92 | $LastFrontSlash=$StoreURL.LastIndexOf("/") 93 | $ProductID=$StoreURL.Substring($LastFrontSlash+1,$StoreURL.Length-$LastFrontSlash-1) 94 | 95 | # OldRegEx Failed when the %tmp% started with a lowercase char 96 | #if ([regex]::IsMatch("$SavePathRoot\$ProductID","([,!@?#$%^&*()\[\]]+|\\\.\.|\\\\\.|\.\.\\\|\.\\\|\.\.\/|\.\/|\/\.\.|\/\.|;|(?1906 a week ago and the pre-production went live this Sunday. 5 | Darn _*-Policies :P 6 | 7 | Only tested this to after the "state restore"-group. 8 | I made a big mistake, assuming that if it works up until then, it would work for the rest of the OSD as well. 9 | But the client agent is actually initiated for program/application installations. And that will fail since the 10 | client will recieve the unmodified policy. 11 | Working on a fix atm. 12 | 13 | #> 14 | Param ( 15 | [parameter(Mandatory = $true)] 16 | [string]$TSDeploymentID 17 | ) 18 | 19 | 20 | $date=(Get-date) 21 | 22 | $SMSClient=[wmiclass]"root/ccm:SMS_Client" 23 | 24 | $pol=Get-CimInstance -class ccm_Policy -Namespace root/ccm/Policy/Machine/ActualConfig | Where-Object {($_.ADV_AdvertisementID -eq $TSDeploymentID)} 25 | $MainTS=$pol | Where-Object {($_.CimClass.CimClassName -eq "CCM_TaskSequence") -and ($_.TS_Type -eq "2")} 26 | $MainTS.ADV_MandatoryAssignments=$true 27 | $MainTS | Set-CimInstance 28 | 29 | [xml]$TSReqs=$MainTS.Prg_Requirements 30 | $SchedID=$TSReqs.SWDReserved.ScheduledMessageID 31 | 32 | 33 | if ($pol) 34 | { 35 | foreach ($cim in $pol) 36 | { 37 | write-host $Cim.PKG_Name $Cim.ADV_ActiveTime 38 | $cimInstance=Get-CimInstance $cim 39 | $out=Set-CimInstance -InputObject $cimInstance -Property @{ADV_ActiveTime=[datetime]::Today} -PassThru | out-null 40 | 41 | } 42 | } 43 | 44 | ([wmiclass]"root\ccm:SMS_Client").TriggerSchedule($SchedID) 45 | -------------------------------------------------------------------------------- /OSD/Wrapper.ps1: -------------------------------------------------------------------------------- 1 | $Logfile="X:\Windows\temp\EarlyTSLog.log" 2 | If ([System.IO.File]::Exists($LogFile)) 3 | { 4 | exit 5 | } 6 | Start-Transcript -Path $Logfile 7 | $ScriptDir=[System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definition) 8 | 9 | $TSEnvExists=$false 10 | while ($TSEnvExists -eq $false) 11 | { 12 | Try 13 | { 14 | Start-Sleep -Seconds 1 15 | $tsenv=New-Object -ComObject Microsoft.sms.TSEnvironment 16 | 17 | try 18 | { 19 | $TS=New-object -ComObject Microsoft.sms.TSEnvironment 20 | if (($TS.GetVariables().Count) -gt 0) 21 | { 22 | foreach($TSVar in $TS.GetVariables()) 23 | { 24 | write-host $TSVar"="($TS["$TSVar"]) 25 | } 26 | $TSEnvExists=$true 27 | } 28 | 29 | } 30 | catch 31 | { 32 | write-host "Waiting for TSEnv to be available..." 33 | Start-Sleep -Seconds 2 34 | } 35 | } 36 | catch 37 | { 38 | $tsenv=$null 39 | } 40 | $tsenv=$null 41 | Start-Sleep -Seconds 1 42 | } 43 | write-host "TSEnv is now available" 44 | 45 | 46 | try 47 | { 48 | $tsenv=New-Object -ComObject Microsoft.sms.TSEnvironment 49 | } 50 | catch 51 | { 52 | write-host "Error before setting TSVariable" 53 | } 54 | 55 | If (($tsenv["ScriptHasRun"]) -eq "True") 56 | { 57 | write-host "Script has already run." 58 | } 59 | else{ 60 | #DoStuff #If triggering another script let it set the 'ScriptHasRun' variable 61 | 62 | write-host "Script will be executed." 63 | $tsenv["ScriptHasRun"]="True" 64 | } 65 | $tsenv=$null 66 | 67 | Stop-Transcript 68 | exit -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Scripts 2 | A mix of scripts I've made, or at least put together 3 | 4 | Create-FireWallRule.ps1 - Create Firewall rules, even in WinPE 5 | ![alt text](https://raw.githubusercontent.com/MattiasC85/Scripts/master/CreateFWRule.png) 6 | 7 | test-port.ps1 - Test connection to hostname on specific port, in WinPE 8 | 9 | UserSid-Coverter.ps1 - Converts SID/Username back and forwards. 10 | 11 | Get-CredentialGuardStatus.ps1 - CredentialGuard configuration and service status. 12 | 13 | Get-InstalledUpdates.ps1 - Installed updates by searching history. 14 | 15 | Get-RegistryKeyLastWriteTime.ps1 - Get LastWriteTime of registry key 16 | 17 | Keycheck - Tool that checks the embedded product key in bios. Works on Win7x86, Winpe (with .net 4) and ofc win10x64. 18 | Used to determine if the key is for core(Home) or Pro. Great when deploying both EDU and ENT windows versions. 19 | Must have a wrapper if running in a TS. Will give an exit code of 600 if pro and 601 if home. 20 | -------------------------------------------------------------------------------- /ScriptUserWrapperPOC/Invoke-SCCMScriptUserTarget.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Gets all the online computers where the name of the console session matches the "usernames"-param. 4 | And triggers a (SCCM) run script action of the choosen computers 5 | .DESCRIPTION 6 | Work in progress 7 | .INPUTS 8 | -SiteServer 9 | The SCCM-site server. 10 | 11 | -SiteCode 12 | The SCCM-site code. 13 | 14 | -UserNames 15 | A string array of usernames to search for. Supports short domain names and % as a wildcard 16 | 17 | -ScriptToDownloadAndRun 18 | UNC-, http- or file -path to the script to download and execute. 19 | \\Server\file.ps1, http://Server/file.ps1, Z:\folder\file.ps1 20 | 21 | -ScriptWrapperName 22 | The name of the script in the SCCM console. 23 | 24 | -RunInUserContext 25 | 0 or 1. 1 = Runs the script in the context and privilege of the targeted user. 26 | 27 | -DownloadLoc 28 | Directory where the downloaded script is stored. 29 | 30 | -SkipVerificationPrompt 31 | Skips the prompt to choose targets and runs the script on all targets matching -Usernames. 32 | Except on servers ofc =) 33 | 34 | .EXAMPLE 35 | Invoke-SCCMScriptUserTarget.ps1 -SiteServer Siteserver1 -SiteName am1 -UserNames ("%mcel","domain\user01") -ScriptToDownloadAndRun "\\server\WrapperShare$\Msgbox\msgbox3.ps1" -ScriptWrapperName "UserWrapper" 36 | #> 37 | Param ( 38 | [Parameter(ValueFromPipelineByPropertyName,Mandatory=$True)] 39 | [string] $SiteServer, 40 | [Parameter(ValueFromPipelineByPropertyName,Mandatory=$True)] 41 | [string] $SiteName, 42 | [Parameter(ValueFromPipelineByPropertyName,Mandatory=$True)] 43 | [string[]] $UserNames, 44 | [Parameter(Mandatory=$True)] 45 | [string]$ScriptToDownloadAndRun, 46 | [Parameter(Mandatory=$True)] 47 | [string]$ScriptWrapperName="WrapperLastOne", 48 | [Parameter(Mandatory=$False)] 49 | [int]$RunInUserContext=1, 50 | [Parameter(Mandatory=$False)] 51 | [string]$DownloadLoc="%windir%\UserScriptStore", 52 | [Parameter(Mandatory=$False)] 53 | [Switch]$SkipVerificationPrompt, 54 | [Parameter(ValueFromPipelineByPropertyName,Mandatory=$False)] 55 | $Domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name # NETBIOSName of remote domain or leave blank for current 56 | ) 57 | 58 | 59 | Function Main 60 | { 61 | 62 | if (($UserNames -join ",").Contains("%") -eq $false) 63 | { 64 | write-host "Observe that UserName is accepting Wildcards in the form of '%'" -ForegroundColor DarkYellow 65 | } 66 | 67 | $BuildDomainName=$null 68 | if ($Domain.Contains(".") -eq $true) 69 | { 70 | $DomainBefore=$Domain 71 | $SplitDomain=$Domain.ToString().Split(".") 72 | 73 | Foreach ($part in $SplitDomain) 74 | { 75 | $BuildDomainName=($BuildDomainName+"dc=$part,") 76 | } 77 | 78 | $BuildDomainName=($BuildDomainName.SubString(0,$BuildDomainName.Length-1)) 79 | #write-host $BuildDomainName 80 | 81 | $Domain=(Get-ADDomain $BuildDomainName).NetBIOSName 82 | 83 | } 84 | 85 | $namespace = "ROOT\SMS\site_$SiteName" 86 | $classname = "SMS_CombinedDeviceResources" 87 | #$Domain=$Domain.ToUpper() 88 | #$UserNames=$UserNames.ToLower().Replace(($Domain.ToLower()+'\'),"") 89 | 90 | write-host "UserNames:"$UserNames 91 | 92 | 93 | #Builds the Targets-object 94 | $Targets=Foreach ($User in $UserNames) 95 | { 96 | $User=$User.replace("\","\\") 97 | $BuildTargets=Get-WmiObject -Query "select Name,ResourceID,CNIsOnline,CurrentLogonUser from SMS_CombinedDeviceResources where CurrentLogonUser like '$User' and CNIsOnline=1" -ComputerName $SiteServer -Namespace $namespace | select Name, CurrentLogonUser, ResourceID, CNIsOnline 98 | $BuildTargets 99 | } 100 | 101 | 102 | write-host "Targets found:" ($Targets.Count) 103 | write-host "Checking for duplicate ResourceID's" 104 | #Removes duplicate target objects (That Eg. '-UserNames ("%01","%er01")' would return) 105 | $Targets=($Targets | Sort-Object -Property ResourceID -Unique) 106 | write-host "Targets after cleanup:" ($Targets.Count) 107 | 108 | If (!$Targets) 109 | { 110 | Write-host "No targets found." 111 | break 112 | } 113 | #Adds index property on each target object. 114 | $index=0 115 | Foreach ($Target in $Targets) 116 | { 117 | $Target | Add-Member -MemberType NoteProperty -Name "Index" -Value $index -Force 118 | #$Target | Format-Table 119 | $index++ 120 | } 121 | 122 | 123 | $TargetList=$null 124 | 125 | #Lets you view and choose targets before execution. 126 | if (!$SkipVerificationPrompt) 127 | { 128 | $Targets 129 | while ($TargetList -in ("",$null)) 130 | { 131 | [ValidatePattern('^(\d+(,\d+)*|all)$')]$TargetList=Read-host "Type the indexes of the targets that you want to run the script on with ',' as the separator or 'all' to include all targets." 132 | if ($TargetList -eq "all") 133 | { 134 | $TargetList=($Targets.Index -join ",") 135 | 136 | } 137 | 138 | } 139 | $Targets=$Targets | Where-Object -Property Index -in ($TargetList.split(",")) 140 | } 141 | write-host "" 142 | Write-Host "Will execute the script on the following computers:" -ForegroundColor Yellow 143 | $Targets.Name 144 | write-host "The script will execute if the console user is in this list:" -ForegroundColor Yellow 145 | $Targets.CurrentLogonUser 146 | 147 | $TargetUsers=($Targets.CurrentLogonUser -join ",") 148 | 149 | #The params to send to the wrapper script. 150 | [Array]$Parameter = @( 151 | @{Name="DownloadLoc";Value=$DownloadLoc}, 152 | @{Name="RunInUserContext";Value=$RunInUserContext}, 153 | @{Name="Users";Value=$TargetUsers}, 154 | @{Name="ScriptToDownloadAndRun";Value=$ScriptToDownloadAndRun}, 155 | @{Name="ScriptHash";Value=((Get-FileHash $ScriptToDownloadAndRun).Hash)} 156 | ) 157 | 158 | $Execute=Invoke-SCCMRunScript -SiteServer $SiteServer -Namespace $namespace -ScriptName $ScriptWrapperName -TargetResourceIDs @($Targets.ResourceID) -InputParameters @($Parameter) 159 | write-host "Done, returnvalue is:" $Execute.ReturnValue 160 | } 161 | 162 | 163 | function Invoke-SCCMRunScript { 164 | 165 | <# 166 | Robert Johnsson's Invoke-SCCMRunScript 167 | https://twitter.com/johnsson_r 168 | https://gist.github.com/Robert-LTH/7423e418aab033d114d7c8a2df99246b#> 169 | 170 | param( 171 | [Parameter(Mandatory=$true)] 172 | [ValidateNotNullOrEmpty()] 173 | [string]$SiteServer, 174 | [Parameter(Mandatory=$true)] 175 | [ValidateNotNullOrEmpty()] 176 | [string]$Namespace, 177 | [Parameter(Mandatory=$true)] 178 | [ValidateNotNullOrEmpty()] 179 | [string]$ScriptName, 180 | [Array]$InputParameters = @(), 181 | [string]$TargetCollectionID = "", 182 | [Array]$TargetResourceIDs = @() 183 | ) 184 | # if something goes wrong, we want to stop! 185 | $ErrorActionPreference = "Stop" 186 | 187 | # We can not run on all members of a collection AND selected resources 188 | if (-not ([string]::IsNullOrEmpty($TargetCollectionID)) -and $TargetResourceIDs -gt 0) { 189 | throw "Use either TargetCollectionID or TargetResourceIDs, not both!" 190 | } 191 | if (([string]::IsNullOrEmpty($TargetCollectionID)) -and $TargetResourceIDs -lt 1) { 192 | throw "We need some resources (devices) to run the script!" 193 | } 194 | 195 | 196 | # Get the script 197 | $Script = [wmi](Get-WmiObject -class SMS_Scripts -Namespace $Namespace -ComputerName $SiteServer -Filter "ScriptName = '$ScriptName'").__PATH 198 | 199 | if (-not $Script) { 200 | throw "Could not find script with name '$ScriptName'" 201 | } 202 | # Parse the parameter definition 203 | $Parameters = [xml]([string]::new([Convert]::FromBase64String($Script.ParamsDefinition))) 204 | 205 | $Parameters.ScriptParameters.ChildNodes | % { 206 | # In the case of a missing required parameter, bail! 207 | if ($_.IsRequired -and $InputParameters.Count -lt 1) { 208 | throw "Script 'ScriptName' has required parameters but no parameters was passed." 209 | } 210 | 211 | if ($_.Name -notin $InputParameters.Name) { 212 | write-host $InputParameters.Name 213 | throw "Parameter '$($_.Name)' has not been passed in InputParamters!" 214 | } 215 | } 216 | 217 | # GUID used for parametergroup 218 | $ParameterGroupGUID = $(New-Guid) 219 | 220 | if ($InputParameters.Count -le 0) { 221 | # If no ScriptParameters: and an empty hash 222 | $ParametersXML = "" 223 | $ParametersHash = "" 224 | } 225 | else { 226 | foreach ($Parameter in $InputParameters) { 227 | $InnerParametersXML = "$InnerParametersXML" 228 | } 229 | $ParametersXML = "$InnerParametersXML" 230 | 231 | $SHA256 = [System.Security.Cryptography.SHA256Cng]::new() 232 | $Bytes = ($SHA256.ComputeHash(([System.Text.Encoding]::Unicode).GetBytes($ParametersXML))) 233 | $ParametersHash = ($Bytes | ForEach-Object ToString X2) -join '' 234 | } 235 | 236 | $RunScriptXMLDefinition = "{1}{2}{3}{4}{5}" 237 | $RunScriptXML = $RunScriptXMLDefinition -f $Script.ScriptGuid,$Script.ScriptVersion,$Script.ScriptType,$Script.ScriptHash,$ParametersXML,$ParametersHash 238 | 239 | # Get information about the class instead of fetching an instance 240 | # WMI holds the secret of what parameters that needs to be passed and the actual order in which they have to be passed 241 | $MC = [WmiClass]"\\$SiteServer\$($Namespace):SMS_ClientOperation" 242 | 243 | # Get the parameters of the WmiMethod 244 | $MethodName = 'InitiateClientOperationEx' 245 | $InParams = $MC.psbase.GetMethodParameters($MethodName) 246 | 247 | # Information about the script is passed as the parameter 'Param' as a BASE64 encoded string 248 | $InParams.Param = ([Convert]::ToBase64String(([System.Text.Encoding]::UTF8).GetBytes($RunScriptXML))) 249 | 250 | # Hardcoded to 0 in certain DLLs 251 | $InParams.RandomizationWindow = "0" 252 | 253 | # If we are using a collection, set it. TargetCollectionID can be empty string: "" 254 | $InParams.TargetCollectionID = $TargetCollectionID 255 | 256 | # If we have a list of resources to run the script on, set it. TargetResourceIDs can be an empty array: @() 257 | # Criteria for a "valid" resource is IsClient=$true and IsBlocked=$false and IsObsolete=$false and ClientType=1 258 | $InParams.TargetResourceIDs = $TargetResourceIDs 259 | 260 | # Run Script is type 135 261 | $InParams.Type = "135" 262 | 263 | # Everything should be ready for processing, invoke the method! 264 | $R = $MC.InvokeMethod($MethodName, $InParams, $null) 265 | 266 | # The result contains the client operation id of the execution 267 | $R 268 | } 269 | 270 | 271 | Main -------------------------------------------------------------------------------- /ScriptUserWrapperPOC/UserWrapper.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattiasC85/Scripts/3687ec33533443bd47e09fada3ec180a78383b5b/ScriptUserWrapperPOC/UserWrapper.gif -------------------------------------------------------------------------------- /ScriptUserWrapperPOC/UserWrapper.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Run a SCCM script as the console user of the targeted machine. 4 | .DESCRIPTION 5 | Use this in SCCM, as a "Run script". The script then downloads another script and executes it as the targeted user on the choosen machine. 6 | .INPUTS 7 | -Users 8 | The users targeted by the script. Needs to match the username of the console session in order for the downloaded script to run. 9 | 10 | -RunInUserContext 11 | 0 or 1. 1 = Runs the script in the context and privilege of the targeted user. 12 | 13 | -ScriptToDownloadAndRun 14 | UNC-, http- or file -path to the script to download and execute. 15 | \\Server\file.ps1, http://Server/file.ps1, Z:\folder\file.ps1 16 | 17 | OBSERVE: 18 | Domain computers needs to have access if the script is located on a share. 19 | 20 | -DownloadLoc 21 | Directory where the downloaded script is stored. 22 | 23 | OBSERVE: 24 | Users need to have read/execute permissions in the folder. But I really advice agains storing the script in a folder where the users 25 | have write-permissions. Could lead to a LPE. (Local privilege escalation) 26 | 27 | -ScriptHash 28 | Hash of the Script to download, just as an extra precaution. Use Get-FileHash to get the it. 29 | 30 | .EXAMPLE 31 | UserWrapper.ps1 -User contoso\user1 -ScriptToDownloadAndRun \\DP\Domaincomputersshare$\msg\msgbox.ps1 -ScriptHash EAE5EDB0FC92B1689BB716E6F15E17003CA5DFF84CDE0D3C3161D3A70634E1FA 32 | Download and run msgbox.ps1 in the context of user1. But only if the console session is user1 and the hash matches 33 | .NOTES 34 | *ToDo* 35 | .TODO 36 | *Get output from the downloaded-script to show in the SCCM Console under "Run details" 37 | *Send parameters to the script that is executed on the clients. 38 | #> 39 | 40 | 41 | param( 42 | [Parameter(Mandatory=$True)] 43 | [string]$Users="ShortDomainName\SamAccount1,ShortDomainName\SamAccount2", #Comma separated string of usernames 44 | [Parameter(Mandatory=$False)] 45 | [int]$RunInUserContext=1, 46 | [Parameter(Mandatory=$True)] 47 | [string]$ScriptToDownloadAndRun="\\Server\Path$\Script.ps1", 48 | [Parameter(Mandatory=$False)] 49 | [string]$DownloadLoc="%windir%\UserScriptStore", 50 | [Parameter(Mandatory=$True)] 51 | [string]$ScriptHash 52 | 53 | 54 | ) 55 | 56 | ################FUNCTIONS 57 | 58 | Function AbortScript 59 | { 60 | Stop-Transcript 61 | break 62 | } 63 | 64 | 65 | Function VerifyHash([String]$LocalFilePath) 66 | { 67 | write-host "Verifying hash of the script to execute...." 68 | $FileHash=(Get-FileHash $LocalFilePath).Hash 69 | if ($ScriptHash -eq $FileHash) 70 | { 71 | write-host "ScriptToRunHash matches the downloaded file" 72 | return $True 73 | } 74 | 75 | Return $false 76 | 77 | } 78 | 79 | 80 | <#Function Test-ADGroupMember { 81 | 82 | Param ($User,$Group) 83 | 84 | Trap {Return "error"} 85 | $PlainUserName=$User.Split("\") 86 | $User=$PlainUserName[$PlainUserName.Count -1] 87 | write-host $User 88 | If ( 89 | 90 | Get-ADUser -Filter "memberof -RecursiveMatch '$((Get-ADGroup $Group).DistinguishedName)'" -SearchBase $((Get-ADUser $User).DistinguishedName)) {$true} 91 | 92 | Else {$false} 93 | 94 | }#> 95 | 96 | ######################### 97 | 98 | 99 | 100 | $RunAsUser = @" 101 | using System; 102 | using System.Runtime.InteropServices; 103 | using System.Diagnostics; 104 | 105 | namespace Runasuser 106 | { 107 | public static class UserWrapper 108 | { 109 | #region Win32 Constants 110 | 111 | private const int CREATE_UNICODE_ENVIRONMENT = 0x00000400; 112 | private const int CREATE_NO_WINDOW = 0x08000000; 113 | private const int CREATE_BREAKAWAY_FROM_JOB = 0x01000000; 114 | private const int CREATE_NEW_PROCESS_GROUP = 0x00000200; 115 | 116 | private const int CREATE_NEW_CONSOLE = 0x00000010; 117 | 118 | private const uint INVALID_SESSION_ID = 0xFFFFFFFF; 119 | private static readonly IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero; 120 | 121 | #endregion 122 | 123 | #region DllImports 124 | 125 | [DllImport("advapi32.dll", EntryPoint = "CreateProcessAsUser", SetLastError = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] 126 | private static extern bool CreateProcessAsUser( 127 | IntPtr hToken, 128 | String lpApplicationName, 129 | String lpCommandLine, 130 | IntPtr lpProcessAttributes, 131 | IntPtr lpThreadAttributes, 132 | bool bInheritHandle, 133 | uint dwCreationFlags, 134 | IntPtr lpEnvironment, 135 | String lpCurrentDirectory, 136 | ref STARTUPINFO lpStartupInfo, 137 | out PROCESS_INFORMATION lpProcessInformation); 138 | 139 | [DllImport("advapi32.dll", EntryPoint = "DuplicateTokenEx")] 140 | private static extern bool DuplicateTokenEx( 141 | IntPtr ExistingTokenHandle, 142 | uint dwDesiredAccess, 143 | IntPtr lpThreadAttributes, 144 | int TokenType, 145 | int ImpersonationLevel, 146 | ref IntPtr DuplicateTokenHandle); 147 | 148 | [DllImport("userenv.dll", SetLastError = true)] 149 | private static extern bool CreateEnvironmentBlock(ref IntPtr lpEnvironment, IntPtr hToken, bool bInherit); 150 | 151 | [DllImport("userenv.dll", SetLastError = true)] 152 | [return: MarshalAs(UnmanagedType.Bool)] 153 | private static extern bool DestroyEnvironmentBlock(IntPtr lpEnvironment); 154 | 155 | [DllImport("kernel32.dll", SetLastError = true)] 156 | private static extern bool CloseHandle(IntPtr hSnapshot); 157 | 158 | [DllImport("kernel32.dll")] 159 | private static extern uint WTSGetActiveConsoleSessionId(); 160 | 161 | [DllImport("Wtsapi32.dll")] 162 | private static extern uint WTSQueryUserToken(uint SessionId, ref IntPtr phToken); 163 | 164 | [DllImport("wtsapi32.dll", SetLastError = true)] 165 | private static extern int WTSEnumerateSessions( 166 | IntPtr hServer, 167 | int Reserved, 168 | int Version, 169 | ref IntPtr ppSessionInfo, 170 | ref int pCount); 171 | 172 | #endregion 173 | 174 | #region Win32 Structs 175 | 176 | private enum SW 177 | { 178 | SW_HIDE = 0, 179 | SW_SHOWNORMAL = 1, 180 | SW_NORMAL = 1, 181 | SW_SHOWMINIMIZED = 2, 182 | SW_SHOWMAXIMIZED = 3, 183 | SW_MAXIMIZE = 3, 184 | SW_SHOWNOACTIVATE = 4, 185 | SW_SHOW = 5, 186 | SW_MINIMIZE = 6, 187 | SW_SHOWMINNOACTIVE = 7, 188 | SW_SHOWNA = 8, 189 | SW_RESTORE = 9, 190 | SW_SHOWDEFAULT = 10, 191 | SW_MAX = 10 192 | } 193 | 194 | private enum WTS_CONNECTSTATE_CLASS 195 | { 196 | WTSActive, 197 | WTSConnected, 198 | WTSConnectQuery, 199 | WTSShadow, 200 | WTSDisconnected, 201 | WTSIdle, 202 | WTSListen, 203 | WTSReset, 204 | WTSDown, 205 | WTSInit 206 | } 207 | 208 | [StructLayout(LayoutKind.Sequential)] 209 | private struct PROCESS_INFORMATION 210 | { 211 | public IntPtr hProcess; 212 | public IntPtr hThread; 213 | public uint dwProcessId; 214 | public uint dwThreadId; 215 | } 216 | 217 | private enum SECURITY_IMPERSONATION_LEVEL 218 | { 219 | SecurityAnonymous = 0, 220 | SecurityIdentification = 1, 221 | SecurityImpersonation = 2, 222 | SecurityDelegation = 3, 223 | } 224 | 225 | [StructLayout(LayoutKind.Sequential)] 226 | private struct STARTUPINFO 227 | { 228 | public int cb; 229 | public String lpReserved; 230 | public String lpDesktop; 231 | public String lpTitle; 232 | public uint dwX; 233 | public uint dwY; 234 | public uint dwXSize; 235 | public uint dwYSize; 236 | public uint dwXCountChars; 237 | public uint dwYCountChars; 238 | public uint dwFillAttribute; 239 | public uint dwFlags; 240 | public short wShowWindow; 241 | public short cbReserved2; 242 | public IntPtr lpReserved2; 243 | public IntPtr hStdInput; 244 | public IntPtr hStdOutput; 245 | public IntPtr hStdError; 246 | } 247 | 248 | private enum TOKEN_TYPE 249 | { 250 | TokenPrimary = 1, 251 | TokenImpersonation = 2 252 | } 253 | 254 | [StructLayout(LayoutKind.Sequential)] 255 | private struct WTS_SESSION_INFO 256 | { 257 | public readonly UInt32 SessionID; 258 | 259 | [MarshalAs(UnmanagedType.LPStr)] 260 | public readonly String pWinStationName; 261 | 262 | public readonly WTS_CONNECTSTATE_CLASS State; 263 | } 264 | 265 | #endregion 266 | 267 | // Gets the user token from the currently active session 268 | private static bool GetSessionUserToken(ref IntPtr phUserToken) 269 | { 270 | var bResult = false; 271 | var hImpersonationToken = IntPtr.Zero; 272 | var activeSessionId = INVALID_SESSION_ID; 273 | var pSessionInfo = IntPtr.Zero; 274 | var sessionCount = 0; 275 | 276 | // Get a handle to the user access token for the current active session. 277 | if (WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, ref pSessionInfo, ref sessionCount) != 0) 278 | { 279 | var arrayElementSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO)); 280 | var current = pSessionInfo; 281 | 282 | for (var i = 0; i < sessionCount; i++) 283 | { 284 | var si = (WTS_SESSION_INFO)Marshal.PtrToStructure((IntPtr)current, typeof(WTS_SESSION_INFO)); 285 | current += arrayElementSize; 286 | 287 | if (si.State == WTS_CONNECTSTATE_CLASS.WTSActive) 288 | { 289 | activeSessionId = si.SessionID; 290 | } 291 | } 292 | } 293 | 294 | // If enumerating did not work, fall back to the old method 295 | if (activeSessionId == INVALID_SESSION_ID) 296 | { 297 | activeSessionId = WTSGetActiveConsoleSessionId(); 298 | } 299 | 300 | if (WTSQueryUserToken(activeSessionId, ref hImpersonationToken) != 0) 301 | { 302 | // Convert the impersonation token to a primary token 303 | bResult = DuplicateTokenEx(hImpersonationToken, 0, IntPtr.Zero, 304 | (int)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, (int)TOKEN_TYPE.TokenPrimary, 305 | ref phUserToken); 306 | 307 | CloseHandle(hImpersonationToken); 308 | } 309 | 310 | return bResult; 311 | } 312 | 313 | public static bool StartProcessAsCurrentUser(string appPath, string cmdLine = null, string workDir = null, bool visible = false) 314 | { 315 | var hUserToken = IntPtr.Zero; 316 | var startInfo = new STARTUPINFO(); 317 | var procInfo = new PROCESS_INFORMATION(); 318 | var pEnv = IntPtr.Zero; 319 | int iResultOfCreateProcessAsUser; 320 | 321 | startInfo.cb = Marshal.SizeOf(typeof(STARTUPINFO)); 322 | 323 | try 324 | { 325 | if (!GetSessionUserToken(ref hUserToken)) 326 | { 327 | throw new Exception("StartProcessAsCurrentUser: GetSessionUserToken failed."); 328 | } 329 | 330 | //uint dwCreationFlags = CREATE_UNICODE_ENVIRONMENT | (uint)(visible ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW); 331 | //uint dwCreationFlags = CREATE_UNICODE_ENVIRONMENT | CREATE_BREAKAWAY_FROM_JOB | CREATE_NO_WINDOW; 332 | uint dwCreationFlags = CREATE_UNICODE_ENVIRONMENT | CREATE_BREAKAWAY_FROM_JOB | CREATE_NO_WINDOW; 333 | startInfo.wShowWindow = (short)(visible ? SW.SW_SHOW : SW.SW_HIDE); 334 | startInfo.lpDesktop = "winsta0\\default"; 335 | 336 | 337 | //if (!CreateEnvironmentBlock(ref pEnv, hUserToken, false)) 338 | if (!CreateEnvironmentBlock(ref pEnv, hUserToken, true)) 339 | { 340 | throw new Exception("StartProcessAsCurrentUser: CreateEnvironmentBlock failed."); 341 | } 342 | 343 | /*CreateProcessAsUser(hUserToken, 344 | appPath, // Application Name 345 | //@"""{appPath}"" {cmdLine}", // Command Line 346 | cmdLine, // Command Line 347 | IntPtr.Zero, 348 | IntPtr.Zero, 349 | false, 350 | dwCreationFlags, 351 | pEnv, 352 | workDir, // Working directory 353 | ref startInfo, 354 | out procInfo);*/ 355 | 356 | if (!CreateProcessAsUser(hUserToken, 357 | appPath, // Application Name 358 | //@"""{appPath}"" {cmdLine}", // Command Line 359 | cmdLine, // Command Line 360 | IntPtr.Zero, 361 | IntPtr.Zero, 362 | true, 363 | dwCreationFlags, 364 | pEnv, 365 | workDir, // Working directory 366 | ref startInfo, 367 | out procInfo)) 368 | 369 | { 370 | iResultOfCreateProcessAsUser = Marshal.GetLastWin32Error(); 371 | throw new Exception("StartProcessAsCurrentUser: CreateProcessAsUser failed. Error Code -" + iResultOfCreateProcessAsUser); 372 | } 373 | 374 | iResultOfCreateProcessAsUser = Marshal.GetLastWin32Error(); 375 | } 376 | finally 377 | { 378 | 379 | CloseHandle(hUserToken); 380 | if (pEnv != IntPtr.Zero) 381 | { 382 | DestroyEnvironmentBlock(pEnv); 383 | } 384 | CloseHandle(procInfo.hThread); 385 | CloseHandle(procInfo.hProcess); 386 | } 387 | 388 | return true; 389 | } 390 | 391 | } 392 | } 393 | "@ 394 | 395 | Add-Type -ReferencedAssemblies 'System', 'System.Runtime.InteropServices' -TypeDefinition $RunAsUser -Language CSharp -ErrorAction Stop 396 | 397 | 398 | 399 | 400 | #####################MAIN 401 | 402 | Start-Transcript 403 | #This will make sure that the script won't execute on servers. 404 | $OS = Get-WmiObject -Class Win32_OperatingSystem 405 | if ($OS.ProductType -ne 1) 406 | { 407 | write-host "The wrapper will only run on Workstations as for now." 408 | AbortScript 409 | } 410 | 411 | $global:ScriptPath = Split-Path -Parent $MyInvocation.MyCommand.Definition 412 | $CurrentID=[System.Security.Principal.WindowsIdentity]::GetCurrent() 413 | write-host "Current identity is:" $CurrentID.Name 414 | $ConsoleUser=((gwmi Win32_computersystem).Username) 415 | 416 | #SCCM Scripts only support integers and strings as params,hence the conversions. 417 | $UsersArray=$Users.Split(",") 418 | write-host "ConsoleUser:" $ConsoleUser 419 | write-host "Users:" $UsersArray 420 | 421 | #Make sure that the console user is targeted. 422 | if ($ConsoleUser -in $UsersArray) 423 | { 424 | #write-host "User match ('`$user')" 425 | 426 | $Windir=([System.Environment]::ExpandEnvironmentVariables("%windir%")) 427 | $DownloadLoc=([System.Environment]::ExpandEnvironmentVariables($DownloadLoc)) 428 | 429 | if ([System.IO.Directory]::Exists($DownloadLoc) -eq $False){ 430 | Write-host "Creating $DownloadLoc" 431 | New-Item -ItemType Directory -Path $DownloadLoc | Out-Null 432 | } 433 | 434 | write-host "Downloading the actual script to run to $DownloadLoc..." 435 | $Uri=([System.Uri]$ScriptToDownloadAndRun).AbsoluteUri 436 | $FileName=([System.Uri]$ScriptToDownloadAndRun).Segments[([System.Uri]$ScriptToDownloadAndRun).Segments.Count -1] 437 | write-host $Uri 438 | $File="$DownloadLoc\$FileName" 439 | 440 | 441 | #Deletes the file is it exsist. 442 | If ([System.IO.File]::Exists($File)) 443 | { 444 | [System.IO.File]::Delete($File) 445 | } 446 | 447 | #Download the script to run. 448 | try{ 449 | $Dwn=Invoke-WebRequest -uri $Uri -OutFile $File 450 | } 451 | catch{ 452 | write-host "Error while downloading $Uri." 453 | AbortScript 454 | } 455 | write-host "Download done." 456 | Start-Sleep -Milliseconds 250 457 | #Verifies the file hash. 458 | $Verified=VerifyHash($File) 459 | 460 | If ($Verified -ne $true){ 461 | write-host "File hash-check verification error." 462 | AbortScript 463 | } 464 | 465 | #Executes the script, either as system or the console user. 466 | If ($RunInUserContext -eq 1) 467 | { 468 | 469 | Write-host "Starting the downloaded script as $ConsoleUser" 470 | $Succeeded=[Runasuser.UserWrapper]::StartProcessAsCurrentUser("C:\Windows\System32\WindowsPowerShell\v1.0\Powershell.exe"," -ExecutionPolicy Bypass -File $File") 471 | } 472 | else{ 473 | write-host "starting the downloaded script as SYSTEM" 474 | Start-Process -Wait $Windir\System32\WindowsPowerShell\v1.0\Powershell.exe -ArgumentList "-NonInteractive -NoProfile -Executionpolicy Bypass -WindowStyle Hidden", "-File $File" 475 | } 476 | } 477 | else 478 | { 479 | Write-host "Console user not found in $Users." 480 | } 481 | Stop-Transcript 482 | 483 | ############################### 484 | -------------------------------------------------------------------------------- /ScriptUserWrapperPOC/msgbox3.ps1: -------------------------------------------------------------------------------- 1 | $a=Start-Transcript 2 | Add-Type -AssemblyName Microsoft.VisualBasic 3 | $User=[System.Security.Principal.WindowsIdentity]::GetCurrent() 4 | write-host $MyInvocation.MyCommand.Definition 5 | $MsgText=$MyInvocation.MyCommand.Name + ([System.Environment]::NewLine) + "Running SCCM script as User:" + $user.Name 6 | 7 | try{ 8 | if ([System.Environment]::UserInteractive){ 9 | $result = [Microsoft.VisualBasic.Interaction]::MsgBox($MsgText,'OKOnly,SystemModal,Information', 'Running as User') 10 | $result 11 | } 12 | else{ 13 | Write-Output $MsgText 14 | } 15 | 16 | } 17 | catch 18 | { 19 | write-host "Error when trying to show the msgbox" 20 | } 21 | finally{ 22 | Stop-Transcript 23 | } 24 | ($a.Path) | Out-File C:\trans.log -------------------------------------------------------------------------------- /WindowsUpdate/Reset-UpdateStore.ps1: -------------------------------------------------------------------------------- 1 | Function Reset-UpdateStore 2 | { 3 | param( 4 | [Parameter(Mandatory=$False)] 5 | [int]$TriggerInstall=0 6 | ) 7 | 8 | Stop-service UsoSvc 9 | $status=(Get-Service UsoSvc).status 10 | #write-host "UsoSvc StartType: $((Get-Service UsoSvc).StartType)" 11 | 12 | while ($status -ne "Stopped") 13 | { 14 | write-host "waiting for stop" 15 | start-sleep -s 1 16 | $status=(Get-Service UsoSvc).status 17 | } 18 | 19 | $SystemSettingsProc=Get-Process SystemSettings -ErrorAction SilentlyContinue 20 | if ($SystemSettingsProc -ne $null) 21 | { 22 | Write-host "Found SystemSettings process, killing it" 23 | $stoppr=Stop-Process $SystemSettingsProc -Force 24 | } 25 | 26 | $etls=Get-ChildItem -Path C:\ProgramData\USO*\*.etl -Recurse 27 | $etls.FullName | % {Remove-Item $_} 28 | 29 | $xmls=Get-ChildItem -Path C:\ProgramData\USO*\*.xml -Recurse 30 | $xmls.FullName | % {Remove-Item $_} 31 | 32 | $etls=Get-ChildItem -Path C:\ProgramData\USO*\*.etl -Recurse 33 | $xmls=Get-ChildItem -Path C:\ProgramData\USO*\*.xml -Recurse 34 | 35 | #Windows 10 1904x 36 | 37 | $dbs=Get-ChildItem -Path C:\ProgramData\USO*\*.db -Recurse 38 | if ($dbs) 39 | { 40 | $dbs.FullName | % {Remove-Item $_} 41 | $dbs=Get-ChildItem -Path C:\ProgramData\USO*\*.db -Recurse 42 | } 43 | 44 | if ($etls -eq $null -and $xmls-eq $null) 45 | { 46 | Write-host "Removed old USO etl- and xml-files sucessfully" 47 | } 48 | 49 | 50 | $Wuares=restart-service wuauserv 51 | $UsoStart=start-service UsoSvc 52 | $status=(Get-Service UsoSvc).status 53 | while ($status -ne "Running") 54 | { 55 | write-host "waiting for start" 56 | start-sleep -s 1 57 | $status=(Get-Service UsoSvc).status 58 | } 59 | 60 | $Wuares=restart-service wuauserv 61 | Start-Sleep -seconds 2 62 | $Usostatus=(Get-Service UsoSvc).status 63 | 64 | Write-host "Starting scan" 65 | Start-Process -FilePath C:\Windows\system32\UsoClient.exe -ArgumentList {"startscan"} -Wait 66 | if ($TriggerInstall -eq 1) 67 | { 68 | Start-Process -FilePath C:\Windows\system32\UsoClient.exe -ArgumentList {"ScanInstallWait"} -Wait 69 | start-sleep -seconds 5 70 | Write-host "Starting install..." 71 | Start-Process -FilePath C:\Windows\system32\UsoClient.exe -ArgumentList {"startInstall"} 72 | write-host "After Install" 73 | } 74 | write-host "Done" 75 | } 76 | -------------------------------------------------------------------------------- /WindowsUpdate/Update-AndRestart.ps1: -------------------------------------------------------------------------------- 1 | <# Remove comment in order to use with configmgr's "run script" 2 | 3 | [CmdletBinding()] 4 | param( 5 | [Parameter(Mandatory=$False)] 6 | [int]$ShutCountdown=90, 7 | [Parameter(Mandatory=$False)] 8 | [int]$ForceShutdown=1 9 | ) 10 | 11 | #> 12 | 13 | 14 | Function Update-AndRestart 15 | { 16 | 17 | <# 18 | .DESCRIPTION 19 | Finalizes a pending FU (installed through WU/WUFB) and restarts the computer 20 | .PARAMETER ShutdownInSecs 21 | Seconds before the shutdown is initiated. 22 | .PARAMETER SkipShutdownOptionsCheck 23 | Bypasses the check of testing if the current shutdownoptions includes "update and reboot" or "update and shut down". 24 | .PARAMETER Force 25 | If set to true forces the shutdown even if a user is logged on. 26 | .NOTES 27 | Version: 0.3Alpha 28 | Author: Mattias Cedervall 29 | Creation Date: 2021-04-05 30 | Purpose/Change: Initial script development 31 | .EXAMPLE 32 | Update-AndRestart -ComputerName MyComputer -ShutdownInSecs 600 -SkipShutdownOptionsCheck 33 | #> 34 | 35 | [CmdletBinding()] 36 | param( 37 | [Parameter(Mandatory=$False)] 38 | [int]$ShutdownInSecs=90, 39 | [Parameter(Mandatory=$False)] 40 | [switch]$SkipShutdownOptionsCheck, 41 | [Parameter(Mandatory=$False)] 42 | [string]$ComputerName=$Env:COMPUTERNAME, 43 | [Parameter(Mandatory=$False)] 44 | [bool]$Force=$true, 45 | [Parameter(Mandatory=$False)] 46 | [bool]$VerboseOutput=$false, 47 | [Parameter(Mandatory=$False)] 48 | [System.Management.Automation.PSCredential] 49 | [System.Management.Automation.Credential()] 50 | $Credential = [System.Management.Automation.PSCredential]::Empty 51 | ) 52 | 53 | Function Get-CurrentShutdownOptions 54 | { 55 | #Anything but 0 indicates that the computer needs to restart to finish an update.(Not only feature updates) 56 | 57 | $CurrentFlyoutOptions=(Get-ItemPropertyValue -LiteralPath hklm:\SOFTWARE\Microsoft\WindowsUpdate\Orchestrator -Name ShutdownFlyoutOptions) 58 | return $CurrentFlyoutOptions 59 | } 60 | 61 | Function Get-FeatureUpdateProgress 62 | { 63 | 64 | $VolatileExist=Get-Item HKLM:\SYSTEM\Setup\MoSetup\Volatile\ -ErrorAction SilentlyContinue 65 | if ($VolatileExist -ne $null) 66 | { 67 | $SetupPhase=($VolatileExist.GetValue("SetupPhase")) 68 | $Progress=($VolatileExist.GetValue("SetupProgress")) 69 | if ($Progress -eq $null) 70 | { 71 | return -1 72 | } 73 | else 74 | { 75 | return $Progress 76 | } 77 | } 78 | } 79 | 80 | Function Get-FUUpdateResult 81 | { 82 | $SetupRes=(Get-ItemPropertyValue hklm:\SYSTEM\Setup\MoSetup\Volatile -Name "SetupHostResult" -ErrorAction SilentlyContinue) 83 | $retValue=$SetupRes 84 | 85 | if ($SetupRes -eq $null) 86 | { 87 | $retValue=(Get-ItemProperty hklm:\SYSTEM\Setup\MoSetup\Volatile -Name "BoxResult" -ErrorAction SilentlyContinue) 88 | } 89 | return $retValue 90 | } 91 | 92 | 93 | Function Initiate-Shutdown 94 | { 95 | param( 96 | 97 | [Parameter(Mandatory=$False)] 98 | [ValidateSet("Restart","Shutdown")] 99 | [String]$ShutdownOption="Restart", 100 | [Parameter(Mandatory=$False)] 101 | [Bool]$Force=$false, 102 | [Parameter(Mandatory=$False)] 103 | [int]$Countdown=30, 104 | [Parameter(Mandatory=$False)] 105 | [bool]$VerboseOutput=$false 106 | ) 107 | 108 | $signature1 = @" 109 | [DllImport("advapi32.dll", SetLastError = true)] 110 | public static extern UInt32 InitiateShutdown(string lpMachineName, string lpMessage, UInt32 dwGraceperiod, UInt32 dwShutdownFlags, UInt32 dwReason); 111 | "@ 112 | 113 | $signature2 = @" 114 | [DllImport("ntdll.dll", SetLastError = true)] 115 | public static extern IntPtr RtlAdjustPrivilege(int Privilege, bool bEnablePrivilege, bool IsThreadPrivilege, out bool PreviousValue); 116 | "@ 117 | 118 | $advapi32 = Add-Type -MemberDefinition $signature1 -name "AdvApi32" -Namespace "Win32" -PassThru 119 | $ntdll = Add-Type -MemberDefinition $signature2 -name "NtDll" -Namespace "Win32" -PassThru 120 | 121 | try{ 122 | $x = $null 123 | $ModifyTokenRetCode=$ntdll::RtlAdjustPrivilege(19,$true,$false,[ref]$x) 124 | } 125 | catch 126 | { 127 | Write-Verbose "Error adjusting token" 128 | #return 129 | } 130 | 131 | Write-Output "Remote current verbose value: $VerbosePreference" 132 | Write-Output "ShouldEnableVerboseOutput: $VerboseOutput" 133 | 134 | if ($VerboseOutput -eq $true) 135 | { 136 | $VerbosePreference='Continue' 137 | } 138 | Write-Verbose "Countdown: $Countdown" 139 | 140 | 141 | if ($Countdown -ge 60) 142 | { 143 | $TimeString="$([Math]::Truncate($Countdown/60)) minute(s)." 144 | if (($Countdown % 60) -gt 0) 145 | { 146 | $TimeString=$TimeString.Replace("minute(s).","minute(s) and $($Countdown % 60) seconds.") 147 | } 148 | 149 | } 150 | else 151 | { 152 | $TimeString="$Countdown seconds." 153 | } 154 | 155 | Enum ShutdownFlags 156 | { 157 | <# 158 | 159 | SHUTDOWN_FORCE_OTHERS 160 | 0x00000001 (0x1) 161 | All sessions are forcefully logged off. If this flag is not set and users other than the current user are logged on to the computer specified by the lpMachineName parameter, this function fails with a return value of ERROR_SHUTDOWN_USERS_LOGGED_ON. 162 | 163 | SHUTDOWN_FORCE_SELF 164 | 0x00000002 (0x2) 165 | Specifies that the originating session is logged off forcefully. If this flag is not set, the originating session is shut down interactively, so a shutdown is not guaranteed even if the function returns successfully. 166 | 167 | SHUTDOWN_GRACE_OVERRIDE 168 | 0x00000020 (0x20) 169 | Overrides the grace period so that the computer is shut down immediately. 170 | 171 | SHUTDOWN_HYBRID 172 | 0x00000200 (0x200) 173 | Beginning with InitiateShutdown running on Windows 8, you must include the SHUTDOWN_HYBRID flag with one or more of the flags in this table to specify options for the shutdown. 174 | Beginning with Windows 8, InitiateShutdown always initiate a full system shutdown if the SHUTDOWN_HYBRID flag is absent. 175 | 176 | SHUTDOWN_INSTALL_UPDATES 177 | 0x00000040 (0x40) 178 | The computer installs any updates before starting the shutdown. 179 | 180 | SHUTDOWN_NOREBOOT 181 | 0x00000010 (0x10) 182 | The computer is shut down but is not powered down or rebooted. 183 | 184 | SHUTDOWN_POWEROFF 185 | 0x00000008 (0x8) 186 | The computer is shut down and powered down. 187 | 188 | SHUTDOWN_RESTART 189 | 0x00000004 (0x4) 190 | The computer is shut down and rebooted. 191 | 192 | SHUTDOWN_RESTARTAPPS 193 | 0x00000080 (0x80) 194 | The system is rebooted using the ExitWindowsEx function with the EWX_RESTARTAPPS flag. This restarts any applications that have been registered for restart using the RegisterApplicationRestart function. 195 | 196 | 0x47=SHUTDOWN_INSTALL_UPDATES, SHUTDOWN_FORCE_OTHERS, SHUTDOWN_FORCE_SELF, SHUTDOWN_RESTART 197 | 198 | #> 199 | 200 | SHUTDOWN_FORCE_OTHERS = 0x00000001 201 | SHUTDOWN_FORCE_SELF = 0x00000002 202 | SHUTDOWN_GRACE_OVERRIDE = 0x00000020 203 | SHUTDOWN_HYBRID = 0x00000200 204 | SHUTDOWN_INSTALL_UPDATES = 0x00000040 205 | SHUTDOWN_NOREBOOT = 0x00000010 206 | SHUTDOWN_POWEROFF = 0x00000008 207 | SHUTDOWN_RESTART = 0x00000004 208 | SHUTDOWN_RESTARTAPPS = 0x00000080 209 | 210 | } 211 | 212 | #https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--1000-1299- 213 | 214 | if ($ShutdownOption -eq "Restart") 215 | { 216 | Write-Verbose "Restart" 217 | $flags=[ShutdownFlags]::SHUTDOWN_FORCE_SELF + [ShutdownFlags]::SHUTDOWN_INSTALL_UPDATES + [ShutdownFlags]::SHUTDOWN_RESTART 218 | } 219 | elseif ($ShutdownOption -eq "Shutdown") 220 | { 221 | Write-Verbose "PowerOff" 222 | $flags=[ShutdownFlags]::SHUTDOWN_FORCE_SELF + [ShutdownFlags]::SHUTDOWN_INSTALL_UPDATES + [ShutdownFlags]::SHUTDOWN_POWEROFF 223 | } 224 | 225 | if ($Force -eq $true) 226 | { 227 | Write-Verbose "Forcing shutdown" 228 | $flags=$flags + [ShutdownFlags]::SHUTDOWN_FORCE_OTHERS 229 | } 230 | 231 | Write-Verbose "Final flags: $flags" 232 | try 233 | { 234 | Write-Verbose "TimeString: $TimeString" 235 | Write-Verbose "CountDown: $Countdown" 236 | #$flags=[int]([ShutdownFlags]::SHUTDOWN_RESTART + [ShutdownFlags]::SHUTDOWN_FORCE_OTHERS + [ShutdownFlags]::SHUTDOWN_FORCE_SELF) 237 | #Write-Host "$($flags)" 238 | #Write-host "Push enter to initiate update and shutdown/restart on $(hostname)" 239 | #Read-Host 240 | 241 | $ShutDownTryRetCode=$advapi32::InitiateShutdown($null,"Installing updates and restarting in $TimeString",$Countdown,[Uint32]$flags,[Uint32]'0x80020011') 242 | if ($ShutDownTryRetCode -eq 1115) 243 | { 244 | Write-Output "Shutdown is already in progress" 245 | } 246 | else 247 | { 248 | Write-Output "ShutdownRetCode: $ShutDownTryRetCode" 249 | } 250 | 251 | } 252 | catch 253 | { 254 | Write-Output "Error restarting $ComputerName, $_" 255 | return 256 | } 257 | } 258 | 259 | 260 | Function Set-InstallAtShutdownRegValue 261 | { 262 | try 263 | { 264 | $regkey = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator",$true) 265 | $regkey.DeleteSubKey("InstallAtShutDown") 266 | $NewKey=$regkey.CreateSubKey("InstallAtShutdown") 267 | #$NewKey.SetValue('',"1") 268 | $NewKey.SetValue('',1, [Microsoft.Win32.RegistryValueKind]::DWord) 269 | $regkey.close() 270 | return 0 271 | 272 | } 273 | catch 274 | { 275 | Write-Verbose $_ 276 | return -1 277 | } 278 | } 279 | 280 | Function ConvertTo-ScriptBlockWithParams 281 | { 282 | param( 283 | [Parameter(Mandatory=$True)] 284 | [String]$FunctionName, 285 | [Parameter(Mandatory=$True)] 286 | [Hashtable]$Parameters 287 | 288 | ) 289 | 290 | try 291 | { 292 | $MyFunction=(get-item Function:$FunctionName) 293 | $params=$Parameters 294 | $ScriptBlock=[ScriptBlock]::Create(".{$($MyFunction.ScriptBlock)} $(&{$args} @params)") 295 | } 296 | 297 | catch{ 298 | Write-Output "Error getting function $FunctionName" 299 | } 300 | return $ScriptBlock 301 | 302 | } 303 | 304 | 305 | Function Check-PendingRebootFU 306 | { 307 | write-host "in Check-PendingRebootFU" 308 | try 309 | { 310 | $Shut=Get-CurrentShutdownOptions 311 | if ($Shut -ne 0) 312 | { 313 | Write-Output "Shutdownoptions: $Shut" 314 | $Prog=Get-FeatureUpdateProgress 315 | Write-Output "Progress: $Prog" 316 | if ($Prog -eq 100) 317 | { 318 | Write-Output "Update 100% done" 319 | $ret=Get-FUUpdateResult 320 | Write-Output "Last FU error: $ret" 321 | if ($ret -eq 0) 322 | { 323 | return 0 324 | } 325 | 326 | } 327 | } 328 | } 329 | catch 330 | { 331 | Write-Output "Error in Check-PendingRebootFU" 332 | return -1 333 | } 334 | return -1 335 | } 336 | 337 | ################################ MAIN ################################ 338 | 339 | if ($VerboseOutput -eq $true) 340 | { 341 | $VerbosePreference='Continue' 342 | } 343 | 344 | if ($ComputerName -ne $Env:ComputerName) 345 | { 346 | try{ 347 | Write-Verbose "Verbose current: $VerbosePreference" 348 | $ShutdownOptFunc=(get-item Function:Get-CurrentShutdownOptions) 349 | $ShutOpt=(Invoke-Command -ScriptBlock $($ShutdownOptFunc.ScriptBlock) -ComputerName $ComputerName -Credential $Credential -ErrorAction Stop) 350 | } 351 | catch 352 | { 353 | ###Either the Computer is Offline or credentials doesn't work. 354 | 355 | Write-Verbose "Error getting `$ShutOpt" 356 | throw $_ 357 | return 358 | } 359 | 360 | if ($ShutOpt -notin ($null,0)) 361 | { 362 | Write-Output "ShutdownOptions: $($ShutOpt.ToString())" 363 | 364 | } 365 | 366 | 367 | if ($ShutOpt -notin ($null,0) -or $SkipShutdownOptionsCheck -eq $true) 368 | { 369 | Write-Verbose "ShutdownOptionCheck was bypassed: $SkipShutdownOptionsCheck" 370 | $ProgressFunc= (get-item Function:Get-FeatureUpdateProgress) 371 | $UpdResFunc=(get-item Function:Get-FUUpdateResult) 372 | 373 | #$ShutOpt=Invoke-Command -ScriptBlock $($ShutdownOptFunc.ScriptBlock) -ComputerName $ComputerName 374 | $FUProgress=Invoke-Command -ScriptBlock $($ProgressFunc.ScriptBlock) -ComputerName $ComputerName -Credential $Credential 375 | $FUResult=Invoke-Command -ScriptBlock $($UpdResFunc.ScriptBlock) -ComputerName $ComputerName -Credential $Credential 376 | 377 | Write-Output "Feature Update progress: " $FUProgress 378 | Write-Output "Feature Update result: " $FUResult 379 | 380 | if ($FUProgress -eq 100 -and $FUResult -eq 0) 381 | { 382 | Write-Verbose "Progress is 100% and result is 0. Continuing" 383 | $InstRegFunc=(get-item Function:Set-InstallAtShutdownRegValue) 384 | $SetInstallRegValueResult=Invoke-Command -ScriptBlock $($InstRegFunc.ScriptBlock) -ComputerName $ComputerName -Credential $Credential 385 | Write-Output "Set InstallAtShutdownRegValue result: $SetInstallRegValueResult" 386 | 387 | } 388 | else 389 | { 390 | Write-Output "FUInstallProgress: $FUProgress percent done" 391 | Write-Output "FU not 100% done or failed to install, won't restart the computer." 392 | return 393 | } 394 | $ForceShutdownIsOne=[bool]$($Force -eq 1) 395 | $TestBoolAsString="`$$ForceShutdownIsOne" 396 | 397 | $InitShutdownParams=@{ 398 | "Countdown"=$ShutdownInSecs 399 | "VerboseOutput"='$true' 400 | "Force"=$TestBoolAsString ##Forces restart even if a user is logged on 401 | } 402 | 403 | 404 | $InitShutdownSB=(ConvertTo-ScriptBlockWithParams -FunctionName "Initiate-Shutdown" -Parameters $InitShutdownParams) 405 | Invoke-Command -ScriptBlock $InitShutdownSB -ComputerName $ComputerName -Credential $Credential 406 | 407 | } 408 | else 409 | { 410 | Write-Output "Current ShutdownOptions is 0 and `$SkipShutdownOptionsCheck was not true. Exiting...." 411 | } 412 | 413 | } 414 | else 415 | { 416 | Write-Verbose "Running local" 417 | $FUProgress=Get-FeatureUpdateProgress 418 | $ShutOpt=Get-CurrentShutdownOptions 419 | $FUResult=Get-FUUpdateResult 420 | Write-Verbose "Progress local: $FUProgress" 421 | Write-Verbose "Current shutdown options: $ShutOpt" 422 | Write-Verbose "Last update result: $FUResult" 423 | 424 | if ($ShutOpt -notin ($null,0) -or $SkipShutdownOptionsCheck -eq $true) 425 | { 426 | if ($FUProgress -eq 100 -and $FUResult -eq 0) 427 | { 428 | Write-Verbose "Progress is 100% and result is 0. Continuing" 429 | $SetInstallRegValueResult=Set-InstallAtShutdownRegValue 430 | Initiate-Shutdown -Force $ForceShutdown -Countdown $ShutCountdown -VerboseOutput $VerboseOutput 431 | } 432 | } 433 | else 434 | { 435 | Write-Output "FUInstallProgress: $FUProgress percent done" 436 | Write-Output "FU not 100% done or failed to install, won't restart the computer." 437 | return 438 | } 439 | } 440 | 441 | 442 | 443 | <# Example of other type of params 444 | 445 | $FunctionParams = @{ 446 | "Restart"='$true' 447 | "Countdown"=$ShutdownInSecs 448 | "MyTestString"='"Edited string"' #Please notice the '" "' surrounding the string when a space is present 449 | "BoolTest"='$true' 450 | } 451 | #> 452 | } 453 | 454 | <# Remove comment in order to use with configmgr's "run script" 455 | 456 | Update-AndRestart -ShutdownInSecs $ShutCountdown -Force $ForceShutdown -VerboseOutput $true 457 | 458 | #> --------------------------------------------------------------------------------