├── 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 | 
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 | #>
--------------------------------------------------------------------------------