Skip to content

Instantly share code, notes, and snippets.

@AlphaKR93
Last active July 12, 2024 10:10
Show Gist options
  • Save AlphaKR93/79d24156e5a20595221d1b58db474fcc to your computer and use it in GitHub Desktop.
Save AlphaKR93/79d24156e5a20595221d1b58db474fcc to your computer and use it in GitHub Desktop.
PSTools
$user = "GitHub ID"; $target = "Gist ID"; $privilege = $false; $direct = $false; $windowStyle = "Normal"
iwr 'https://gist.githubusercontent.com/AlphaKR93/79d24156e5a20595221d1b58db474fcc/raw/invoke.ps1' | iex
function Round {
param(
# Number to round
[Parameter(ValueFromPipeline)]
[double] $Number,
[Parameter(Mandatory = $false)]
[int] $Delimeter = 0
)
return [int] [System.Math]::Round($Number, $Delimeter)
}
function Select-NotNull {
param(
# Array to remove null values
[Parameter(Mandatory, ValueFromPipeline)] [AllowNull()]
[object[]] $Object
)
process {
$objects += @($Object)
}
end {
return ($objects | Where-Object { ($null -ne $_) })
}
}
function Select-Like {
param(
[Parameter(Mandatory, ValueFromPipeline)] [AllowNull()]
[object[]] $Object,
[Parameter(Mandatory)]
[object[]] $Filter
)
process {
$objects += @($Object)
}
end {
return ($objects | Where-Object {
$name = $_; $match = $Filter | Where-Object { $name -like "$_*" }
("$null" -ne "$match") -and ($Filter -contains "$match")
})
}
}
function Select-Last {
param(
[Parameter(Mandatory, ValueFromPipeline)] [AllowNull()]
[object[]] $Object
)
process {
$objects += @($Object)
}
end {
return [object] ($objects | Select-Object -Last 1)
}
}
function Write-Operation {
param(
# Operation in progress
[Parameter(Mandatory)]
[string] $Operation,
# What to apply the operation to
[Parameter(Mandatory)]
[string] $Target
)
Write-Information "Performing the operation `"$Operation`" on target `"$Target`""
}
function Write-Result {
param(
# Script to run and log
[Parameter(Mandatory)]
[scriptblock] $Lambda
)
$output = $Lambda.Invoke()
Write-Information ($output | Out-String)
return $output
}
function Write-Status {
param(
[Parameter(Mandatory=$true)]
[string] $Content,
[Parameter(Mandatory=$false)]
[switch] $Success
)
Clear-Host
if ($Success) {
Write-Host " $Content " -ForegroundColor Black -BackgroundColor Green
return
}
Write-Host " $Content " -ForegroundColor Black -BackgroundColor DarkYellow
}
function Write-Success {
param(
[Parameter(Mandatory=$true)]
[string] $Content
)
Write-Host "$Content" -ForegroundColor Green
}
function Write-Notify {
param(
[Parameter(Mandatory=$true)]
[string] $Content
)
Write-Host "$Content" -ForegroundColor DarkCyan
}
function Write-Linebreak {
param(
# Amount of linebreak to write
[Parameter(Mandatory)]
[int] $Amount
)
(0..$Amount) | ForEach-Object { Write-Host " " }
}
function Read-Choices {
param(
# Title of the prompt
[Parameter(Mandatory = $false)]
[string] $Title,
# Contents of the prompt
[Parameter(Mandatory = $false)] [Alias("Description")]
[string[]] $Content,
# Choices of the prompt
[Parameter(Mandatory = $false, ValueFromPipeline, ValueFromRemainingArguments)]
[string[]] $Choice = ('&Yes', '&No'),
# Default value index of the prompt
[Parameter(Mandatory = $false)]
[int] $Default
)
return $Host.UI.PromptForChoice($Title, $Content, $Choice, $Default)
}
function Read-Prompts {
param(
# Content of the prompt
[Parameter(Mandatory)] [Alias("Prompt")]
[string] $Content,
# Default value of the prompt
[Parameter(ValueFromPipeline)]
[string] $DefaultValue
)
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.SendKeys]::SendWait($DefaultValue)
return Read-Host -Prompt $Content
}
function Test-Paths {
param(
# Paths to test
[Parameter(Mandatory)]
[string[]] $Path,
# Whether to always return a true if it is included
[Parameter(Mandatory = $false)] [Alias("Or")]
[switch] $IncludesValid
)
if ($IncludesValid) {
return ($true -in (Test-Path -Path $Path))
}
return ($false -notin (Test-Path -Path $Path))
}
# by FatalMerlin. https://github.com/FatalMerlin/PowerShell/blob/master/Remove-ItemWithProgress.psm1
function Remove-ItemWithProgress {
param(
# File or folder to delete
[Parameter(Mandatory)]
[string[]] $Path,
# Access rule to add before removal
[Parameter(Mandatory = $false)]
[System.Security.AccessControl.FileSystemAccessRule] $AccessRule,
# Depth of unit to divide the chunk of the file to be deleted
[Parameter(Mandatory = $false)] [Alias("Depth")]
[int] $ChunkDepth = -1
)
try { [string[]] $paths = ($Path | ForEach-Object {
if (Test-Path -Path $_) { Resolve-Path -Path $_ } else { $null }
}).Path | Select-NotNull }
catch { throw 'Invalid Path.' }
$jid = Lock-Random
$timeStart = Get-Date; $activity = "Deleting $Path"; $counter = 0
Write-Progress -Id $jid -Activity $activity -Status "Reading files..." -PercentComplete 0
if (0 -le $ChunkDepth) {
$paths = ([string[]] ($paths | ForEach-Object { (Get-ChildItem -Path $_ -Recurse -Directory -Depth $ChunkDepth -Force -ErrorAction SilentlyContinue).FullName })) + $paths
$size = $paths.Count + 1
Write-Information "Deleting $paths with size $size"
forEach ($ipath in $paths) {
$elapsed = ((Get-Date) - $timeStart).TotalSeconds
$completed = (++$counter) / $size; $percent = $completed * 100 | Round
$current = $ipath.Replace($Path, ".")
Write-Information $current
Write-Progress `
-Id $jid `
-Activity $activity `
-Status "Deleting Files... ($percent% Complete)" `
-CurrentOperation $current `
-PercentComplete $percent `
-SecondsRemaining (($elapsed / $completed) - $elapsed)
if ($null -ne $AccessRule) { Add-AccessRule -Path "$ipath" -AccessRule $AccessRule -Recurse -Silent }
Remove-Item -Path $ipath -Recurse -Force
}
} else {
$size = ($paths | ForEach-Object { (Get-ChildItem -Path $_ -Recurse -Force -ErrorAction SilentlyContinue).FullName }).Count + 1
Write-Information "Deleting $paths with size $size"
forEach ($path in $paths) {
if ($null -ne $AccessRule) { Add-AccessRule -Path "$path" -AccessRule $AccessRule -Recurse -Silent }
Remove-Item -Path $path -Recurse -Force -Verbose 4>&1 | ForEach-Object {
Write-Information $_
$elapsed = ((Get-Date) - $timeStart).TotalSeconds
$completed = (++$counter) / $size; $percent = $completed * 100 | Round
$current = [regex]::Match($_, '"([^"]+)"\.').Captures.Groups[1].Value.Replace($path, ".")
Write-Progress `
-Id $jid `
-Activity $activity `
-Status "Deleting Files... ($percent% Complete)" `
-CurrentOperation $current `
-PercentComplete $percent `
-SecondsRemaining (($elapsed / $completed) - $elapsed)
}
}
}
Write-Progress -Id $jid -Activity $Activity -PercentComplete 100 -Completed
Write-Output "Deleted $counter items."
Unlock-Random $jid
}
function Copy-ItemWithProgress {
param(
# File or folder to copy
[Parameter(Mandatory)]
[string[]] $Path,
# Destination to which files or folders are copied
[Parameter(Mandatory)]
[string] $Destination,
# Files to exclude from Copying
[Parameter(Mandatory = $false)]
[string[]] $Exclude,
# Depth of unit to divide the chunk of the file to be copied
[Parameter(Mandatory = $false)] [Alias("Depth")]
[int] $ChunkDepth = -1
)
try { [string] $_dest = (Resolve-Path $Destination).Path } catch { throw 'Invalid Destination.' }
try { [string[]] $paths = ($Path | ForEach-Object {
if (Test-Path -Path $_) { Resolve-Path -Path $_ } else { $null }
}).Path | Select-NotNull }
catch { throw 'Invalid Path.' }
$jid = Lock-Random
$timeStart = Get-Date; $activity = "Copying $Path to $_dest"; $counter = 0
Write-Progress -Id $jid -Activity $activity -Status "Reading files..." -PercentComplete 0
if (0 -le $ChunkDepth) {
$paths = ($paths | ForEach-Object { (Get-ChildItem -Path $_ -Recurse -Directory -Depth $ChunkDepth -Force).FullName } | Select-NotNull) + $paths
$size = $paths.Count + 1
forEach ($path in $paths) {
$elapsed = ((Get-Date) - $timeStart).TotalSeconds
$completed = (++$counter) / $size; $percent = $completed * 100 | Round
$current = "$path"
Write-Information "Copying $path to $_dest with size $size"
Write-Progress `
-Id $jid `
-Activity $activity `
-Status "Copying Files... ($percent% Complete)" `
-CurrentOperation $current `
-PercentComplete ($completed * 100) `
-SecondsRemaining (($elapsed / $completed) - $elapsed)
Copy-Item -Path $path -Destination $_dest -Recurse -Force -Exclude $Exclude
}
} else {
$size = ($paths | ForEach-Object { (Get-ChildItem -Path $_ -Recurse -Force).FullName }).Count + 1
Write-Information "Copying $paths to $_dest with size $size"
forEach ($path in $paths) {
Copy-Item -Path $path -Destination $_dest -Recurse -Force -Verbose -Exclude $Exclude 4>&1 | ForEach-Object {
Write-Information $_
if (' "Copy File" ' -eq ([regex]::Match( $_, ' "([a-zA-Z ]+)" ' ).Captures.Groups[0].Value)) {
$elapsed = ((Get-Date) - $timeStart).TotalSeconds
$completed = (++$counter) / $size; $percent = $completed * 100 | Round
$current = [regex]::Match($_, '"([^"]+)"\.').Captures.Groups[1].Value.Replace($_Dest, ".")
$current = [regex]::Match($current, '(\.\\[^/:*?"<>|]+)').Captures.Groups[1].Value
Write-Progress `
-Id $jid `
-Activity $activity `
-Status "Copying Files... ($percent% Complete)" `
-CurrentOperation $current `
-PercentComplete $percent `
-SecondsRemaining (($elapsed / $completed) - $elapsed)
}
}
}
}
Write-Progress -Id $jid -Activity $activity -PercentComplete 100 -Completed
Write-Output "Copied $counter items."
Unlock-Random $jid
}
function Add-AccessRule {
param(
# File or folder to add an access rule to
[Parameter(Mandatory)]
[string] $Path,
# Access rule to add
[Parameter(Mandatory)]
[System.Security.AccessControl.FileSystemAccessRule] $AccessRule,
# Whether access rules are added recursively (to subfiles and folders)
[Parameter(Mandatory = $false)]
[switch] $Recurse,
# Whether to hide progress bar
[Parameter(Mandatory = $false)]
[switch] $Silent
)
try { [string] $_Path = (Resolve-Path $Path).Path } catch { throw "Invalid Path" }
$sar = New-Object System.Security.AccessControl.FileSystemAccessRule($AccessRule.IdentityReference, $AccessRule.FileSystemRights, "None", $AccessRule.PropagationFlags, $AccessRule.AccessControlType)
if (((Test-Path -Path "$_Path" -PathType Leaf) -eq $true) -or !$Recurse)
{
$acl = Get-Acl -Path $_Path
$acl.AddAccessRule($sar)
Set-Acl -Path $_Path -AclObject $acl
Write-Output "Applied ACL Object to $_Path"
return
}
if ($Silent)
{
$adder = {
Write-Information "$_"
$acl = Get-Acl -Path $_
$acl.AddAccessRule($targetAR)
Set-Acl -Path $_ -AclObject $acl
Write-Information "Applied ACL Object to $_"
}
$targetAR = $AccessRule; (([string[]] (Get-ChildItem -Path $_Path -Recurse -Directory -Force).FullName) + $_Path) | ForEach-Object $adder
$files = (Get-ChildItem -Path $_Path -Recurse -File -Force).FullName
if (0 -lt $files.Length) { $targetAR = $sar; $files | ForEach-Object $adder }
return
}
$jid = Lock-Random
$activity = "Adding access rule to $_Path and subfolders..."
Write-Progress -Id $jid -Activity $activity -Status "Reading files..." -PercentComplete 0
$dirs = ([string[]] (Get-ChildItem -Path $_Path -Recurse -Directory -Force).FullName) + $_Path
$files = (Get-ChildItem $_Path -Recurse -File -Force).FullName
$size = ($files.Length + $dirs.Length + 1)
$timeStart = Get-Date
$adder = {
$acl = Get-Acl -Path $_
$acl.AddAccessRule($targetAR)
Set-Acl -Path $_ -AclObject $acl
$completed = (++$counter) / $size
$percent = [math]::Round($completed * 100)
$elapsed = ((Get-Date) - $timeStart).TotalSeconds
Write-Progress `
-Id $jid `
-Activity $activity `
-Status "Adding access rule to subfolders... ($percent% Complete)" `
-CurrentOperation $_ `
-PercentComplete $percent `
-SecondsRemaining (($elapsed / $completed) - $elapsed)
Write-Information "Applied ACL Object to $_"
}
$targetAR = $AccessRule; $dirs | ForEach-Object $adder
if (0 -lt $files.Length) { $targetAR = $sar; $files | ForEach-Object $adder }
Write-Output "Applied ACL Object to $_Path and childs"
Write-Progress -Id $jid -Activity $activity -Status "Done." -Completed
Unlock-Random $jid
}
# this function allows PowerShell to take ownership of the Scheduled Tasks registry key from TrustedInstaller. Based on Jose Espitia's script.
$adjPriv = Add-Type -PassThru -TypeDefinition @'
using System;
using System.Runtime.InteropServices;
public class AdjPriv
{
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);
[DllImport("advapi32.dll", SetLastError = true)]
internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct TokPriv1Luid
{
public int Count;
public long Luid;
public int Attr;
}
internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
internal const int SE_PRIVILEGE_DISABLED = 0x00000000;
internal const int TOKEN_QUERY = 0x00000008;
internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
public static bool EnablePrivilege(long processHandle, string privilege, bool disable)
{
bool retVal;
TokPriv1Luid tp;
IntPtr hproc = new IntPtr(processHandle);
IntPtr htok = IntPtr.Zero;
retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
tp.Count = 1;
tp.Luid = 0;
if(disable)
{
tp.Attr = SE_PRIVILEGE_DISABLED;
}
else
{
tp.Attr = SE_PRIVILEGE_ENABLED;
}
retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
return retVal;
}
}
'@
function Set-Privilege {
param(
[ValidateSet("SeAssignPrimaryTokenPrivilege", "SeAuditPrivilege", "SeBackupPrivilege", "SeChangeNotifyPrivilege", "SeCreateGlobalPrivilege", "SeCreatePagefilePrivilege", "SeCreatePermanentPrivilege", "SeCreateSymbolicLinkPrivilege", "SeCreateTokenPrivilege", "SeDebugPrivilege", "SeEnableDelegationPrivilege", "SeImpersonatePrivilege", "SeIncreaseBasePriorityPrivilege", "SeIncreaseQuotaPrivilege", "SeIncreaseWorkingSetPrivilege", "SeLoadDriverPrivilege", "SeLockMemoryPrivilege", "SeMachineAccountPrivilege", "SeManageVolumePrivilege", "SeProfileSingleProcessPrivilege", "SeRelabelPrivilege", "SeRemoteShutdownPrivilege", "SeRestorePrivilege", "SeSecurityPrivilege", "SeShutdownPrivilege", "SeSyncAgentPrivilege", "SeSystemEnvironmentPrivilege", "SeSystemProfilePrivilege", "SeSystemtimePrivilege", "SeTakeOwnershipPrivilege", "SeTcbPrivilege", "SeTimeZonePrivilege", "SeTrustedCredManAccessPrivilege", "SeUndockPrivilege", "SeUnsolicitedInputPrivilege")]
$Privilege,
[int] $ProcessId = $pid,
[Switch] $Disable
)
$processHandle = (Get-Process -id $ProcessId).Handle
$adjPriv[0]::EnablePrivilege($processHandle, $Privilege, $Disable)
}
$locked = New-Object System.Collections.ArrayList
function Lock-Random {
$value = Get-Random
if ($value -in $locked) { return Lock-Random }
$script:locked.Add($value) > $null
return $value
}
function Unlock-Random {
param(
# Job ID to unlock
[Parameter(Mandatory)]
[int] $JobID
)
if ($JobID -notin $locked) { throw "Unable to find locked job id: $JobID" }
$script:locked.Remove($value)
}
function Invoke-Safely {
param(
# Name of the script
[Parameter(Mandatory)]
[string] $Title,
# Script to run safely
[Parameter(Mandatory)]
[scriptblock] $Lambda,
# Condition for performing the section
[Parameter(Mandatory = $false)]
[scriptblock] $When,
# Index of the script
[Parameter(Mandatory = $false)]
[int] $Id = 0
)
if (($null -ne $When) -and ($false -eq $When.Invoke())) { return; }
try {
(0..8) | ForEach-Object { Write-Information " " }
$idx = if (0 -lt $Id) { "{0:D2}. " -f $Id } else { "####" }
Write-Information "$idx################################################"
Write-Information $Title
Write-Information "####################################################"
Clear-Host
if ((0 -lt $StartDebugAt) -and (0 -lt $Id) -and ($Id -lt $StartDebugAt)) {
Write-Information "This script was not executed because the starting point is later than this script."
return
}
if ((0 -lt $StopDebugAt) -and (0 -lt $Id) -and ($Id -ge $StopDebugAt)) {
Write-Warning "You have been ordered to suspend from this section."
Stop-Transcript
exit 0
}
$Lambda.Invoke()
if (!$y) { Start-Sleep -Seconds 2 }
} catch {
(0..8) | ForEach-Object { Write-Information " " }
Write-Information "!!!!An error occurred while performing the script!!!!"
Write-Information " "
Write-Information "$($_.Categorinfo.Category) due to $($_.Categorinfo.Reason)"
Write-Information " "
Write-Information $_.Exception
Write-Information $_.ScriptStackTrace
Write-Information $_.InvocationInfo.PositionMessage
Write-Host " "
Write-Host "An error occurred while performing the script" -ForegroundColor Red
Write-Host "The script could not continue. The operation has been cancelled." -ForegroundColor Red
Write-Host " "
Write-Host "All work processes were recorded in micro11.log"
Write-Host "You can contribute to troubleshooting by sending the file to the developer."
Write-Host " "
Read-Host "Press enter to continue"
$locked | ForEach-Object { Write-Progress "Failed" -Id $_ -Completed }
Clear-Host
Write-Host "Performing cleanup..."
[gc]::collect()
Start-Sleep -Seconds 2
if ((Get-WindowsImage -Mounted | Where-Object { ("$ScratchPath" -eq $_.Path) -or ("$wimPath" -eq $_.ImagePath) }).Length -gt 0)
{
@('DRV', 'SCM', 'COM', 'DEF', 'USR', 'SFT', 'SYS') |
Where-Object { Test-Path -Path "HKLM:\MICRO11_$_" } |
ForEach-Object { Write-Result { & 'reg' 'unload' "HKLM\MICRO11_$_" } > $null }
Dismount-WindowsImage -Path "$ScratchPath" -Discard > $null
}
Remove-ItemWithProgress -Path "$source", "$ScratchPath" > $null
Stop-Transcript
exit 1
}
}
function Invoke-Immediately {
param(
# Executable to run
[Parameter(Mandatory = $false)]
[string] $Executable,
# Arguments to send to the process
[Parameter(ValueFromRemainingArguments)]
[string[]] $Arguments
)
Write-Result {
Start-Process -FilePath $Executable `
-Wait `
-PassThru `
-NoNewWindow `
-ArgumentList $Arguments
}
}
$Booleans = @($true, $false, $null)
$WinStyle = @('Normal', 'Hidden', 'Maximized', 'Minimized')
$purgeVars = { Remove-Variable -Name "$_" -Force -ErrorAction 'SilentlyContinue' }
if ($target.Length -ne 32 ) { throw 'Invalid Gist ID' }
if ($privilege -notin $Booleans) { throw "Invalid value: expected booleans, but got $privilege" }
if ($direct -notin $Booleans) { throw "Invalid value: expected booleans, but got $direct" }
if ($privilege -and $direct ) { throw '"$privilege" and "$direct" cannot be set together' }
if ($windowStyle -notin $WinStyle) { throw 'Invalid Window Style' }
@('Booleans', 'WinStyle') | ForEach-Object $purgeVars
#####################################################################################################
$pf = 'https://gist.githubusercontent.com/'; $sf = 'raw/script.ps1?cachebust=&'
$PSTool = '79d24156e5a20595221d1b58db474fcc'
$script = "clear; iwr '$pf/AlphaKR93/$PSTool/$sf' | iex; clear; iwr '$pf/$user/$target/$sf' | iex"
$Arguments = @{
FilePath = 'PowerShell.exe'
WindowStyle = "$windowStyle"
WorkingDirectory = "$pwd"
ArgumentList = "-NoProfile -Command & { `$sandbox = `$true; $script; `$sandbox = `$false }"
}
if ($privilege) { $Arguments.Verb = 'runAs' }
elseif ($direct ) { $Arguments.NoNewWindow = $true }
Start-Process @Arguments
@('target', 'privilege', 'direct', 'windowStyle', 'user') | ForEach-Object $purgeVars
@('pf', 'sf', 'PSTool', 'Arguments', 'purgeVars') | ForEach-Object $purgeVars
if (("$null" -ne "$($MyInvocation.InvocationName)") -or ($true -eq $sandbox))
{
Write-Host "Loading dependent script, please wait." -ForegroundColor black -BackgroundColor DarkYellow
$GIST_URI = 'https://gist.githubusercontent.com/AlphaKR93/79d24156e5a20595221d1b58db474fcc'
$SCRIPTS_COUNT = 0
@(
'Calculate'
'Select'
'Logger'
'Prompt'
'I-O'
'Security'
'Invoke'
) | ForEach-Object {
$formattedIndex = '{0:d4}' -f (++$SCRIPTS_COUNT)
$req = Invoke-WebRequest "$GIST_URI/raw/$formattedIndex-$_.ps1?cachebust=&"
$req | Invoke-Expression
}
Remove-Variable -Name GIST_URI -Force
Remove-Variable -Name SCRIPTS_COUNT -Force
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment