├── .github ├── FUNDING.yml └── workflows │ ├── CI.yml │ └── publish.yml ├── .gitignore ├── LICENSE ├── README.md ├── build.ps1 ├── publish.ps1 ├── src ├── FindLinks.ps1 ├── clockres.ps1 ├── coreinfo.ps1 ├── handle.ps1 ├── listdlls.ps1 ├── logonsession.ps1 ├── ntfsinfo.ps1 ├── pipelist.ps1 ├── psexec.ps1 ├── psloggedon.ps1 ├── sync.ps1 └── whois.ps1 ├── tests └── handle.tests.ps1 └── version.txt /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: adamdriscoll 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /.github/workflows/CI.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: [push, pull_request, workflow_dispatch] 3 | 4 | jobs: 5 | build: 6 | name: Build 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v1 10 | - name: Build 11 | run: ./build.ps1 12 | shell: pwsh -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish 2 | on: [workflow_dispatch] 3 | 4 | jobs: 5 | build: 6 | name: Build 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v1 10 | - name: Build 11 | run: ./build.ps1 12 | shell: pwsh 13 | - name: Publish 14 | run: ./publish.ps1 15 | shell: pwsh 16 | env: 17 | NUGETAPIKEY: ${{ secrets.NUGETAPIKEY }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | output 2 | obj -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Adam Driscoll 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SysInternals 2 | 3 | PowerShell Crescendo module for SysInternals tools. 4 | 5 | ![](https://img.shields.io/powershellgallery/dt/sysinternals?style=for-the-badge) 6 | 7 | # Installation 8 | 9 | This module does not include the commands that it wraps. You can install them with scoop or Chocolatey. 10 | 11 | ```powershell 12 | Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh') 13 | scoop bucket add extras 14 | scoop install sysinternals 15 | ``` 16 | 17 | ```powershell 18 | choco install sysinternals 19 | ``` 20 | 21 | To install this module: 22 | 23 | ```powershell 24 | Install-Module SysInternals 25 | ``` 26 | 27 | 28 | # Commands 29 | ## Get-LogonSession ([logonsessions.exe](https://docs.microsoft.com/en-us/sysinternals/downloads/logonsessions)) 30 | 31 | ```powershell 32 | Get-LogonSession [] 33 | ``` 34 | 35 | ## Find-Handle ([handle.exe](https://docs.microsoft.com/en-us/sysinternals/downloads/handle)) 36 | 37 | ```powershell 38 | Find-Handle [[-Name] ] [[-Process] ] [] 39 | ``` 40 | 41 | ## Show-ClockResolution ([clockres.exe](https://docs.microsoft.com/en-us/sysinternals/downloads/clockres)) 42 | 43 | ```powershell 44 | Show-ClockResolution [] 45 | ``` 46 | 47 | ## Show-CoreInfo ([coreinfo.exe](https://docs.microsoft.com/en-us/sysinternals/downloads/coreinfo)) 48 | 49 | ```powershell 50 | Show-CoreInfo [-Cores] [-Features] [-Groups] [-Caches] [-NumaNodes] [-Sockets] [-NumaAccessCost] [-Virtualization] [] 51 | ``` 52 | 53 | ## Show-Dll ([listdlls.exe](https://docs.microsoft.com/en-us/sysinternals/downloads/listdlls)) 54 | 55 | ```powershell 56 | Show-Dll [[-Name] ] [[-Process] ] [] 57 | ``` 58 | 59 | ## Show-LoggedOnAccount ([psloggedon.exe](https://docs.microsoft.com/en-us/sysinternals/downloads/psloggedon)) 60 | 61 | ```powershell 62 | Show-LoggedOnAccount [[-ComputerName] ] [[-User] ] [-Local] [-NoLogonTimes] [] 63 | ``` 64 | 65 | ## Show-NamedPipe ([pipelist.exe](https://docs.microsoft.com/en-us/sysinternals/downloads/pipelist)) 66 | 67 | ```powershell 68 | Show-NamedPipe [] 69 | ``` 70 | 71 | ## Start-PsExec ([psexec.exe](https://docs.microsoft.com/en-us/sysinternals/downloads/psexec)) 72 | 73 | ```powershell 74 | Start-PsExec [[-ComputerName] ] [[-Command] ] [[-Arguments] ] [-System] [] 75 | ``` 76 | 77 | ## Sync-Disk ([sync.exe](https://docs.microsoft.com/en-us/sysinternals/downloads/sync)) 78 | 79 | ```powershell 80 | Sync-Disk [[-Drive] ] [-FlushRemovableDrive] [-EjectRemovableDrive] [] 81 | ``` 82 | 83 | # Contributing 84 | 85 | Commands are defined in the [src](./src) directory. Each command should be in a PS1 file with the same name as the SysInternal tool. Commands are defined by hashtables that match the Crescendo JSON format. 86 | 87 | For example, the `Get-LogonSession` cmdlet is defined using this hashtable. 88 | 89 | ```powershell 90 | @{ 91 | Verb = 'Get' 92 | Noun = 'LogonSession' 93 | OriginalName = 'logonsession.exe' 94 | OriginalCommandElements = @("--nobanner", "--acceptlogo", "-c") 95 | OutputHandlers = @( 96 | @{ 97 | ParameterSetName = 'Default' 98 | HandlerType = 'Inline' 99 | Handler = '$args[0] | ConvertFrom-Csv' 100 | } 101 | ) 102 | } 103 | ``` 104 | 105 | To build and test the module, run `build.ps1`. Please note you will need Powershell 7 to run the build.ps1 106 | -------------------------------------------------------------------------------- /build.ps1: -------------------------------------------------------------------------------- 1 | $Output = "$PSScriptRoot\output" 2 | $obj = "$PSScriptRoot\obj" 3 | $Version = (Get-Content $PSScriptRoot\version.txt) 4 | Remove-Item $Output -Recurse -Force -ErrorAction SilentlyContinue 5 | Remove-Item $obj -Recurse -Force -ErrorAction SilentlyContinue 6 | 7 | $M = Import-Module Microsoft.PowerShell.Crescendo -RequiredVersion 1.0.0 -PassThru -ErrorAction SilentlyContinue 8 | if (-not $M) { 9 | Install-Module Microsoft.PowerShell.Crescendo -RequiredVersion 1.0.0 -Force -Scope CurrentUser 10 | } 11 | 12 | $M = Import-Module Pester -PassThru -ErrorAction SilentlyContinue 13 | if (-not $M) { 14 | Install-Module Pester -Force -Scope CurrentUser 15 | } 16 | 17 | New-Item $Output -ItemType Directory 18 | New-Item $obj -ItemType Directory 19 | 20 | $Commands = Get-ChildItem "$PSScriptRoot\src" | ForEach-Object { 21 | $Definition = & $_.FullName 22 | $Command = New-CrescendoCommand -Verb $Definition.Verb -Noun $Definition.Noun -OriginalName $Definition.OriginalName 23 | $Command.OriginalCommandElements = $Definition.OriginalCommandElements 24 | $Command.Platform = "Windows" 25 | 26 | if ($Definition.Parameters) { 27 | $Command.Parameters = $Definition.Parameters | ForEach-Object { 28 | $Parameter = New-ParameterInfo -Name $_.Name -OriginalName $_.OriginalName 29 | $Parameter.OriginalName = $_.OriginalName 30 | $Parameter.OriginalPosition = $_.OriginalPosition 31 | $Parameter.ParameterType = $_.ParameterType 32 | $Parameter 33 | } 34 | } 35 | 36 | if ($Definition.OutputHandlers) { 37 | $Command.OutputHandlers = $Definition.OutputHandlers | ForEach-Object { 38 | $Handler = New-OutputHandler 39 | $Handler.ParameterSetName = $_.ParameterSetName 40 | $Handler.Handler = $_.Handler 41 | $Handler.HandlerType = $_.HandlerType 42 | $Handler.StreamOutput = $_.StreamOutput 43 | $Handler 44 | } 45 | } 46 | 47 | $Command 48 | } 49 | 50 | @{ 51 | '$schema' = 'https://aka.ms/PowerShell/Crescendo/Schemas/2021-11' 52 | Commands = $Commands 53 | } | ConvertTo-Json -Depth 5 | Out-File "$obj\Commands.json" 54 | 55 | Export-CrescendoModule -ConfigurationFile (Get-ChildItem "$obj") -ModuleName (Join-Path $Output "SysInternals") -Force 56 | 57 | $ManifestInfo = @{ 58 | ModuleVersion = $Version 59 | Author = "Adam Driscoll" 60 | Company = 'Ironman Software' 61 | Description = 'PowerShell cmdlets for SysInternal tools' 62 | LicenseUri = 'https://github.com/adamdriscoll/sysinternals/blob/main/LICENSE' 63 | ProjectUri = 'https://github.com/adamdriscoll/sysinternals' 64 | } 65 | 66 | Update-ModuleManifest -Path (Join-Path $Output "SysInternals.psd1") @ManifestInfo 67 | 68 | Invoke-Pester -Path "$PSScriptRoot\tests" -------------------------------------------------------------------------------- /publish.ps1: -------------------------------------------------------------------------------- 1 | Rename-Item "$PSScriptRoot\output" -NewName "SysInternals" 2 | Publish-Module -Path "$PSScriptRoot\SysInternals" -NuGetApiKey $Env:NUGETAPIKEY -------------------------------------------------------------------------------- /src/FindLinks.ps1: -------------------------------------------------------------------------------- 1 | @{ 2 | Verb = 'Find' 3 | Noun = 'Links' 4 | OriginalName = 'FindLinks.exe' 5 | OriginalCommandElements = @("-nobanner","accepteula") 6 | Parameters = @( 7 | @{ 8 | ParameterType = 'String' 9 | OriginalPosition = [Int]::MaxValue 10 | Name = "File" 11 | } 12 | ) 13 | } -------------------------------------------------------------------------------- /src/clockres.ps1: -------------------------------------------------------------------------------- 1 | @{ 2 | Verb = 'Show' 3 | Noun = 'ClockResolution' 4 | OriginalName = 'clockres.exe' 5 | OriginalCommandElements = @("-nobanner", '-accepteula') 6 | } -------------------------------------------------------------------------------- /src/coreinfo.ps1: -------------------------------------------------------------------------------- 1 | @{ 2 | Verb = 'Show' 3 | Noun = 'CoreInfo' 4 | OriginalName = 'coreinfo.exe' 5 | OriginalCommandElements = @("-nobanner", '-accepteula') 6 | Parameters = @( 7 | @{ 8 | ParameterType = 'switch' 9 | OriginalName = '-c' 10 | Name = "Cores" 11 | } 12 | @{ 13 | ParameterType = 'switch' 14 | OriginalName = '-f' 15 | Name = "Features" 16 | } 17 | @{ 18 | ParameterType = 'switch' 19 | OriginalName = '-g' 20 | Name = "Groups" 21 | } 22 | @{ 23 | ParameterType = 'switch' 24 | OriginalName = '-l' 25 | Name = "Caches" 26 | } 27 | @{ 28 | ParameterType = 'switch' 29 | OriginalName = '-n' 30 | Name = "NumaNodes" 31 | } 32 | @{ 33 | ParameterType = 'switch' 34 | OriginalName = '-s' 35 | Name = "Sockets" 36 | } 37 | @{ 38 | ParameterType = 'switch' 39 | OriginalName = '-m' 40 | Name = "NumaAccessCost" 41 | } 42 | @{ 43 | ParameterType = 'switch' 44 | OriginalName = '-v' 45 | Name = "Virtualization" 46 | } 47 | ) 48 | } -------------------------------------------------------------------------------- /src/handle.ps1: -------------------------------------------------------------------------------- 1 | @{ 2 | Verb = 'Find' 3 | Noun = 'Handle' 4 | OriginalName = 'handle.exe' 5 | OriginalCommandElements = @("-nobanner") 6 | Parameters = @( 7 | @{ 8 | ParameterType = 'String' 9 | OriginalPosition = [Int]::MaxValue 10 | Name = "Name" 11 | } 12 | @{ 13 | ParameterType = 'String' 14 | Name = "Process" 15 | OriginalName = "-p" 16 | } 17 | @{ 18 | ParameterType = 'Switch' 19 | Name = "UserName" 20 | OriginalName = "-u" 21 | } 22 | @{ 23 | ParameterType = 'String' 24 | Name = "Close" 25 | OriginalName = "-c" 26 | } 27 | @{ 28 | ParameterType = 'Switch' 29 | Name = "NoPrompt" 30 | OriginalName = "-y" 31 | } 32 | ) 33 | } -------------------------------------------------------------------------------- /src/listdlls.ps1: -------------------------------------------------------------------------------- 1 | @{ 2 | Verb = 'Show' 3 | Noun = 'Dll' 4 | OriginalName = 'listdlls.exe' 5 | OriginalCommandElements = @("-accepteula", '-nobanner') 6 | Parameters = @( 7 | @{ 8 | ParameterType = 'String' 9 | ParameterSetName = "DLL" 10 | OriginalName = "-d" 11 | Name = "Name" 12 | } 13 | @{ 14 | ParameterType = 'String' 15 | ParameterSetName = "Process" 16 | Name = "Process" 17 | OriginalPosition = [Int]::MaxValue 18 | } 19 | ) 20 | } -------------------------------------------------------------------------------- /src/logonsession.ps1: -------------------------------------------------------------------------------- 1 | @{ 2 | Verb = 'Get' 3 | Noun = 'LogonSession' 4 | OriginalName = 'logonsessions.exe' 5 | OriginalCommandElements = @("-nobanner", "-c") 6 | OutputHandlers = @( 7 | @{ 8 | ParameterSetName = 'Default' 9 | HandlerType = 'Inline' 10 | Handler = '$args[0] | ConvertFrom-Csv' 11 | } 12 | ) 13 | } -------------------------------------------------------------------------------- /src/ntfsinfo.ps1: -------------------------------------------------------------------------------- 1 | @{ 2 | Verb = 'Get' 3 | Noun = 'NtfsInfo' 4 | Description = 'NTFSInfo is a little applet that shows you information about NTFS volumes.' 5 | OriginalName = 'ntfsinfo.exe' 6 | OriginalCommandElements = @("-accepteula", '-nobanner') 7 | Parameters = @( 8 | @{ 9 | ParameterType = 'String' 10 | Name = "DriveLetter" 11 | Mandatory = $true 12 | Description = "The drive letter to retrieve NTFS information for." 13 | } 14 | ) 15 | } -------------------------------------------------------------------------------- /src/pipelist.ps1: -------------------------------------------------------------------------------- 1 | @{ 2 | Verb = 'Show' 3 | Noun = 'NamedPipe' 4 | OriginalName = 'pipelist.exe' 5 | OriginalCommandElements = @("-nobanner", '-accepteula') 6 | } -------------------------------------------------------------------------------- /src/psexec.ps1: -------------------------------------------------------------------------------- 1 | @{ 2 | Verb = 'Start' 3 | Noun = 'PsExec' 4 | OriginalName = 'psexec.exe' 5 | OriginalCommandElements = @("--nobanner", "--accepteula") 6 | Parameters = @( 7 | @{ 8 | ParameterType = 'String' 9 | OriginalPosition = 0 10 | Name = "ComputerName" 11 | } 12 | @{ 13 | ParameterType = 'String' 14 | OriginalPosition = 1 15 | Name = "Command" 16 | } 17 | @{ 18 | ParameterType = 'String' 19 | OriginalPosition = 2 20 | Name = "Arguments" 21 | } 22 | @{ 23 | ParameterType = 'Switch' 24 | OriginalName = "-s" 25 | Name = "System" 26 | } 27 | ) 28 | OutputHandlers = @( 29 | @{ 30 | ParameterSetName = 'Default' 31 | HandlerType = 'Inline' 32 | Handler = '$args[0] | ConvertFrom-Csv' 33 | } 34 | ) 35 | } -------------------------------------------------------------------------------- /src/psloggedon.ps1: -------------------------------------------------------------------------------- 1 | @{ 2 | Verb = 'Show' 3 | Noun = 'LoggedOnAccount' 4 | OriginalName = 'psloggedon.exe' 5 | OriginalCommandElements = @("-nobanner", '-accepteula') 6 | Parameters = @( 7 | @{ 8 | ParameterType = 'switch' 9 | OriginalName = '-l' 10 | Name = "Local" 11 | } 12 | @{ 13 | ParameterType = 'switch' 14 | OriginalName = '-x' 15 | Name = "NoLogonTimes" 16 | } 17 | @{ 18 | ParameterType = 'string' 19 | OriginalPosition = 1 20 | ParameterSetName = "Computer" 21 | Name = "ComputerName" 22 | } 23 | @{ 24 | ParameterType = 'string' 25 | OriginalPosition = 1 26 | ParameterSetName = "User" 27 | Name = "User" 28 | } 29 | ) 30 | } -------------------------------------------------------------------------------- /src/sync.ps1: -------------------------------------------------------------------------------- 1 | @{ 2 | Verb = 'Sync' 3 | Noun = 'Disk' 4 | OriginalName = 'sync.exe' 5 | OriginalCommandElements = @("-nobanner", '-accepteula') 6 | Parameters = @( 7 | @{ 8 | ParameterType = 'string' 9 | OriginalPosition = 1 10 | Name = "Drive" 11 | } 12 | @{ 13 | ParameterType = 'switch' 14 | OriginalName = "-f" 15 | Name = "FlushRemovableDrive" 16 | } 17 | @{ 18 | ParameterType = 'switch' 19 | OriginalName = "-e" 20 | Name = "EjectRemovableDrive" 21 | } 22 | ) 23 | } -------------------------------------------------------------------------------- /src/whois.ps1: -------------------------------------------------------------------------------- 1 | @{ 2 | Verb = 'Find' 3 | Noun = 'Domain' 4 | OriginalName = 'whois.exe' 5 | OriginalCommandElements = @("-nobanner","-accepteula") 6 | Parameters = @( 7 | @{ 8 | ParameterType = 'String' 9 | Name = "DomainName" 10 | OriginalName = "-v" 11 | } 12 | ) 13 | } -------------------------------------------------------------------------------- /tests/handle.tests.ps1: -------------------------------------------------------------------------------- 1 | Import-Module "$PSScriptRoot\..\output\SysInternals.psd1" -Force 2 | 3 | Describe "Find-Handle" { 4 | It "should have command" { 5 | Get-Command Find-Handle | Should -Not -Be $null 6 | } 7 | } -------------------------------------------------------------------------------- /version.txt: -------------------------------------------------------------------------------- 1 | 1.1.0 2 | --------------------------------------------------------------------------------