Last active
November 12, 2020 18:52
-
-
Save bjarkirafn/0ca3609155e6fccc789790f6cf0a7a0b to your computer and use it in GitHub Desktop.
posh:snippets
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Convert-AsciiToBinary { | |
[CmdletBinding()] | |
[Alias('ascii2bin')] | |
param ([Parameter(Mandatory)][string]$String) | |
return [byte[]][char[]]$String | | |
ForEach-Object { [convert]::ToString($_, 2).PadLeft(8, '0') | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# @https://powershell.one/powershell-internals/attributes/custom-attributes | |
#requires -Version 5.0 | |
#region Attribute Type | |
# custom attributes derive from the type "Attribute": | |
class PesterTestAttribute : Attribute { | |
# field to store constructor argument: | |
[string]$TestName = '' | |
# field becomes an optional named argument later: | |
[int]$Level = 0 | |
# field becomes an optional named argument later: | |
[bool]$IsParam = $false | |
# constructor with one argument, | |
# this argument becomes a mandatory positional argument later: | |
PesterTestAttribute([string]$TestName) { | |
$this.TestName = $TestName | |
} | |
# constructor with NO argument, | |
# turns the positional mandatory argument into a positional optional argument later: | |
PesterTestAttribute() {} | |
} | |
function Test-This { | |
param | |
( | |
[PesterTest('Variable', Level = 6, IsParam)] | |
[string] | |
$Name | |
) | |
$result = $PSBoundParameters | |
Write-Output $result | |
} | |
function Test-Attribute { | |
[PesterTest('ReturnValue')] | |
[PesterTest('Log', Level = 1)] | |
param | |
( | |
[PesterTest('Name', IsParam)] | |
[string] | |
$Name | |
) | |
[PesterTest()]$init = 100 | |
} | |
$scriptblock = { | |
[PesterTest('ReturnValue')] | |
[PesterTest('Log')] | |
param() | |
'Hello!' | |
} | |
$scriptblock.Attributes | |
#endregion Attribute Type | |
#region Variable Attributes | |
# apply attribute to variable: | |
[PesterTest(Level = 5)]$test = 12 | |
# read attribute: | |
(Get-Variable -Name test).Attributes | |
#endregion Variable attributes | |
#region Tag attributes | |
# define very simple attribute: | |
class DocumentAttribute : Attribute {} | |
# use attribute to tag important variables that you want to | |
# include into your documentation: | |
[Document()]$important = 12 | |
$notimportant = "I am hidden" | |
[Document()]$addThis = "I am not!" | |
# dump only tagged variables: | |
Get-Variable | | |
Where-Object { $_.Attributes.Where{ $_.TypeId.Name -eq 'DocumentAttribute' } } | |
#endregion Tag attributes | |
#region IArgument Completers | |
class CustomerAttribute : System.Management.Automation.ArgumentCompleterAttribute { | |
# constructor calls base constructor and submits the completion code: | |
CustomerAttribute() : base( { | |
# receive information about current state: | |
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) | |
# list all customers... | |
'Microsoft', 'Amazon', 'Google' | | |
Sort-Object -Property LogName | | |
# filter results by word to complete | |
Where-Object { $_.LogName -like "$wordToComplete*" } | | |
Foreach-Object { | |
[Management.Automation.CompletionResult]::new($_, $_, "ParameterValue", $_) | |
} | |
}) { | |
# constructor has no own code | |
} | |
} | |
function Get-CustomerInfo { | |
param | |
( | |
# suggest customer names: | |
[Customer()] | |
[string] | |
$Customer | |
) | |
"Hello $Customer!" | |
} | |
#endregion IArgument Completers | |
#region ArgumentCompleter Factory | |
# define the attribute: | |
class CompleteAttribute : System.Management.Automation.ArgumentCompleterAttribute { | |
# add an optional parameter | |
[string]$Icon = 'ParameterValue' | |
# constructor calls base constructor and submits the completion code: | |
# added a mandatory positional argument $Values with the autocompletion values | |
# this argument is passed to a static method that creates the scriptblock that the base constructor wants | |
# also pass reference to object instance ($this) to be able to access optional parameters like $Icon later: | |
CompleteAttribute([string[]] $Items) : base([CompleteAttribute]::_createScriptBlock($Items, $this)) { | |
# constructor has no own code | |
} | |
# create a static helper method that creates the scriptblock that the base constructor needs | |
# this is necessary to be able to access the argument(s) submitted to the constructor | |
# the method needs a reference to the object instance to (later) access its optional parameters: | |
hidden static [ScriptBlock] _createScriptBlock([string[]] $Items, [CompleteAttribute] $instance) { | |
$scriptblock = { | |
# receive information about current state: | |
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) | |
# list all submitted values... | |
$Items | | |
Sort-Object -Property LogName | | |
# filter results by word to complete | |
Where-Object { $_.LogName -like "$wordToComplete*" } | | |
Foreach-Object { | |
[System.Management.Automation.CompletionResult]::new($_, $_, $instance.Icon, $_) | |
} | |
}.GetNewClosure() | |
return $scriptblock | |
} | |
} | |
# example: | |
function Get-CustomerInfoNew { | |
param | |
( | |
# suggest customer names: | |
[Complete(('Karl', 'Jenny', 'Zumsel'), Icon = 'History')] | |
[string] | |
$Customer | |
) | |
"Hello $Customer!" | |
} | |
#endregion ArgumentCompleter Factory | |
#region Self learning validation attribute | |
class AutoLearnAttribute : System.Management.Automation.ValidateArgumentsAttribute { | |
# define path to store hint lists | |
[string]$Path = "$env:temp\hints" | |
# define id to manage multiple hint lists: | |
[string]$Id = 'default' | |
# define parameterless constructor: | |
AutoLearnAttribute() : base() {} | |
# define constructor with parameter for id: | |
AutoLearnAttribute([string]$Id) : base() { | |
$this.Id = $Id | |
} | |
# Validate() is called whenever there is a variable or parameter assignment | |
[void]Validate([object]$value, [Management.Automation.EngineIntrinsics]$engineIntrinsics) { | |
# make sure the folder with hints exists | |
$exists = Test-Path -Path $this.Path | |
if (!$exists) { $null = New-Item -Path $this.Path -ItemType Directory } | |
# create filename for hint list | |
$filename = '{0}.hint' -f $this.Id | |
$hintPath = Join-Path -Path $this.Path -ChildPath $filename | |
# use a hashtable to keep hint list | |
$hints = @{} | |
# read hint list if it exists | |
$exists = Test-Path -Path $hintPath | |
if ($exists) { | |
Get-Content -Path $hintPath -Encoding Default | | |
# remove leading and trailing blanks | |
ForEach-Object { $_.Trim() } | | |
# remove empty lines | |
Where-Object { ![string]::IsNullOrEmpty($_) } | | |
# add to hashtable | |
ForEach-Object { | |
# value is not used, set it to $true: | |
$hints[$_] = $true | |
} | |
} | |
# add new value to hint list | |
if (![string]::IsNullOrWhiteSpace($value)) { | |
$hints[$value] = $true | |
} | |
# save hints list | |
$hints.Keys | | |
Sort-Object | | |
Set-Content -Path $hintPath -Encoding Default | |
# skip any validation (we only care about logging) | |
} | |
} | |
# apply new attribute to a variable: | |
[AutoLearn()]$test = "Hello" | |
# variable is now self-learning and logs all assignments: | |
$test = 123 | |
$test = "check this out" | |
# read logged values: | |
Get-Content -Path $env:temp\hints\default.hint | |
function Connect-MyServer { | |
param | |
( | |
[string] | |
[Parameter(Mandatory)] | |
# auto-learn computer names to servers.hint | |
[AutoLearn('servers')] | |
$ComputerName | |
) | |
"connecting you to $ComputerName" | |
} | |
Get-Content -Path $env:temp\hints\servers.hint | |
function Connect-MyServerNew { | |
param | |
( | |
[string] | |
[Parameter(Mandatory)] | |
# auto-learn computer names to servers.hint | |
# in folder c:\myhints: | |
[AutoLearn('servers', Path = 'c:\tmp\myhints')] | |
$ComputerName | |
) | |
"connecting you to $ComputerName" | |
} | |
Get-Content -Path c:\tmp\myhints\servers.hint | |
#endregion Self learning validation attribute | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Profile addition to redefine cd as a proxy for push location (and cd- for Pop). | |
# cd ... is transformed into into cd ..\.. (extra dot is an extra level), | |
# cd ^ is transformed into cd <<script i.e. profile>> directory | |
# cd \*doc is transformed into cd \*\Doc*\ | |
# cd = is transformed into an item from the stack. = is the first each extra = goes one deeper in the stack | |
# cd - will not tab expand but will pop an item from the location stack. 3 or more - will do an extra pop. | |
# -- means "all the rest are a strings", so two levels needs -- -- | |
# cd\ & cd.. (without space) do push instead of set and cd~ (no space) has been added | |
# cd HK[tab] will expand to HKCU: and HKLM: and similarly for other drives. | |
Remove-Item -Path Alias:\cd -ErrorAction SilentlyContinue | |
class PathTransformAttribute : Management.Automation.ArgumentTransformationAttribute { | |
[object] Transform([Management.Automation.EngineIntrinsics]$EngineIntrinsics, [object] $InputData) { | |
switch -regex ($InputData) { | |
"^=+" { return ($inputData -replace "^=+", (Get-Location -Stack).ToArray()[$Matches[0].Length - 1].Path); break } | |
"^\^" { return ($inputData -replace "^\^", $PSScriptRoot) ; break } | |
"^\\\*|/\*" { return ($pwd.path -replace "^(.*$($InputData.substring(2)).*?)[/\\].*$", '$1') ; break } | |
"^\.{3}" { return ($InputData -replace "(?<=^\.[.\\]*)(?=\.{2,}(\\|$))", ".\") ; break } | |
} | |
return ($InputData) | |
} | |
} | |
class ValidatePathAttribute : Management.Automation.ValidateArgumentsAttribute { | |
[string]$Exemption = "" #"^-+$" | |
[switch]$ContainersOnly | |
[int]$MaxItems = -1 | |
[void] Validate([object] $arguments , [Management.Automation.EngineIntrinsics]$EngineIntrinsics) { | |
if ($this.Exemption -and $arguments -match $this.Exemption) { return } #Exempt some things eg "-"" or "----"" | |
elseif ($arguments -match "^(\w+):\\?" -and (Get-PSDrive $Matches[1] -ErrorAction SilentlyContinue) ) { return } #Allow drives | |
else { | |
if ($this.ContainersOnly) { $count = (Get-Item -Path $arguments -ErrorAction SilentlyContinue).where( { $_.psIscontainer }).count } | |
else { $count = (Get-Item -Path $arguments -ErrorAction SilentlyContinue).count } | |
if ($count -eq 0 -and $this.maxitems -ge 0) { | |
throw [Management.Automation.ValidationMetadataException]::new("'$arguments' does not exist.") | |
} | |
elseif ($this.Maxitems -ge 0 -and $count -gt $this.maxitems) { | |
throw [Management.Automation.ValidationMetadataException]::new("'$arguments' resolved to multiple $count items. Maximum allowed is $($this.Maxitems)") | |
} | |
} | |
return | |
} | |
} | |
class PathCompleter : Management.Automation.IArgumentCompleter { | |
[Collections.Generic.IEnumerable[Management.Automation.CompletionResult]] CompleteArgument( | |
[string]$CommandName, | |
[string]$ParameterName, | |
[string]$WordToComplete, | |
[Management.Automation.Language.CommandAst]$CommandAst, | |
[Collections.IDictionary] $FakeBoundParameters | |
) { | |
$results = [Collections.Generic.List[Management.Automation.CompletionResult]]::new() | |
$dots = [regex]"^\.\.(\.*)(\\|$|/)" #find two dots, any more dots (captured), followed by / \ or end of string | |
$sep = [io.path]::DirectorySeparatorChar | |
$wtc = "" | |
switch -regex ($wordToComplete) { | |
#.. alone doesn't expand, expand .. followed by n dots (and possibly \ or /) to ..\ n+1 times | |
$dots { | |
$newPath = "..$Sep" * (1 + $dots.Matches($wordToComplete)[0].Groups[1].Length) | |
$wtc = $dots.Replace($wordtocomplete, $newPath) ; break | |
} | |
"^\^$" { $wtc = $PSScriptRoot ; break } # ^ [tab] ==> PS profile dir | |
"^\.$" { $wtc = "" ; break } # . and ~ alone don't expand. | |
"^~$" { $wtc = $env:USERPROFILE ; break } | |
#for 1 = sign tab through the location stack. | |
"^=$" { | |
foreach ($stackPath in (Get-Location -Stack).ToArray().Path) { | |
if ($stackpath -match "[ ']") { $stackpath = '"' + $stackPath + '"' } | |
$results.Add([Management.Automation.CompletionResult]::new($stackPath)) | |
} | |
return $results ; continue | |
} | |
#replace string of = signs with the item that many up the location stack | |
"^=+$" { $wtc = (Get-Location -Stack).ToArray()[$wordToComplete.Length - 1].Path ; continue } | |
#if path is c:\here\there\everywhere\stuff convert "\*the" to "c:\here\there" | |
"^\\\*|/\*" { $wtc = $pwd.path -replace "^(.*$($WordToComplete.substring(2)).*?)[/\\].*$", '$1' ; continue } | |
default { $wtc = $wordToComplete } | |
} | |
foreach ($result in [Management.Automation.CompletionCompleters]::CompleteFilename($wtc) ) { | |
if ($result.resultType -eq "ProviderContainer" -or $CommandName -notin @("cd", "dir")) { $results.Add($result) } | |
} | |
foreach ($result in $Global:ExecutionContext.SessionState.Drive.GetAll().name -like "$wordTocomplete*") { | |
$results.Add([Management.Automation.CompletionResult]::new("$result`:")) | |
} | |
return $results | |
} | |
} | |
function cd { | |
<# | |
.ForwardHelpTargetName Microsoft.PowerShell.Management\Push-Location | |
.ForwardHelpCategory Cmdlet | |
#> | |
[CmdletBinding(DefaultParameterSetName = 'Path')] | |
param( | |
[Parameter(ParameterSetName = 'Path', Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] | |
[PathTransform()] | |
[ArgumentCompleter([PathCompleter])] | |
[ValidatePath(Exemption = "^-+$", ContainersOnly = $true, MaxItems = 1)] | |
[string]$Path, | |
[Parameter(ParameterSetName = 'LiteralPath', ValueFromPipelineByPropertyName = $true)] | |
[Alias('PSPath', 'LP')] | |
[string]$LiteralPath, | |
[switch]$PassThru, | |
[Parameter(ValueFromPipelineByPropertyName = $true)] | |
[string]$StackName | |
) | |
process { | |
if ($Path -match "^-+$") { foreach ($i in (1..$Path.Length)) { Pop-Location } } | |
elseif ($Path -or $LiteralPath) { Push-Location @PSBoundParameters } | |
} | |
} | |
Set-Alias -Name "cd-" -Value Pop-Location | |
Function cd.. { Push-Location -Path .. } | |
Function cd\ { Push-Location -Path \ } | |
Function cd~ { Push-Location -Path ~ } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$root = 'HKCU:\Software\Microsoft\IdentityCRL' | |
$UserEmail = (Get-ChildItem $root\UserExtendedProperties).PSChildName | |
$UserAccountUrl = (Get-ItemProperty -Path $root\InterruptState).AccountSettingsUrl | |
$UserEmail | |
$UserAccountUrl | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
param([string]$Path) | |
$resolvedPath = [IO.Path]::GetFullPath($Path) | |
(New-Object -ComObject WScript.Shell).CreateShortcut($resolvedPath).TargetPath |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$appsPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions' | |
Get-ItemProperty "$appsPath\*" | | |
Select-Object PSChildName, Name | | |
Sort-Object Name | | |
out-gridview | |
$folder = [ref]'dummy' | |
While ($folder.value) { | |
$folder.value = (Get-ItemProperty "$appsPath\*" | | |
Select-Object Name | | |
Sort-Object Name | | |
out-gridview -PassThru) | |
If ($folder.value) { | |
explorer "Shell:$($folder.value.Name)" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Enum]::GetNames([Management.Automation.CompletionResultType]) | | |
Sort-Object |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
param( | |
[Parameter(Mandatory)] | |
[String]$Name, | |
[Parameter(Mandatory)] | |
[String]$Root, | |
[Parameter(Mandatory)] | |
[Management.Automation.PSCredential]$Credentials) | |
$net = new-object -ComObject WScript.Network | |
$driveName = $Name.EndsWith(":") ? $Name : "$($Name):" | |
$net.MapNetworkDrive($driveName, $Root.TrimEnd("\"), $false, $Credentials.UserName, $Credentials.Password) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# @ https://www.powershellmagazine.com/2015/04/13/pstip-use-shell-application-to-display-extended-file-attributes/ | |
$com = (New-Object -ComObject Shell.Application).NameSpace('C:\') | |
$com.Items() | ForEach-Object { | |
New-Object -TypeName PSCustomObject -Property @{ | |
Name = $com.GetDetailsOf($_,0) | |
Size = $com.GetDetailsOf($_,1) | |
ItemType = $com.GetDetailsOf($_,2) | |
} | |
} | |
function Get-ExtensionAttribute { | |
[CmdletBinding()] | |
Param ( | |
[Parameter(ValueFromPipeline=$true, | |
ValueFromPipelineByPropertyName=$true, | |
Position=0)] | |
[string[]] | |
$FullName | |
) | |
DynamicParam | |
{ | |
$Attributes = New-Object System.Management.Automation.ParameterAttribute | |
$Attributes.ParameterSetName = "__AllParameterSets" | |
$Attributes.Mandatory = $false | |
$AttributeCollection = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute] | |
$AttributeCollection.Add($Attributes) | |
$Values = @($Com=(New-Object -ComObject Shell.Application).NameSpace('C:\');1..400 | ForEach-Object {$com.GetDetailsOf($com.Items,$_)} | Where-Object {$_} | ForEach-Object {$_ -replace '\s'}) | |
$AttributeValues = New-Object System.Management.Automation.ValidateSetAttribute($Values) | |
$AttributeCollection.Add($AttributeValues) | |
$DynParam1 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter("ExtensionAttribute", [string[]], $AttributeCollection) | |
$ParamDictionary = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary | |
$ParamDictionary.Add("ExtensionAttribute", $DynParam1) | |
$ParamDictionary | |
} | |
begin { | |
$ShellObject = New-Object -ComObject Shell.Application | |
$DefaultName = $ShellObject.NameSpace('C:\') | |
$ExtList = 0..400 | ForEach-Object { | |
($DefaultName.GetDetailsOf($DefaultName.Items,$_)).ToUpper().Replace(' ','') | |
} | |
} | |
process { | |
foreach ($Object in $FullName) { | |
# Check if there is a fullname attribute, in case pipeline from Get-ChildItem is used | |
if ($Object.FullName) { | |
$Object = $Object.FullName | |
} | |
# Check if the path is a single file or a folder | |
if (-not (Test-Path -Path $Object -PathType Container)) { | |
$CurrentNameSpace = $ShellObject.NameSpace($(Split-Path -Path $Object)) | |
$CurrentNameSpace.Items() | Where-Object { | |
$_.Path -eq $Object | |
} | ForEach-Object { | |
$HashProperties = @{ | |
FullName = $_.Path | |
} | |
foreach ($Attribute in $MyInvocation.BoundParameters.ExtensionAttribute) { | |
$HashProperties.$($Attribute) = $CurrentNameSpace.GetDetailsOf($_,$($ExtList.IndexOf($Attribute.ToUpper()))) | |
} | |
New-Object -TypeName PSCustomObject -Property $HashProperties | |
} | |
} elseif (-not $input) { | |
$CurrentNameSpace = $ShellObject.NameSpace($Object) | |
$CurrentNameSpace.Items() | ForEach-Object { | |
$HashProperties = @{ | |
FullName = $_.Path | |
} | |
foreach ($Attribute in $MyInvocation.BoundParameters.ExtensionAttribute) { | |
$HashProperties.$($Attribute) = $CurrentNameSpace.GetDetailsOf($_,$($ExtList.IndexOf($Attribute.ToUpper()))) | |
} | |
New-Object -TypeName PSCustomObject -Property $HashProperties | |
} | |
} | |
} | |
} | |
end { | |
Remove-Variable -Force -Name DefaultName | |
Remove-Variable -Force -Name CurrentNameSpace | |
Remove-Variable -Force -Name ShellObject | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$signature = @' | |
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)] | |
public static extern IntPtr SendMessageTimeout( | |
IntPtr hWnd, | |
uint Msg, | |
UIntPtr wParam, | |
IntPtr lParam, | |
SendMessageTimeoutFlags fuFlags, | |
uint uTimeout, | |
out UIntPtr lpdwResult); | |
'@ | |
Add-Type -MemberDefinition $signature -Name SendMessage -Namespace user32 -PassThru | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$signature = @' | |
class Program | |
{ | |
[System.Runtime.InteropServices.DllImport("Shell32.dll")] | |
private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2); | |
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)] | |
private static extern IntPtr SendMessageTimeout(IntPtr hWnd, int Msg, IntPtr wParam, string lParam, uint fuFlags, uint uTimeout, IntPtr lpdwResult); | |
private static readonly IntPtr HWND_BROADCAST = new IntPtr(0xffff); | |
private const int WM_SETTINGCHANGE = 0x1a; | |
private const int SMTO_ABORTIFHUNG = 0x0002; | |
static void Main(string[] args) | |
{ | |
SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, IntPtr.Zero, null, SMTO_ABORTIFHUNG, 100, IntPtr.Zero); | |
} | |
} | |
'@ | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$NS = @{ | |
Taskbar = '4234d49b-0245-4df3-b780-3893943456e1' | |
QuickAccess = '679F85CB-0220-4080-B29B-5540CC05AAB6' | |
} | |
$shell = New-Object -Com Shell.Application | |
$NameSpace = $shell.NameSpace("shell:::{$($NS.QuickAccess)}") | |
$items = $NameSpace.Items() | |
function Get-QuickAccess { | |
[CmdletBinding()] | |
[Alias('gqa')] | |
param( | |
[ArgumentCompleter( { 'Pinned', 'Unpinned' })] | |
[String]$Type = 'Pinned' | |
) | |
$qa = (New-Object -Com Shell.Application).NameSpace('shell:::{679F85CB-0220-4080-B29B-5540CC05AAB6}') | |
$match = (($Type -like 'Pinned')? 'UnPin From': 'Pin To') + ' Quick access' | |
$qa.Items() | Where-Object { ($_.Verbs() | ForEach-Object Name) -match $match } | |
} | |
$verbs = $items | | |
Where-Object { | |
($_.Verbs() | ForEach-Object Name) -match $match | |
} | |
$verbs | |
$NameSpace.Items() | | |
ForEach-Object -Parallel { | |
$verb = $_.Verbs() | ForEach-Object -Parallel { $_.Name } | |
$verb | |
# @{Item = $_; Verb = $_.Verbs() } | |
} | |
# Where-Object { $_.Verb.Name -match 'Remove from Quick access' } | | |
# ForEach-Object Item | |
# Where-Object{$_.Verbs().Name.Replace('&','') -match "Remove from QuickAccess"} | |
# | | |
# Where-Object { $_.Verbs().Name.Replace('&','') -like 'Remove from Quick access' } | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#requires -Version 5 | |
# this enum works in PowerShell 5 only | |
# in earlier versions, simply remove the enum, | |
# and use the numbers for the desired window state | |
# directly | |
Enum ShowStates { | |
Hide = 0 | |
Normal = 1 | |
Minimized = 2 | |
Maximized = 3 | |
ShowNoActivateRecentPosition = 4 | |
Show = 5 | |
MinimizeActivateNext = 6 | |
MinimizeNoActivate = 7 | |
ShowNoActivate = 8 | |
Restore = 9 | |
ShowDefault = 10 | |
ForceMinimize = 11 | |
} | |
# the C#-style signature of an API function (see also www.pinvoke.net) | |
$signarture = '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);' | |
# add signature as new type to PowerShell (for this session) | |
$type = Add-Type -MemberDefinition $signarture -Name win -Namespace user32 -PassThru | |
# access a process | |
# (in this example, we are accessing the current PowerShell host | |
# with its process ID being present in $pid, but you can use | |
# any process ID instead) | |
$process = Get-Process | Where-Object { $_.ProcessName -like 'notepad' } | select -First 1 | |
# get the process window handle | |
$hwnd = $process.MainWindowHandle | |
# apply a new window size to the handle, i.e. hide the window completely | |
$type::ShowWindowAsync($hwnd, [ShowStates]::ShowNoActivate) | |
# Start-Sleep -Seconds 2 | |
# restore the window handle again | |
# [usre32.win]::ShowWindowAsync($hwnd, [ShowStates]::Show) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Invoke-WakeOnLan | |
{ | |
param | |
( | |
# one or more MACAddresses | |
[Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] | |
# mac address must be a following this regex pattern: | |
[ValidatePattern('^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$')] | |
[string[]] | |
$MacAddress | |
) | |
begin | |
{ | |
# instantiate a UDP client: | |
$UDPclient = [Net.Sockets.UdpClient]::new() | |
} | |
process | |
{ | |
foreach($_ in $MacAddress) | |
{ | |
try { | |
$currentMacAddress = $_ | |
# get byte array from mac address: | |
$mac = $currentMacAddress -split '[:-]' | | |
# convert the hex number into byte: | |
ForEach-Object { | |
[Convert]::ToByte($_, 16) | |
} | |
#region compose the "magic packet" | |
# create a byte array with 102 bytes initialized to 255 each: | |
$packet = [byte[]](,0xFF * 102) | |
# leave the first 6 bytes untouched, and | |
# repeat the target mac address bytes in bytes 7 through 102: | |
6..101 | Foreach-Object { | |
# $_ is indexing in the byte array, | |
# $_ % 6 produces repeating indices between 0 and 5 | |
# (modulo operator) | |
$packet[$_] = $mac[($_ % 6)] | |
} | |
#endregion | |
# connect to port 400 on broadcast address: | |
$UDPclient.Connect(([Net.IPAddress]::Broadcast),4000) | |
# send the magic packet to the broadcast address: | |
$null = $UDPclient.Send($packet, $packet.Length) | |
Write-Verbose "sent magic packet to $currentMacAddress..." | |
} | |
catch | |
{ | |
Write-Warning "Unable to send ${mac}: $_" | |
} | |
} | |
} | |
end | |
{ | |
# release the UDF client and free its memory: | |
$UDPclient.Close() | |
$UDPclient.Dispose() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment