├── .config └── tsaoptions.json ├── .github ├── CODE_OF_CONDUCT.md ├── SECURITY.md └── workflows │ └── ci-test.yml ├── .gitignore ├── .pipelines └── TextUtility-Official.yml ├── LICENSE ├── README.md ├── build.ps1 ├── global.json ├── nuget.config ├── src ├── Microsoft.PowerShell.TextUtility.format.ps1xml ├── Microsoft.PowerShell.TextUtility.psd1 ├── code │ ├── CompareTextCommand.cs │ ├── ConvertBase64Command.cs │ ├── DiffMatchPatch.cs │ ├── Microsoft.PowerShell.TextUtility.csproj │ ├── TestSpellingCommand.cs │ └── TextTableParser.cs └── dictionary.txt ├── test ├── Base64.tests.ps1 ├── CompareText.tests.ps1 ├── TextTableParser.Tests.ps1 └── assets │ ├── attrib.01.txt │ ├── columns.01.txt │ ├── df.01.txt │ ├── docker.01.txt │ ├── docker.02.txt │ ├── docker.03.txt │ ├── docker.04.txt │ ├── getmac.01.txt │ ├── kmutil.01.txt │ ├── ls.01.txt │ ├── ls.02.txt │ ├── ls.03.txt │ ├── ps.01.txt │ ├── ps.02.txt │ ├── ps.03.txt │ ├── ps.04.txt │ ├── tasklist.01.txt │ ├── tasklist.02.txt │ ├── who.01.txt │ └── who.02.txt └── yaml ├── ci.yml ├── releaseBuild.yml └── template └── runtest.yml /.config/tsaoptions.json: -------------------------------------------------------------------------------- 1 | { 2 | "instanceUrl": "https://msazure.visualstudio.com", 3 | "projectName": "One", 4 | "areaPath": "One\\MGMT\\Compute\\Powershell\\Powershell\\PowerShell Core\\TextUtility", 5 | "codebaseName": "TFSMSAzure_TextUtility", 6 | "notificationAliases": [ "jimtru@microsoft.com", "slee@microsoft.com" ], 7 | "tools": [ "CredScan", "PoliCheck", "BinSkim" ] 8 | } 9 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | - Employees can reach out at [aka.ms/opensource/moderation-support](https://aka.ms/opensource/moderation-support) 11 | -------------------------------------------------------------------------------- /.github/SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin) and [PowerShell](https://github.com/PowerShell). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/security.md/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/security.md/msrc/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/security.md/msrc/pgp). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/security.md/msrc/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/security.md/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /.github/workflows/ci-test.yml: -------------------------------------------------------------------------------- 1 | name: TextUtility CI Tests 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | ci: 11 | name: Build and Test 12 | strategy: 13 | matrix: 14 | os: [ windows-latest, macos-latest, ubuntu-latest ] 15 | runs-on: ${{ matrix.os }} 16 | env: 17 | DOTNET_NOLOGO: true 18 | DOTNET_GENERATE_ASPNET_CERTIFICATE: false 19 | steps: 20 | - name: Checkout repository 21 | uses: actions/checkout@v4 22 | 23 | - name: Install dotnet 24 | uses: actions/setup-dotnet@v4 25 | with: 26 | cache: true 27 | cache-dependency-path: '**/*.csproj' 28 | 29 | - name: Install PSResources 30 | run: ./build.ps1 -Bootstrap 31 | shell: pwsh 32 | 33 | - name: Build 34 | run: ./build.ps1 -Configuration Release 35 | shell: pwsh 36 | 37 | - name: Test 38 | run: ./build.ps1 -Test -NoBuild 39 | shell: pwsh 40 | 41 | - name: Upload test results 42 | uses: actions/upload-artifact@v4 43 | if: always() 44 | with: 45 | name: TextUtility-tests-${{ matrix.os }} 46 | path: testResults.xml 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # directories created during build 2 | bin/ 3 | obj/ 4 | out/ 5 | *.nupkg 6 | project.lock.json 7 | .DS_Store 8 | Microsoft.PowerShell.TextUtility.xml 9 | testResults.xml 10 | # VSCode directories that are not at the repository root 11 | /**/.vscode/ 12 | -------------------------------------------------------------------------------- /.pipelines/TextUtility-Official.yml: -------------------------------------------------------------------------------- 1 | name: TextUtility-ModuleBuild-$(Build.BuildId) 2 | trigger: none 3 | pr: none 4 | 5 | schedules: 6 | - cron: '0 3 * * 1' 7 | displayName: Weekly Build 8 | branches: 9 | include: 10 | - main 11 | always: true 12 | 13 | parameters: 14 | - name: 'publishToPowerShellGallery' 15 | displayName: 'Publish module to PowerShell gallery' 16 | type: boolean 17 | default: false 18 | 19 | variables: 20 | BuildConfiguration: Release 21 | DOTNET_NOLOGO: true 22 | DOTNET_GENERATE_ASPNET_CERTIFICATE: false 23 | DOTNET_CLI_TELEMETRY_OPTOUT: 1 24 | POWERSHELL_TELEMETRY_OPTOUT: 1 25 | DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 26 | WindowsContainerImage: onebranch.azurecr.io/windows/ltsc2022/vse2022:latest 27 | 28 | resources: 29 | repositories: 30 | - repository: templates 31 | type: git 32 | name: OneBranch.Pipelines/GovernedTemplates 33 | ref: refs/heads/main 34 | 35 | extends: 36 | # https://aka.ms/obpipelines/templates 37 | template: v2/OneBranch.Official.CrossPlat.yml@templates 38 | parameters: 39 | featureFlags: 40 | WindowsHostVersion: '1ESWindows2022' 41 | globalSdl: # https://aka.ms/obpipelines/sdl 42 | asyncSdl: 43 | enabled: true 44 | forStages: [build] 45 | #credscan: 46 | # enabled: true 47 | # scanfolder: $(Build.SourcesDirectory) 48 | # suppressionsFile: $(Build.SourcesDirectory)\.config\suppress.json 49 | stages: 50 | - stage: build 51 | jobs: 52 | - job: main 53 | displayName: Build package 54 | pool: 55 | type: windows 56 | variables: 57 | - name: ob_outputDirectory 58 | value: $(Build.SourcesDirectory)/out 59 | #- name: ob_sdl_credscan_suppressionsFile 60 | # value: $(Build.SourcesDirectory)\.config\suppress.json 61 | steps: 62 | - pwsh: | 63 | Write-Verbose -Verbose ((Get-Item $(Build.SourcesDirectory)).FullName) 64 | Get-ChildItem $(Build.SourcesDirectory) -Recurse -File -Name | Write-Verbose -Verbose 65 | $manifestData = Import-PowerShellDataFile -Path src/Microsoft.PowerShell.TextUtility.psd1 66 | $moduleVersion = $manifestData.ModuleVersion 67 | Write-Output "##vso[task.setvariable variable=version;isOutput=true]$moduleVersion" 68 | if ($manifestData.PrivateData.PsData.Prerelease) { 69 | $prerel = $manifestData.PrivateData.PSData.Prerelease 70 | $nupkgVersion = "${moduleVersion}-${prerel}" 71 | } else { 72 | $nupkgVersion = $moduleVersion 73 | } 74 | Write-Output "##vso[task.setvariable variable=nupkgversion;isOutput=true]$nupkgVersion" 75 | name: package 76 | displayName: Get version from project properties 77 | - task: onebranch.pipeline.version@1 78 | displayName: Set OneBranch version 79 | inputs: 80 | system: Custom 81 | customVersion: $(package.version) 82 | - task: UseDotNet@2 83 | displayName: Use .NET SDK 84 | inputs: 85 | packageType: sdk 86 | useGlobalJson: true 87 | - pwsh: | 88 | Get-ChildItem | Write-Verbose -Verbose 89 | ./build.ps1 -Configuration Release 90 | displayName: Build 91 | - task: onebranch.pipeline.signing@1 92 | displayName: Sign 1st-party files 93 | inputs: 94 | command: sign 95 | signing_profile: external_distribution 96 | search_root: $(Build.SourcesDirectory)/out/Microsoft.PowerShell.TextUtility 97 | files_to_sign: | 98 | *.psd1; 99 | *.ps1xml; 100 | Microsoft.PowerShell.*.dll; 101 | - task: ArchiveFiles@2 102 | displayName: Zip module 103 | inputs: 104 | rootFolderOrFile: $(Build.SourcesDirectory)/out/Microsoft.PowerShell.TextUtility 105 | includeRootFolder: false 106 | archiveType: zip 107 | archiveFile: out/Microsoft.PowerShell.TextUtility-v$(package.version).zip 108 | - pwsh: | 109 | ./build -package -nobuild 110 | Write-Verbose -Verbose ((Get-Item .).FullName) 111 | Write-Verbose -Verbose ((Get-Item $(Build.SourcesDirectory)).FullName) 112 | Get-ChildItem $(Build.SourcesDirectory) -Recurse -File -Name | Write-Verbose -Verbose 113 | displayName: Package module 114 | - task: onebranch.pipeline.signing@1 115 | displayName: Sign NuGet package 116 | inputs: 117 | command: sign 118 | signing_profile: external_distribution 119 | search_root: $(Build.SourcesDirectory) 120 | files_to_sign: "**/*.nupkg" 121 | - stage: release 122 | dependsOn: build 123 | condition: ${{ parameters.publishToPowerShellGallery }} 124 | variables: 125 | version: $[ stageDependencies.build.main.outputs['package.version'] ] 126 | drop: $(Pipeline.Workspace)/drop_build_main 127 | jobs: 128 | - job: validation 129 | displayName: Manual validation 130 | pool: 131 | type: agentless 132 | timeoutInMinutes: 1440 133 | steps: 134 | - task: ManualValidation@0 135 | displayName: Wait 24 hours for validation 136 | inputs: 137 | notifyUsers: $(Build.RequestedForEmail) 138 | instructions: Please validate the release and then publish it! 139 | timeoutInMinutes: 1440 140 | - job: publish 141 | dependsOn: validation 142 | displayName: Publish to PowerShell Gallery 143 | pool: 144 | type: windows 145 | variables: 146 | ob_outputDirectory: $(Build.SourcesDirectory)/out/Microsoft.PowerShell.TextUtility 147 | steps: 148 | - download: current 149 | displayName: Download artifacts 150 | - task: NuGetCommand@2 151 | displayName: Publish ConsoleGuiTools to PowerShell Gallery 152 | inputs: 153 | command: push 154 | packagesToPush: $(Build.SourcesDirectory)/out/Microsoft.PowerShell.TextUtility.$(package.nupkgVersion).nupkg 155 | nuGetFeedType: external 156 | publishFeedCredentials: PowerShellGallery 157 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 PowerShell Team 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 | # Microsoft.PowerShell.TextUtility 2 | 3 | This module is a collection of cmdlets for working with text content. 4 | 5 | > Please note that this module has been archived and is no longer actively maintained. 6 | > Feel free to fork it if you'd like! 7 | 8 | ## Compare-Text 9 | 10 | This cmdlet compares two text strings using [diff-match-patch](https://github.com/google/diff-match-patch). 11 | 12 | `diff-match-patch` is under [Apache 2.0 License](https://github.com/google/diff-match-patch/blob/master/LICENSE) 13 | 14 | ## ConvertFrom-Base64 15 | 16 | Return a string decoded from base64. 17 | 18 | ## ConvertTo-Base64 19 | 20 | Return a base64 encoded representation of a string. 21 | 22 | ## ConvertFrom-TextTable 23 | 24 | This will convert tabular data and convert it to an object. 25 | 26 | ## Code of Conduct 27 | 28 | Please see our [Code of Conduct](.github/CODE_OF_CONDUCT.md) before participating in this project. 29 | 30 | ## Security Policy 31 | 32 | For any security issues, please see our [Security Policy](.github/SECURITY.md). 33 | -------------------------------------------------------------------------------- /build.ps1: -------------------------------------------------------------------------------- 1 | ## Copyright (c) Microsoft Corporation. 2 | ## Licensed under the MIT License. 3 | 4 | [CmdletBinding(DefaultParameterSetName="build")] 5 | param ( 6 | [Parameter(ParameterSetName="build")] 7 | [string] 8 | $Configuration = "Debug", 9 | 10 | [Parameter(ParameterSetName="package")] 11 | [switch] 12 | $NoBuild, 13 | 14 | [Parameter(ParameterSetName="package")] 15 | [switch] 16 | $Package, 17 | 18 | [Parameter(ParameterSetName="package")] 19 | [switch] 20 | $signed, 21 | 22 | [Parameter(ParameterSetName="package")] 23 | [Parameter(ParameterSetName="test")] 24 | [switch] 25 | $test, 26 | 27 | [Parameter()] 28 | [switch] 29 | $Clean, 30 | 31 | [Parameter()] 32 | [switch] 33 | $GetPackageVersion, 34 | 35 | [Parameter(ParameterSetName="bootstrap")] 36 | [switch] 37 | $Bootstrap 38 | 39 | ) 40 | 41 | 42 | $moduleFileManifest = @( 43 | @{ Sign = $true ; File = "Microsoft.PowerShell.TextUtility.format.ps1xml" } 44 | @{ Sign = $true ; File = "Microsoft.PowerShell.TextUtility.psd1" } 45 | @{ Sign = $false; File = "dictionary.txt" } 46 | @{ Sign = $true ; File = "Microsoft.PowerShell.TextUtility.dll" } 47 | ) 48 | 49 | $moduleName = "Microsoft.PowerShell.TextUtility" 50 | $repoRoot = git rev-parse --show-toplevel 51 | $testRoot = "${repoRoot}/test" 52 | 53 | # 54 | function Get-ModuleInfo { 55 | import-powershelldatafile "$repoRoot/src/${moduleName}.psd1" 56 | } 57 | 58 | # this takes the files for the module and publishes them to a created, local repository 59 | # so the nupkg can be used to publish to the PSGallery 60 | function Export-Module 61 | { 62 | [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingWriteHost", "")] 63 | param($packageRoot) 64 | 65 | if ( -not (test-path $packageRoot)) { 66 | throw "'$packageRoot' does not exist" 67 | } 68 | # now construct a nupkg by registering a local repository and calling publish module 69 | $repoName = [guid]::newGuid().ToString("N") 70 | try { 71 | Register-PSRepository -Name $repoName -SourceLocation "${repoRoot}/out" -InstallationPolicy Trusted 72 | Publish-Module -Path $packageRoot -Repository $repoName 73 | } 74 | catch { 75 | throw $_ 76 | } 77 | finally { 78 | if (Get-PackageSource -Name $repoName) { 79 | Unregister-PSRepository -Name $repoName 80 | } 81 | } 82 | Get-ChildItem -Recurse -Name $packageRoot | Write-Verbose -Verbose 83 | 84 | # construct the package path and publish it 85 | $nupkgName = "{0}.{1}" -f $moduleName,$moduleInfo.ModuleVersion 86 | $pre = $moduleInfo.PrivateData.PSData.Prerelease 87 | if ($pre) { $nupkgName += "-${pre}" } 88 | $nupkgName += ".nupkg" 89 | $nupkgPath = Join-Path $repoRoot out $nupkgName 90 | Write-Verbose -Verbose "package path: ${nupkgPath} (exists:$(Test-Path $nupkgPath))" 91 | } 92 | 93 | function Test-Module { 94 | try { 95 | $PSVersionTable | Out-String -Stream | Write-Verbose -Verbose 96 | $importTarget = "Import-Module ${PSScriptRoot}/out/${ModuleName}" 97 | $importPester = "Import-Module Pester -Max 4.10.1" 98 | $invokePester = "Invoke-Pester -OutputFormat NUnitXml -EnableExit -OutputFile ../testResults.xml" 99 | $sb = [scriptblock]::Create("${importTarget}; ${importPester}; ${invokePester}") 100 | Push-Location $testRoot 101 | # calculate the shell to run rather than hardcoding it. 102 | $PSEXE = (Get-Process -id $PID).MainModule.FileName 103 | & $PSEXE -noprofile -command $sb 104 | } 105 | finally { 106 | Pop-Location 107 | } 108 | } 109 | 110 | function Invoke-Bootstrap 111 | { 112 | $neededPesterModule = Get-Module -Name Pester -ListAvailable | Where-Object { $_.Version -eq "4.10.1" } 113 | $neededPesterVersion = [version]"4.10.1" 114 | if ($neededPesterModule.Version -eq $neededPesterVersion) 115 | { 116 | Write-Verbose -Verbose -Message "Required pester version $neededPesterVersion is available." 117 | return 118 | } 119 | 120 | Write-Verbose -Verbose -Message "Attempting install of Pester version ${neededPesterVersion}." 121 | Install-Module -Name Pester -Scope CurrentUser -RequiredVersion 4.10.1 -Force -SkipPublisherCheck 122 | $neededPesterModule = Get-Module -Name Pester -ListAvailable | Where-Object { $_.Version -eq $neededPesterVersion } 123 | if ($neededPesterModule.Version -ne $neededPesterVersion) 124 | { 125 | throw "Pester install failed" 126 | } 127 | 128 | Write-Verbose -Verbose -Message "Pester version $neededPesterVersion installed." 129 | return 130 | } 131 | 132 | 133 | try { 134 | Push-Location "$PSScriptRoot/src/code" 135 | $script:moduleInfo = Get-ModuleInfo 136 | if ($GetPackageVersion) { 137 | return $moduleInfo.ModuleVersion 138 | } 139 | 140 | if ($Bootstrap) { 141 | Invoke-Bootstrap 142 | return 143 | } 144 | 145 | $outPath = "$PSScriptRoot/out/${moduleName}" 146 | if ($Clean) { 147 | if (Test-Path $outPath) { 148 | Write-Verbose "Deleting $outPath" 149 | Remove-Item -recurse -force -path $outPath 150 | } 151 | 152 | dotnet clean 153 | } 154 | 155 | if (-not $NoBuild) { 156 | dotnet publish --verbosity d --output $outPath --configuration $Configuration 157 | Remove-Item -Path "$outPath/Microsoft.PowerShell.TextUtility.deps.json" -ErrorAction SilentlyContinue 158 | if ($Configuration -eq "Release") { 159 | Remove-Item -Path "$outPath/Microsoft.PowerShell.TextUtility.pdb" -ErrorAction SilentlyContinue 160 | } 161 | } 162 | 163 | if ($Test) { 164 | Test-Module 165 | return 166 | } 167 | 168 | if ($Package) { 169 | if ($Signed) { 170 | $pkgBase = "${PSScriptRoot}/signed/${moduleName}" 171 | } 172 | else { 173 | $pkgBase = "${PSScriptRoot}/out/${moduleName}" 174 | } 175 | 176 | if (-not (Test-Path $pkgBase)) { 177 | throw "Directory '$pkgBase' does not exist" 178 | } 179 | 180 | Export-Module -packageRoot $pkgBase 181 | } 182 | } 183 | finally { 184 | Pop-Location 185 | } 186 | -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "8.0.100", 4 | "rollForward": "latestMajor" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/Microsoft.PowerShell.TextUtility.format.ps1xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Inline 5 | 6 | Microsoft.PowerShell.TextUtility.CompareTextDiff 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Set-StrictMode -Off 15 | 16 | $deleteColor = "$([char]0x1b)[1;9;31m" 17 | $insertColor = "$([char]0x1b)[0;1;32m" 18 | $resetColor = "$([char]0x1b)[0m" 19 | $textBuilder = [System.Text.StringBuilder]::new() 20 | $newline = [System.Environment]::NewLine 21 | 22 | $addNewLine = $false 23 | if ($_.LeftFile) { 24 | $null = $textBuilder.Append("${deleteColor}File:${resetColor} $($_.LeftFile)${newline}") 25 | $addNewLine = $true 26 | } 27 | 28 | if ($_.RightFile) { 29 | $null = $textBuilder.Append("${insertColor}File:${resetColor} $($_.RightFile)${newline}") 30 | $addNewLine = $true 31 | } 32 | 33 | if ($addNewLine) { 34 | $null = $textBuilder.Append($newline) 35 | } 36 | 37 | foreach ($diff in $_.Diff) { 38 | $text = $diff.text 39 | switch ($diff.Operation) 40 | { 41 | "EQUAL" { 42 | $null = $textBuilder.Append($text) 43 | } 44 | 45 | "DELETE" { 46 | $null = $textBuilder.Append("${deleteColor}${text}${resetColor}") 47 | } 48 | 49 | "INSERT" { 50 | $null = $textBuilder.Append("${insertColor}${text}${resetColor}") 51 | } 52 | } 53 | } 54 | 55 | $textBuilder.ToString() 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | SideBySide 65 | 66 | Microsoft.PowerShell.TextUtility.CompareTextDiff#SideBySide 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | Set-StrictMode -Off 75 | 76 | $consoleWidth = 120 77 | try { 78 | if ([Console]::WindowWidth -ne 0) { 79 | $consoleWidth = [Console]::WindowWidth 80 | } 81 | } 82 | catch { 83 | # just use default if this fails because there isn't a real console 84 | } 85 | 86 | $deleteText = [System.Text.StringBuilder]::new() 87 | $insertText = [System.Text.StringBuilder]::new() 88 | $deleteColor = "$([char]0x1b)[1;9;31m" 89 | $insertColor = "$([char]0x1b)[0;1;32m" 90 | $resetColor = "$([char]0x1b)[0m" 91 | $ellipsis = [char]0x2026 92 | $newline = [System.Environment]::NewLine 93 | 94 | foreach ($diff in $_.Diff) { 95 | $text = $diff.text.Replace("`r","") 96 | 97 | switch ($diff.operation) 98 | { 99 | "EQUAL" { 100 | $text = $text.Replace("`n","`n${resetColor}") 101 | $null = $deleteText.Append("${resetColor}${text}") 102 | $null = $insertText.Append("${resetColor}${text}") 103 | } 104 | 105 | "DELETE" { 106 | $text = $text.Replace("`n","`n${deleteColor}") 107 | $null = $deleteText.Append("${deleteColor}${text}") 108 | } 109 | 110 | "INSERT" { 111 | $text = $text.Replace("`n","`n${insertColor}") 112 | $null = $insertText.Append("${insertColor}${text}") 113 | } 114 | } 115 | } 116 | 117 | function Remove-VT100([string] $text) { 118 | $text.Replace($deleteColor,"").Replace($insertColor,"").Replace($resetColor,"") 119 | } 120 | 121 | $leftLines = $deleteText.ToString().Split("`n") 122 | $rightLines = $insertText.ToString().Split("`n") 123 | $lines = $leftLines.Count 124 | 125 | if ($rightLines.Count -gt $lines) { 126 | $lines = $rightLines.Count 127 | } 128 | 129 | $linesWidth = ($lines + 1).ToString().Length 130 | # 5 chars for whitespace and pipe after line number and whitespace, pipe, whitespace separating left and right 131 | [int]$columnWidth = ($consoleWidth - $linesWidth - 5) / 2 132 | 133 | # find longest line and use that as the columnWidth if less than current 134 | $longestWidth = 0 135 | foreach ($line in $leftLines) { 136 | $line = Remove-VT100 -text $line 137 | if ($line.Length -gt $longestWidth) { 138 | $longestWidth = $line.Length 139 | } 140 | } 141 | 142 | if ($longestWidth -lt $columnWidth) { 143 | $columnWidth = $longestWidth 144 | } 145 | 146 | $textOutput = [System.Text.StringBuilder]::new() 147 | 148 | if ($_.LeftFile -or $_.RightFile) { 149 | $prefix = "File: " 150 | $null = $textOutput.Append("".PadLeft($linesWidth)) 151 | $null = $textOutput.Append("${resetColor} | ") 152 | if ($_.LeftFile) { 153 | $leftFile = $_.LeftFile 154 | if ($leftFile.Length + $prefix.Length -gt $columnWidth) { 155 | $leftFile = $ellipsis + $leftFile.Remove(0, $leftFile.Length - $columnWidth + 1 + $prefix.Length) 156 | } 157 | else { 158 | $leftFile = $leftFile.PadRight($columnWidth - $prefix.Length) 159 | } 160 | 161 | $leftFile = "${deleteColor}${prefix}${resetColor}${leftFile}" 162 | } 163 | else { 164 | $leftFile = "".PadLeft($columnWidth) 165 | } 166 | 167 | if ($_.RightFile) { 168 | $rightFile = $_.RightFile 169 | if ($rightFile.Length + $prefix.Length -gt $columnWidth) { 170 | $rightFile = $ellipsis + $rightFile.Remove(0, $rightFile.Length - $columnWidth + 1 + $prefix.Length) 171 | } 172 | 173 | $rightFile = "${insertColor}${prefix}${resetColor}${rightFile}" 174 | } 175 | 176 | $null = $textOutput.Append($leftFile) 177 | $null = $textOutput.Append("${resetColor} | ") 178 | $null = $textOutput.Append($rightFile) 179 | $null = $textOutput.Append($newline) 180 | $null = $textOutput.Append("".PadLeft($linesWidth)) 181 | $null = $textOutput.Append("${resetColor} | ") 182 | $null = $textOutput.Append("".PadLeft($columnWidth)) 183 | $null = $textOutput.Append(" |") 184 | $null = $textOutput.Append($newline) 185 | } 186 | 187 | for ($i = 0; $i -lt $lines; $i++) { 188 | if ($i -ge $leftLines.Count) { 189 | $leftText = "".PadRight($columnWidth) 190 | } 191 | else { 192 | $lineLength = (Remove-VT100 -text $leftLines[$i]).Length 193 | if ($lineLength -gt $columnWidth) { 194 | $leftText = $leftLines[$i].Substring(0, $columnWidth - 1 + ($leftLines[$i].Length - $lineLength)) + $ellipsis 195 | } 196 | else { 197 | $leftText = $leftLines[$i] + "${resetColor}" + "".PadRight($columnWidth - $lineLength) 198 | } 199 | } 200 | 201 | if ($i -ge $rightLines.Count) { 202 | $rightText = "" 203 | } 204 | else { 205 | $lineLength = (Remove-VT100 -text $rightLines[$i]).Length 206 | if ($lineLength -gt $columnWidth) { 207 | $rightText = $rightLines[$i].Substring(0, $columnWidth - 1 + ($rightLines[$i].Length - $lineLength)) + $ellipsis 208 | } 209 | else { 210 | $rightText = $rightLines[$i] 211 | } 212 | } 213 | 214 | $lineNumber = ($i + 1).ToString() 215 | $null = $textOutput.Append($resetColor) 216 | $null = $textOutput.Append($lineNumber.PadLeft($linesWidth - $lineNumber.Length)) 217 | $null = $textOutput.Append(" | ") 218 | $null = $textOutput.Append($leftText) 219 | $null = $textOutput.Append("${resetColor} | ") 220 | $null = $textOutput.Append($rightText) 221 | $null = $textOutput.Append($newline) 222 | } 223 | 224 | $null = $textOutput.Append("${resetColor}") 225 | $textOutput.ToString() 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | -------------------------------------------------------------------------------- /src/Microsoft.PowerShell.TextUtility.psd1: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Corporation. 2 | # Licensed under the MIT License. 3 | 4 | @{ 5 | RootModule = '.\Microsoft.PowerShell.TextUtility.dll' 6 | ModuleVersion = '0.5.0' 7 | CompatiblePSEditions = @('Desktop', 'Core') 8 | GUID = '5cb64356-cd04-4a18-90a4-fa4072126155' 9 | Author = 'Microsoft Corporation' 10 | CompanyName = 'Microsoft Corporation' 11 | Copyright = '(c) Microsoft Corporation. All rights reserved.' 12 | Description = "This module contains cmdlets to help with manipulating or reading text." 13 | PowerShellVersion = '7.0' 14 | FormatsToProcess = @('Microsoft.PowerShell.TextUtility.format.ps1xml') 15 | CmdletsToExport = @( 16 | 'Compare-Text','ConvertFrom-Base64','ConvertTo-Base64',"ConvertFrom-TextTable" 17 | ) 18 | PrivateData = @{ 19 | PSData = @{ 20 | LicenseUri = 'https://github.com/PowerShell/TextUtility/blob/main/LICENSE' 21 | ProjectUri = 'https://github.com/PowerShell/TextUtility' 22 | ReleaseNotes = 'Second pre-release' 23 | } 24 | } 25 | 26 | # HelpInfoURI = '' 27 | } 28 | -------------------------------------------------------------------------------- /src/code/CompareTextCommand.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Management.Automation; 8 | 9 | using DiffMatchPatch; 10 | 11 | namespace Microsoft.PowerShell.TextUtility 12 | { 13 | public struct CompareTextDiff 14 | { 15 | public List Diff; 16 | } 17 | 18 | public enum CompareTextView 19 | { 20 | Inline, 21 | SideBySide, 22 | 23 | } 24 | 25 | [Cmdlet(VerbsData.Compare, "Text")] 26 | [OutputType(typeof(CompareTextDiff))] 27 | public sealed class CompareTextCommand : PSCmdlet 28 | { 29 | /// 30 | /// Gets or sets the left hand side text to compare. 31 | /// 32 | [Parameter(Position=0, Mandatory=true)] 33 | public string LeftText { get; set; } 34 | 35 | /// 36 | /// Gets or sets the right hand side text to compare. 37 | /// 38 | [Parameter(Position=1, Mandatory=true)] 39 | public string RightText { get; set; } 40 | 41 | /// 42 | /// Gets or sets the view type. 43 | /// 44 | [Parameter()] 45 | public CompareTextView View { get; set; } 46 | 47 | private string _leftFile = null; 48 | private string _rightFile = null; 49 | protected override void BeginProcessing() 50 | { 51 | try 52 | { 53 | string leftFile = SessionState.Path.GetUnresolvedProviderPathFromPSPath(LeftText); 54 | string rightFile = SessionState.Path.GetUnresolvedProviderPathFromPSPath(RightText); 55 | if (File.Exists(leftFile)) 56 | { 57 | _leftFile = leftFile; 58 | LeftText = File.ReadAllText(_leftFile); 59 | } 60 | 61 | if (File.Exists(rightFile)) 62 | { 63 | _rightFile = rightFile; 64 | RightText = File.ReadAllText(_rightFile); 65 | } 66 | } 67 | catch 68 | { 69 | // do nothing and treat as text 70 | } 71 | } 72 | 73 | protected override void ProcessRecord() 74 | { 75 | diff_match_patch dmp = new diff_match_patch(); 76 | List diff = dmp.diff_main(LeftText, RightText); 77 | dmp.diff_cleanupSemantic(diff); 78 | var output = new CompareTextDiff(); 79 | output.Diff = diff; 80 | var psObj = new PSObject(output); 81 | 82 | if (_leftFile != null) 83 | { 84 | psObj.Properties.Add(new PSNoteProperty("LeftFile", _leftFile)); 85 | } 86 | 87 | if (_rightFile != null) 88 | { 89 | psObj.Properties.Add(new PSNoteProperty("RightFile", _rightFile)); 90 | } 91 | 92 | if (View == CompareTextView.SideBySide) 93 | { 94 | psObj.TypeNames.Insert(0, "Microsoft.PowerShell.TextUtility.CompareTextDiff#SideBySide"); 95 | } 96 | 97 | WriteObject(psObj); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/code/ConvertBase64Command.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Management.Automation; 7 | using System.Text; 8 | 9 | namespace Microsoft.PowerShell.TextUtility 10 | { 11 | [Cmdlet(VerbsData.ConvertFrom, "Base64", DefaultParameterSetName="Text")] 12 | [OutputType(typeof(string))] 13 | public sealed class ConvertFromBase64Command : PSCmdlet 14 | { 15 | /// 16 | /// Gets or sets the base64 encoded string. 17 | /// 18 | [Parameter(Position=0, Mandatory=true, ValueFromPipeline=true, ParameterSetName="Text")] 19 | public string EncodedText { get; set; } 20 | 21 | /// 22 | /// Gets or sets the AsByteArray switch. 23 | /// 24 | [Parameter()] 25 | public SwitchParameter AsByteArray { get; set; } 26 | 27 | protected override void ProcessRecord() 28 | { 29 | var base64Bytes = Convert.FromBase64String(EncodedText); 30 | 31 | if (AsByteArray) 32 | { 33 | WriteObject(base64Bytes); 34 | } 35 | else 36 | { 37 | WriteObject(Encoding.UTF8.GetString(base64Bytes)); 38 | } 39 | } 40 | } 41 | 42 | [Cmdlet(VerbsData.ConvertTo, "Base64", DefaultParameterSetName="Text")] 43 | [OutputType(typeof(string))] 44 | public sealed class ConvertToBase64Command : PSCmdlet 45 | { 46 | /// 47 | /// Gets or sets the text to encoded to base64. 48 | /// 49 | [Parameter(Position=0, Mandatory=true, ValueFromPipeline=true, ParameterSetName="Text")] 50 | public string Text { get; set; } 51 | 52 | /// 53 | /// Gets or sets the base64 encoded byte array. 54 | /// 55 | [Parameter(Position=0, Mandatory=true, ValueFromPipeline=true, ParameterSetName="ByteArray")] 56 | public byte[] ByteArray { get; set; } 57 | 58 | /// 59 | /// Gets or sets the InsertBreakLines switch. 60 | /// 61 | [Parameter()] 62 | public SwitchParameter InsertBreakLines { get; set; } 63 | 64 | private List _bytearray = new List(); 65 | private Base64FormattingOptions _base64Option = Base64FormattingOptions.None; 66 | 67 | protected override void ProcessRecord() 68 | { 69 | if (InsertBreakLines) 70 | { 71 | _base64Option = Base64FormattingOptions.InsertLineBreaks; 72 | } 73 | 74 | if (ParameterSetName.Equals("Text")) 75 | { 76 | var textBytes = Encoding.UTF8.GetBytes(Text); 77 | WriteObject(Convert.ToBase64String(textBytes, _base64Option)); 78 | } 79 | else 80 | { 81 | _bytearray.AddRange(ByteArray); 82 | } 83 | } 84 | 85 | protected override void EndProcessing() 86 | { 87 | if (ParameterSetName.Equals("ByteArray")) 88 | { 89 | WriteObject(Convert.ToBase64String(_bytearray.ToArray(), _base64Option)); 90 | } 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/code/Microsoft.PowerShell.TextUtility.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Library 6 | Microsoft.PowerShell.TextUtility 7 | Microsoft.PowerShell.TextUtility 8 | 1.0.0.0 9 | 1.0.0 10 | 1.0.0 11 | netstandard2.0 12 | true 13 | true 14 | 15 | 16 | 17 | 18 | all 19 | 20 | 21 | all 22 | 23 | 24 | 25 | 26 | 27 | Always 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/code/TestSpellingCommand.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Management.Automation; 8 | 9 | namespace Microsoft.PowerShell.TextUtility 10 | { 11 | [Cmdlet(VerbsDiagnostic.Test, "Spelling")] 12 | [OutputType(typeof(string))] 13 | public sealed class TestSpellingCommand : PSCmdlet 14 | { 15 | /// 16 | /// Gets or sets the text to check spelling. 17 | /// 18 | [Parameter(Position=0, Mandatory=true)] 19 | public string Text { get; set; } 20 | 21 | private HashSet _dictionary; 22 | 23 | protected override void BeginProcessing() 24 | { 25 | _dictionary = new HashSet(); 26 | using (var dictionary = new StreamReader(@"dictionary.txt")) 27 | { 28 | string line; 29 | while ((line = dictionary.ReadLine()) != null) 30 | { 31 | _dictionary.Add(line); 32 | } 33 | } 34 | 35 | // TODO: use .spelling 36 | } 37 | 38 | protected override void ProcessRecord() 39 | { 40 | 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/code/TextTableParser.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Diagnostics; 7 | using System.Management.Automation; 8 | using System.Text.Json; 9 | 10 | namespace TextTableParser 11 | { 12 | public class ColumnInfo { 13 | public int Start; 14 | public int Length; 15 | public int SpaceLength; 16 | } 17 | 18 | public class HeaderField { 19 | public string Name; 20 | public int Start; 21 | public int Length; 22 | } 23 | 24 | public class ObjectPropertyInfo { 25 | public HeaderField[] HeaderFields; 26 | ObjectPropertyInfo(string line, ColumnInfo[] cInfos) 27 | { 28 | HeaderFields = new HeaderField[cInfos.Length]; 29 | for(int i = 0; i < cInfos.Length; i++) 30 | { 31 | HeaderFields[i] = new HeaderField(){ 32 | Name = line.Substring(cInfos[i].Start, cInfos[i].Length).Trim(), 33 | Start = cInfos[i].Start, 34 | Length = cInfos[i].Length 35 | }; 36 | 37 | } 38 | } 39 | } 40 | 41 | [Cmdlet("ConvertFrom","TextTable")] 42 | public class ConvertTextTableCommand : PSCmdlet 43 | { 44 | [Parameter()] 45 | public int MaximumWidth { get; set; } = 200; 46 | 47 | [Parameter()] 48 | public int AnalyzeRowCount { get; set; } = 0; // 0 is all 49 | 50 | [Parameter(ValueFromPipeline=true,Mandatory=true,Position=0)] 51 | [AllowEmptyString()] 52 | public string[] Line { get; set; } 53 | 54 | [Parameter()] 55 | public int Skip { get; set; } = 0; 56 | 57 | [Parameter()] 58 | public SwitchParameter NoHeader { get; set; } 59 | 60 | [Parameter()] 61 | public SwitchParameter AsJson { get; set; } 62 | 63 | [Parameter()] 64 | public int[] ColumnOffset { get; set; } 65 | 66 | [Parameter()] 67 | public SwitchParameter ConvertPropertyValue { get; set; } 68 | 69 | [Parameter()] 70 | public int HeaderLine { get; set; } = 0; // Assume the first line is the header 71 | 72 | [Parameter()] 73 | public string[] TypeName { get; set; } 74 | 75 | private ListLines = new List(); 76 | 77 | private int SkippedLines = 0; 78 | protected override void BeginProcessing() 79 | { 80 | if (NoHeader) 81 | { 82 | HeaderLine = -1; 83 | } 84 | 85 | } 86 | 87 | private int[] SpaceArray; 88 | private string spaceRepresentation; 89 | private bool Analyzed = false; 90 | 91 | protected override void ProcessRecord() 92 | { 93 | if (Line is null) 94 | { 95 | return; 96 | } 97 | 98 | foreach(string _line in Line) 99 | { 100 | 101 | // don't add empty lines 102 | if(string.IsNullOrEmpty(_line)) 103 | { 104 | continue; 105 | } 106 | 107 | // add the line to the list if we've skipped enough lines 108 | if (SkippedLines++ >= Skip) 109 | { 110 | Lines.Add(_line); 111 | } 112 | 113 | if (AnalyzeRowCount == 0) 114 | { 115 | continue; 116 | } 117 | 118 | // We've done the analysis, so just emit the object or json. 119 | if(Analyzed) 120 | { 121 | Emit(_line); 122 | continue; 123 | } 124 | 125 | if (Lines.Count == 0) { continue; } 126 | // We've collected enough lines to analyze 127 | // analyze what we have and then emit them, set the analyzed flag so we will just emit from now on. 128 | if (! Analyzed && Lines.Count > AnalyzeRowCount) 129 | { 130 | AnalyzeLines(Lines); 131 | Analyzed = true; 132 | foreach(string l in Lines) 133 | { 134 | Emit(l); 135 | } 136 | Lines.Clear(); // unneeded 137 | // Calculate the column widths 138 | } 139 | } 140 | } 141 | 142 | protected override void EndProcessing() 143 | { 144 | if (Lines.Count == 0) { return; } 145 | if (!Analyzed) 146 | { 147 | AnalyzeLines(Lines); 148 | foreach(string _line in Lines) 149 | { 150 | Emit(_line); 151 | } 152 | } 153 | } 154 | 155 | private void Emit(string line) 156 | { 157 | if (ColumnInfoList != null && columnHeaders != null) 158 | { 159 | if (AsJson) 160 | { 161 | var jsonOptions = new JsonSerializerOptions(); 162 | jsonOptions.MaxDepth = 1; 163 | WriteObject(GetJson(ColumnInfoList, line, columnHeaders)); 164 | } 165 | else 166 | { 167 | WriteObject(GetPsObject(ColumnInfoList, line, columnHeaders)); 168 | } 169 | } 170 | else 171 | { 172 | WriteError(new ErrorRecord(new Exception("No column info"), "NoColumnInfo", ErrorCategory.InvalidOperation, null)); 173 | } 174 | } 175 | 176 | private List ColumnInfoList { get; set; } 177 | private string[] columnHeaders { get; set; } 178 | 179 | private void AnalyzeLines(List lines) 180 | { 181 | if (lines.Count == 0) 182 | { 183 | return; 184 | } 185 | SpaceArray = AnalyzeColumns(Lines); 186 | spaceRepresentation = GetSpaceRepresentation(Lines.Count, SpaceArray); 187 | if (ColumnOffset != null) 188 | { 189 | ColumnInfoList = GetColumnList(ColumnOffset); 190 | } 191 | else 192 | { 193 | ColumnInfoList = GetColumnList(Lines.Count, SpaceArray); 194 | } 195 | 196 | if (NoHeader) 197 | { 198 | columnHeaders = new string[ColumnInfoList.Count]; 199 | for(int i = 0; i < ColumnInfoList.Count; i++) 200 | { 201 | columnHeaders[i] = string.Format("Property_{0:00}", i+1); 202 | } 203 | } 204 | else 205 | { 206 | columnHeaders = GetHeaderColumns(ColumnInfoList, Lines[HeaderLine]); 207 | Lines.RemoveAt(HeaderLine); 208 | } 209 | } 210 | 211 | private string GetSpaceRepresentation(int count, int[] spaceArray) 212 | { 213 | char[] spaceChars = new char[spaceArray.Length]; 214 | for(int i = 0; i < spaceArray.Length; i++) 215 | { 216 | if (spaceArray[i] == count) 217 | { 218 | spaceChars[i] = 'S'; 219 | } 220 | else 221 | { 222 | spaceChars[i] = ' '; 223 | } 224 | } 225 | return new string(spaceChars); 226 | } 227 | 228 | public PSObject GetPsObject(List cInfos, string line, string[] columnHeaders) 229 | { 230 | PSObject o = new PSObject(); 231 | if (TypeName != null) 232 | { 233 | foreach (string t in TypeName) 234 | { 235 | o.TypeNames.Insert(0, t); 236 | } 237 | } 238 | object[]data = GetObjectColumnData(cInfos, line); 239 | Debug.Assert(data.Length == columnHeaders.Length); 240 | for(int i = 0; i < cInfos.Count; i++) 241 | { 242 | o.Properties.Add(new PSNoteProperty(columnHeaders[i], data[i])); 243 | } 244 | return o; 245 | } 246 | 247 | public string GetJson(List cInfos, string line, string[] columnHeaders) 248 | { 249 | string[]data = GetStringColumnData(cInfos, line); 250 | Debug.Assert(data.Length == columnHeaders.Length); 251 | string[]dataWithHeader = new string[data.Length]; 252 | for(int j = 0; j < data.Length; j++) 253 | { 254 | if (data[j] is string) 255 | { 256 | dataWithHeader[j] = string.Format("\"{0}\": \"{1}\"", columnHeaders[j], JsonEncodedText.Encode(data[j])); 257 | } 258 | else 259 | { 260 | dataWithHeader[j] = string.Format("\"{0}\": \"{1}\"", columnHeaders[j], (JsonEncodedText.Encode((string)data[j]))); 261 | } 262 | } 263 | return string.Format("{{ {0} }}", string.Join(", ", dataWithHeader)); 264 | } 265 | 266 | private object[] GetObjectColumnData(List cInfos, string line) 267 | { 268 | 269 | object[] data = new object[cInfos.Count]; 270 | for(int i = 0; i < cInfos.Count; i++) 271 | { 272 | string value; 273 | if (cInfos[i].Length == -1) // end of line 274 | { 275 | value = line.Substring(cInfos[i].Start).Trim(); 276 | } 277 | else 278 | { 279 | value = line.Substring(cInfos[i].Start, cInfos[i].Length).Trim(); 280 | } 281 | 282 | // If ConvertPropertyValue is specified, try to convert to int, int64, decimal, datetime, or timespan. 283 | if (! ConvertPropertyValue) 284 | { 285 | data[i] = value; 286 | } 287 | else if (LanguagePrimitives.TryConvertTo(value, out int intValue)) 288 | { 289 | data[i] = intValue; 290 | } 291 | else if (LanguagePrimitives.TryConvertTo(value, out Int64 int64Value)) 292 | { 293 | data[i] = int64Value; 294 | } 295 | else if (LanguagePrimitives.TryConvertTo(value, out Decimal decimalValue)) 296 | { 297 | data[i] = decimalValue; 298 | } 299 | else if (LanguagePrimitives.TryConvertTo(value, out DateTime dateTimeValue)) 300 | { 301 | data[i] = dateTimeValue; 302 | } 303 | else if (LanguagePrimitives.TryConvertTo(value, out TimeSpan timeSpanValue)) 304 | { 305 | data[i] = timeSpanValue; 306 | } 307 | else if (LanguagePrimitives.TryConvertTo(string.Format("0:{0}", value), out TimeSpan exTimeSpanValue)) 308 | { 309 | data[i] = exTimeSpanValue; 310 | } 311 | else 312 | { 313 | data[i] = value; 314 | } 315 | } 316 | return data; 317 | } 318 | 319 | // This will return the data in the columns as an array of objects. 320 | // We will try to convert the data to a type that makes sense. 321 | private string[] GetStringColumnData(List cInfos, string line) 322 | { 323 | string[] data = new string[cInfos.Count]; 324 | for(int i = 0; i < cInfos.Count; i++) 325 | { 326 | string value; 327 | if (cInfos[i].Length == -1) // end of line 328 | { 329 | value = line.Substring(cInfos[i].Start).Trim(); 330 | } 331 | else 332 | { 333 | value = line.Substring(cInfos[i].Start, cInfos[i].Length).Trim(); 334 | } 335 | data[i] = value; 336 | 337 | } 338 | return data; 339 | } 340 | 341 | private string[] GetHeaderColumns(List cInfos, string line) 342 | { 343 | string[] columns = new string[cInfos.Count]; 344 | for(int i = 0; i < cInfos.Count; i++) 345 | { 346 | if (cInfos[i].Length == -1) // end of line 347 | { 348 | columns[i] = line.Substring(cInfos[i].Start).Trim().Replace(" ", "_"); 349 | } 350 | else 351 | { 352 | columns[i] = line.Substring(cInfos[i].Start, cInfos[i].Length).Trim().Replace(" ", "_"); 353 | } 354 | } 355 | return columns; 356 | } 357 | 358 | private int GetMaxLength(Listlines) 359 | { 360 | int maximumLength = 0; 361 | foreach(string line in lines) 362 | { 363 | if (line.Length > maximumLength) 364 | { 365 | maximumLength = line.Length; 366 | } 367 | } 368 | return maximumLength; 369 | } 370 | 371 | // Analyze for white space. If we find consistent white space, 372 | // then we can use that to determine the columns. 373 | // If the value in the array element is the same as the number of lines, 374 | // we have a column. 375 | 376 | private int[] AnalyzeColumns(Listlines) 377 | { 378 | int maximumLength = GetMaxLength(lines); 379 | int[] SpaceArray = new int[maximumLength]; 380 | for(int i = 0; i < maximumLength; i++) 381 | { 382 | SpaceArray[i] = 0; 383 | } 384 | 385 | foreach(string line in lines) 386 | { 387 | for(int i = 0; i < line.Length; i++) 388 | { 389 | if(char.IsWhiteSpace(line[i])) 390 | { 391 | SpaceArray[i] += 1; 392 | } 393 | } 394 | } 395 | return SpaceArray; 396 | } 397 | 398 | private List GetColumnList(int[]StartColumns) 399 | { 400 | List ColumnInfoList = new List(); 401 | for(int i = 0; i < StartColumns.Length; i++) 402 | { 403 | int length; 404 | try 405 | { 406 | length = StartColumns[i+1] - StartColumns[i]; 407 | } 408 | catch 409 | { 410 | length = -1; 411 | } 412 | ColumnInfoList.Add(new ColumnInfo() { Start = StartColumns[i], Length = length, SpaceLength = 0 }); 413 | 414 | } 415 | return ColumnInfoList; 416 | } 417 | 418 | // Get the column list from the space array. 419 | private List GetColumnList(int count, int[]SpaceArray) 420 | { 421 | List ColumnInfoList = new List(); 422 | for(int i = 0; i < SpaceArray.Length; i++) { 423 | ColumnInfoList.Add( 424 | new ColumnInfo() { Start = i, Length = 0, SpaceLength = 0 } 425 | ); 426 | // Chew up the spaces 427 | while (i < SpaceArray.Length && SpaceArray[i] == count) 428 | { 429 | ColumnInfoList[ColumnInfoList.Count - 1].SpaceLength++; 430 | ColumnInfoList[ColumnInfoList.Count - 1].Length++; 431 | i++; 432 | } 433 | 434 | // chew up the non spaces or end of line 435 | while(i < SpaceArray.Length && SpaceArray[i] != count) 436 | { 437 | ColumnInfoList[ColumnInfoList.Count - 1].Length++; 438 | i++; 439 | } 440 | 441 | int totalLength = ColumnInfoList[ColumnInfoList.Count-1].Length + ColumnInfoList[ColumnInfoList.Count-1].Start; 442 | if (totalLength >= SpaceArray.Length) 443 | { 444 | ColumnInfoList[ColumnInfoList.Count - 1].Length = -1; 445 | } 446 | 447 | i--; 448 | } 449 | 450 | return ColumnInfoList; 451 | } 452 | } 453 | } 454 | -------------------------------------------------------------------------------- /test/Base64.tests.ps1: -------------------------------------------------------------------------------- 1 | ## Copyright (c) Microsoft Corporation. 2 | ## Licensed under the MIT License. 3 | 4 | Describe 'Base64 cmdlet tests' { 5 | BeforeAll { 6 | $testString = 'Hello World!' 7 | $testBase64 = 'SGVsbG8gV29ybGQh' 8 | $longString = $testString * 10 9 | $longBase64 = "SGVsbG8gV29ybGQhSGVsbG8gV29ybGQhSGVsbG8gV29ybGQhSGVsbG8gV29ybGQhSGVsbG8gV29y`r`nbGQhSGVsbG8gV29ybGQhSGVsbG8gV29ybGQhSGVsbG8gV29ybGQhSGVsbG8gV29ybGQhSGVsbG8g`r`nV29ybGQh" 10 | } 11 | 12 | It 'ConvertTo-Base64 will accept text input from parameter' { 13 | ConvertTo-Base64 -Text $testString | Should -BeExactly $testBase64 14 | } 15 | 16 | It 'ConvertTo-Base64 will accept text input from positional parameter' { 17 | ConvertTo-Base64 $testString | Should -BeExactly $testBase64 18 | } 19 | 20 | It 'ConvertTo-Base64 will accept text input from pipeline' { 21 | $testString | ConvertTo-Base64 | Should -BeExactly $testBase64 22 | } 23 | 24 | It 'ConvertTo-Base64 will accept text and insert breaklines' { 25 | $longString | ConvertTo-Base64 -InsertBreakLines | Should -BeExactly $longBase64 26 | } 27 | 28 | It 'ConvertTo-Base64 will accept byte array' { 29 | [System.Text.Encoding]::Utf8.GetBytes($testString) | ConvertTo-Base64 | Should -BeExactly $testBase64 30 | } 31 | 32 | It 'ConvertTo-Base64 will accept byte array and insert break lines' { 33 | [System.Text.Encoding]::Utf8.GetBytes($longString) | ConvertTo-Base64 -InsertBreakLines | Should -BeExactly $longBase64 34 | } 35 | 36 | It 'ConvertFrom-Base64 will accept encoded input from parameter' { 37 | ConvertFrom-Base64 -EncodedText $testBase64 | Should -BeExactly $testString 38 | } 39 | 40 | It 'ConvertFrom-Base64 will accept encoded input from positional parameter' { 41 | ConvertFrom-Base64 $testBase64 | Should -BeExactly $testString 42 | } 43 | 44 | It 'ConvertFrom-Base64 will accept encoded input form pipeline' { 45 | $testBase64 | ConvertFrom-Base64 | Should -BeExactly $testString 46 | } 47 | 48 | It 'ConvertFrom-Base64 -AsByteArray returns byte array' { 49 | ($testBase64 | ConvertFrom-Base64 -AsByteArray) | Should -BeExactly ([System.Text.Encoding]::Utf8.GetBytes($testString)) 50 | } 51 | 52 | It 'ConvertFrom-Base64 will accept text with breaks' { 53 | $longBase64 | ConvertFrom-Base64 | Should -Be $longString 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /test/CompareText.tests.ps1: -------------------------------------------------------------------------------- 1 | ## Copyright (c) Microsoft Corporation. 2 | ## Licensed under the MIT License. 3 | 4 | Describe 'Compare-Text tests' { 5 | BeforeAll { 6 | $currentOutputRendering = $PSStyle.OutputRendering 7 | $PSStyle.OutputRendering = 'Ansi' 8 | $leftText = @("This is some", "example text.") -join [Environment]::NewLine 9 | $rightText = @(" This is other", "example text used!") -join [Environment]::NewLine 10 | $expectedInline = @( 11 | "" 12 | "``e[0;1;32m ``e[0mThis is ``e[1;9;31msome``e[0m``e[0;1;32mother``e[0m" 13 | "example text``e[1;9;31m.``e[0m``e[0;1;32m used!``e[0m" 14 | "" 15 | ) 16 | $expectedSideBySide = @( 17 | "" 18 | "``e[0m1 | ``e[0mThis is ``e[1;9;31msome``e[0m``e[0m ``e[0m | ``e[0;1;32m ``e[0mThis is ``e[0;1;32mother``e…" 19 | "``e[0m2 | ``e[0mexample text``e[1;9;31m.``e[0m``e[0m | ``e[0mexample text``e[0;1;32m…" 20 | "``e[0m" 21 | "" 22 | ) 23 | # this reset text was added in 7.3.0, we need to remove it from the output so the tests can pass on different ps versions. 24 | $inlineResetText = "``e[0;1;32m``e[0m``e[1;9;31m``e[0m``e[0;1;32m``e[0m" 25 | $sideBySideResetText = "``e[0m``e[0m``e[1;9;31m``e[0m``e[0m``e[0m``e[0;1;32m``e[0m``e[0;1;32m" 26 | } 27 | 28 | AfterAll { 29 | $PSStyle.OutputRendering = $currentOutputRendering 30 | } 31 | 32 | # These tests convert the emitted escape sequences to their literal representation 33 | # to ease debugging. Also, we use Out-String -Stream to get the output as a collection which Pester 4.10.1 can handle. 34 | It 'Compare with no specified view uses inline' { 35 | $out = Compare-Text -LeftText $leftText -RightText $rightText | Out-String -Stream | Foreach-Object {"$_".Replace("`e","``e").Replace($inlineResetText, "")} 36 | $out | Should -Be $expectedInline 37 | } 38 | 39 | It 'Compare with no specified view uses inline and positional parameters' { 40 | $out = Compare-Text $leftText $rightText | Out-String -Stream | Foreach-Object {"$_".Replace("`e","``e").Replace($inlineResetText, "")} 41 | $out | Should -Be $expectedInline 42 | } 43 | 44 | It 'Compare with inline works' { 45 | $out = Compare-Text $leftText $rightText -View Inline | Out-String -Stream | Foreach-Object {"$_".Replace("`e","``e").Replace($inlineResetText, "")} 46 | $out | Should -Be $expectedInline 47 | } 48 | 49 | It 'Compare with sidebyside works' { 50 | Set-ItResult -Pending -Because "https://github.com/PowerShell/TextUtility/issues/30" 51 | $out = Compare-Text $leftText $rightText -View SideBySide | Out-String -Stream | Foreach-Object {"$_".Replace("`e","``e").Replace($sideBySideResetText, "")} 52 | $out | Should -Be $expectedSideBySide 53 | } 54 | 55 | 56 | Context "PlainText comparison" { 57 | BeforeAll { 58 | $currentRendering = $PSStyle.OutputRendering 59 | $PSStyle.OutputRendering = 'PlainText' 60 | } 61 | 62 | AfterAll { 63 | $PSStyle.OutputRendering = $currentRendering 64 | } 65 | 66 | It "Default view should have no escape characters" { 67 | (Compare-Text $leftText $rightText | Out-String -Stream) | Should -Not -Match "`e" 68 | } 69 | 70 | It "SideBySide view should have no escape characters" { 71 | Set-ItResult -Pending -Because "https://github.com/PowerShell/TextUtility/issues/30" 72 | (Compare-Text $leftText $rightText -View SideBySide | Out-String -Stream) | Should -Not -Match "`e" 73 | } 74 | 75 | } 76 | } -------------------------------------------------------------------------------- /test/TextTableParser.Tests.ps1: -------------------------------------------------------------------------------- 1 | Describe "Test text table parser" { 2 | BeforeAll { 3 | $cmdletName = "ConvertFrom-TextTable" 4 | $testCases = @{ 5 | FileName = "attrib.01.txt" 6 | convertArgs = @{ NoHeader = $true } 7 | Rows = 12 8 | Results = @{Row = 0; Property_01 = "A";Property_02 = "C:\windows\system32\mmgaserver.exe"}, 9 | @{Row = -1; Property_01 = "A";Property_02 = "C:\windows\system32\msdtc.exe"} 10 | }, 11 | @{ 12 | FileName = "df.01.txt" 13 | convertArgs = @{} 14 | Rows = 10 15 | Results = @{ Row = 0; "Filesystem" = "/dev/disk4s1s1"; "512-blocks" = "3907805752"; "Used" = "17463888"; "Available" = "1387159800"; "Capacity" = "2%"; "iused" = "349475"; "ifree" = "4291443272"; "%iused" = "0%"; "Mounted_on" = "/" }, 16 | @{ Row = 1; "Filesystem" = "devfs"; "512-blocks" = "427"; "Used" = "427"; "Available" = "0"; "Capacity" = "100%"; "iused" = "739"; "ifree" = "0"; "%iused" = "100%"; "Mounted_on" = "/dev" } 17 | }, 18 | @{ 19 | FileName = "docker.01.txt" 20 | convertArgs = @{} 21 | Rows = 8 22 | Results = @{ ROW = 0; "REPOSITORY" = "docker101tutorial"; "TAG" = "latest"; "IMAGE_ID" = "234e26cd95c2"; "CREATED" = "5 weeks ago"; "SIZE" = "28.9MB" }, 23 | @{ Row = 3; "REPOSITORY" = "alpine/git"; "TAG" = "latest"; "IMAGE_ID" = "692618a0d74d"; "CREATED" = "6 weeks ago"; "SIZE" = "43.4MB" } 24 | }, 25 | @{ 26 | FileName = "docker.02.txt" 27 | convertArgs = @{} 28 | Rows = 25 29 | Results = @{ ROW = 0; "NAME" = "centos/powershell"; "DESCRIPTION" = "PowerShell is a cross-platform (Windows, Lin`u{2026}"; "STARS" = "8"; "OFFICIAL" = ""; "AUTOMATED" = "[OK]" }, 30 | @{ ROW = 20; "NAME" = "powershellduzero/api"; "DESCRIPTION" = ""; "STARS" = "0"; "OFFICIAL" = ""; "AUTOMATED" = "" } 31 | }, 32 | @{ 33 | FileName = "docker.03.txt" 34 | convertArgs = @{} 35 | Rows = 25 36 | Results = @{ ROW = 22; "NAME" = "zoilus/powershell"; "DESCRIPTION" = ""; "STARS" = "0"; "OFFICIAL" = ""; "AUTOMATED" = "" }, 37 | @{ ROW = 23; "NAME" = "ephesoft/powershell.git"; "DESCRIPTION" = "Powershell image with Git pre-installed"; "STARS" = "0"; "OFFICIAL" = ""; "AUTOMATED" = "" } 38 | }, 39 | @{ 40 | FileName = "docker.04.txt" 41 | convertArgs = @{} 42 | Rows = 1 43 | Results = @(@{ ROW = 0; "DRIVER" = "local"; "VOLUME_NAME" = "6bf5c897a2cdcf0bfe5da45a795fa7fe94032f79b98d2f63563578ed40d0f0c6" }) 44 | }, 45 | @{ 46 | FileName = "getmac.01.txt" 47 | convertArgs = @{} 48 | Rows = 6 49 | Results = @{ ROW = 3; "Physical_Address" = "0C-C4-7A-28-C7-13"; "Transport_Name" = "\Device\Tcpip_{8234FC65-751E-4B56-AB8A-0758A4C18889}" }, 50 | @{ ROW = 4; "Physical_Address" = "0C-C4-7A-28-C7-12"; "Transport_Name" = "N/A" } 51 | }, 52 | @{ 53 | FileName = "kmutil.01.txt" 54 | convertArgs = @{} 55 | Rows = 30 56 | Results = @{ ROW = 0; "Index" = "1"; "Refs" = "161"; "Address" = "0"; "Size" = "0"; "Wired" = "0"; "Name_(Version)_UUID_" = "com.apple.kpi.bsd (22.3.0) 10E5D254-4A37-3A2A-B560-E6956A093ADE `u{003C}`u{003E}" }, 57 | @{ ROW = 1; "Index" = "2"; "Refs" = "12"; "Address" = "0"; "Size" = "0"; "Wired" = "0"; "Name_(Version)_UUID_" = "com.apple.kpi.dsep (22.3.0) 10E5D254-4A37-3A2A-B560-E6956A093ADE `u{003C}`u{003E}" } 58 | }, 59 | @{ 60 | FileName = "ls.01.txt" 61 | convertArgs = @{skip = 1; NoHeader = $true } 62 | Rows = 5 63 | Results = @{ ROW = 0; "Property_01" = "-rw-r--r--"; "Property_02" = "1"; "Property_03" = "james"; "Property_04" = "staff"; "Property_05" = "2687"; "Property_06" = "Oct"; "Property_07" = "12"; "Property_08" = "16:58"; "Property_09" = "NativeTableParser.deps.json" }, 64 | @{ ROW = 3; "Property_01" = "-rwxr--r--"; "Property_02" = "1"; "Property_03" = "james"; "Property_04" = "staff"; "Property_05" = "354304"; "Property_06" = "Mar"; "Property_07" = "7"; "Property_08" = "2019"; "Property_09" = "System.Management.Automation.dll" } 65 | }, 66 | @{ 67 | FileName = "ls.02.txt" 68 | convertArgs = @{ skip = 1; NoHeader = $true } 69 | Rows = 5 70 | Results = @(@{ ROW = 4; "Property_01" = "-rwxr--r--"; "Property_02" = "1"; "Property_03" = "james"; "Property_04" = "457864"; "Property_05" = "Aug"; "Property_06" = "19"; "Property_07" = "12:49"; "Property_08" = "System.Text.Json.dll" }) 71 | }, 72 | @{ 73 | FileName = "ls.03.txt" 74 | convertArgs = @{ skip = 1; NoHeader = $true } 75 | Rows = 5 76 | Results = @{ ROW = 1; "Property_01" = "-rw-r--r--"; "Property_02" = "1"; "Property_03" = "12288"; "Property_04" = "Oct"; "Property_05" = "12"; "Property_06" = "16:58"; "Property_07" = "NativeTableParser.dll" }, 77 | @{ ROW = 2; "Property_01" = "-rw-r--r--"; "Property_02" = "1"; "Property_03" = "14512"; "Property_04" = "Oct"; "Property_05" = "12"; "Property_06" = "16:58"; "Property_07" = "NativeTableParser.pdb" } 78 | }, 79 | @{ 80 | FileName = "ps.01.txt" 81 | convertArgs = @{ } 82 | Rows = 6 83 | Results = @{ ROW = 0; "PID" = "2596"; "TTY" = "ttys000"; "TIME" = "1:59.45"; "CMD" = "/usr/local/bin/pwsh -l" }, 84 | @{ ROW = 1; "PID" = "2601"; "TTY" = "ttys001"; "TIME" = "0:44.13"; "CMD" = "/usr/local/bin/pwsh -l" }, 85 | @{ ROW = 2; "PID" = "2661"; "TTY" = "ttys002"; "TIME" = "0:23.53"; "CMD" = "/usr/local/bin/pwsh" } 86 | }, 87 | @{ 88 | FileName = "ps.02.txt" 89 | convertArgs = @{ } 90 | Rows = 88 91 | Results = @{ ROW = 82; "UID" = "0"; "PID" = "69835"; "PPID" = "2596"; "C" = "0"; "STIME" = "8:25AM"; "TTY" = "ttys000"; "TIME" = "0:00.01"; "CMD" = "/bin/ps -ef" }, 92 | @{ ROW = 85; "UID" = "501"; "PID" = "2669"; "PPID" = "2658"; "C" = "0"; "STIME" = "9:45AM"; "TTY" = "ttys003"; "TIME" = "0:23.04"; "CMD" = "/usr/local/bin/pwsh" }, 93 | @{ ROW = 87; "UID" = "501"; "PID" = "2676"; "PPID" = "2658"; "C" = "0"; "STIME" = "9:45AM"; "TTY" = "ttys005"; "TIME" = "0:23.16"; "CMD" = "/usr/local/bin/pwsh" } 94 | }, 95 | @{ 96 | FileName = "ps.03.txt" 97 | convertArgs = @{ } 98 | Rows = 6 99 | Results = @{ ROW = 0; "UID" = "501"; "PID" = "2596"; "PPID" = "2587"; "F" = "4006"; "CPU" = "0"; "PRI" = "33"; "NI" = "0"; "SZ" = "39662748"; "RSS" = "167544"; "WCHAN" = "-"; "S" = "S`u{002B}"; "ADDR" = "0"; "TTY" = "ttys000"; "TIME" = "2:01.35"; "CMD" = "/usr/local/bin/pwsh -l" }, 100 | @{ ROW = 5; "UID" = "501"; "PID" = "2676"; "PPID" = "2658"; "F" = "4006"; "CPU" = "0"; "PRI" = "33"; "NI" = "0"; "SZ" = "39658344"; "RSS" = "136596"; "WCHAN" = "-"; "S" = "Ss`u{002B}"; "ADDR" = "0"; "TTY" = "ttys005"; "TIME" = "0:23.17"; "CMD" = "/usr/local/bin/pwsh" } 101 | 102 | }, 103 | @{ 104 | FileName = "ps.04.txt" 105 | convertArgs = @{ } 106 | Rows = 785 107 | Results = @{ ROW = 782; "PID" = "2676"; "TTY" = "ttys005"; "TIME" = "0:27.57"; "CMD" = "pwsh" }, 108 | @{ ROW = 783; "PID" = "94197"; "TTY" = "ttys006"; "TIME" = "1:07.57"; "CMD" = "pwsh" }, 109 | @{ ROW = 784; "PID" = "94200"; "TTY" = "ttys007"; "TIME" = "0:05.13"; "CMD" = "pwsh" } 110 | }, 111 | @{ 112 | FileName = "tasklist.01.txt" 113 | convertArgs = @{} 114 | Rows = 46 115 | Results = @{ ROW = 0; "Image_Name" = "========================="; "PID" = "========"; "Session_Name" = "================"; "Session#" = "==========="; "Mem_Usage" = "============" }, 116 | @{ ROW = 1; "Image_Name" = "System Idle Process"; "PID" = "0"; "Session_Name" = "Services"; "Session#" = "0"; "Mem_Usage" = "8 K" }, 117 | @{ ROW = 2; "Image_Name" = "System"; "PID" = "4"; "Session_Name" = "Services"; "Session#" = "0"; "Mem_Usage" = "8,240 K" } 118 | }, 119 | @{ 120 | FileName = "tasklist.02.txt" 121 | convertArgs = @{} 122 | Rows = 39 123 | Results = @{ ROW = 14; "Image_Name" = "svchost.exe"; "PID" = "1364"; "Session_Name" = "Services"; "Session#" = "0"; "Mem_Usage" = "24,896 K" }, 124 | @{ ROW = 15; "Image_Name" = "svchost.exe"; "PID" = "1412"; "Session_Name" = "Services"; "Session#" = "0"; "Mem_Usage" = "18,576 K" } 125 | }, 126 | @{ 127 | FileName = "who.01.txt" 128 | convertArgs = @{ NoHeader = $true } 129 | Rows = 6 130 | Results = @{ ROW = 0; "Property_01" = "reboot"; "Property_02" = "~"; "Property_03" = "Sep"; "Property_04" = "14"; "Property_05" = "10:10"; "Property_06" = "00:04"; "Property_07" = "1" }, 131 | @{ ROW = 4; "Property_01" = "james"; "Property_02" = "ttys002"; "Property_03" = "Oct"; "Property_04" = "5"; "Property_05" = "16:36"; "Property_06" = "."; "Property_07" = "90609`tterm=0 exit=0" }, 132 | @{ ROW = 5; "Property_01" = "james"; "Property_02" = "ttys006"; "Property_03" = "Oct"; "Property_04" = "11"; "Property_05" = "15:41"; "Property_06" = "."; "Property_07" = "25351`tterm=0 exit=0" } 133 | } 134 | 135 | } 136 | 137 | Context "Test JSON output" { 138 | 139 | It "Should create proper json from '' " -testCases $testCases { 140 | param ($FileName, $convertArgs, $rows, $Results) 141 | $Path = [io.path]::Combine($PSScriptRoot, "assets", $FileName) 142 | # do not alter convertArgs directly as it is a reference rather than a copy 143 | $localArgs = $convertArgs.Clone() 144 | $localArgs['AsJson'] = $true 145 | { Get-Content $Path | ConvertFrom-TextTable @localArgs | ConvertFrom-Json -ErrorAction Stop } | Should -Not -Throw 146 | $result = Get-Content $Path | ConvertFrom-TextTable @localArgs | ConvertFrom-Json -ErrorAction Ignore 147 | $result | Should -Not -BeNullOrEmpty 148 | $result.Count | Should -Be $Rows 149 | foreach ( $r in $results ) { 150 | $rObject = $result[$r.Row] 151 | foreach ( $k in $r.Keys.Where({$_ -ne "Row"}) ) { 152 | $rObject."$k" | Should -Be $r."$k" 153 | } 154 | } 155 | } 156 | } 157 | 158 | Context "Test PSObject output" { 159 | It "Should create proper psobject from '' " -testCases $testCases { 160 | param ($FileName, $convertArgs, $rows, $Results ) 161 | $Path = [io.path]::Combine($PSScriptRoot, "assets", $FileName) 162 | $result = Get-Content $Path | ConvertFrom-TextTable @convertArgs 163 | $result | Should -BeOfType System.Management.Automation.PSObject 164 | $result.Count | Should -Be $Rows 165 | foreach ( $r in $results ) { 166 | $rObject = $result[$r.Row] 167 | foreach ( $k in $r.Keys.Where({$_ -ne "Row"}) ) { 168 | $rObject."$k" | Should -Be $r."$k" 169 | } 170 | } 171 | } 172 | } 173 | 174 | Context "Column offset use" { 175 | BeforeAll { 176 | $expectedResult = @( 177 | @{ Name = "Property_01"; Value = "S1234" } 178 | @{ Name = "Property_02"; Value = "56789012" } 179 | @{ Name = "Property_03"; Value = "3456789012" } 180 | @{ Name = "Property_04"; Value = "34567890123456789" } 181 | @{ Name = "Property_05"; Value = "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" } 182 | ) 183 | $testFile = [io.path]::Combine($PSScriptRoot, "assets", "columns.01.txt") 184 | $result = Get-Content $testFile | ConvertFrom-TextTable -ColumnOffset 0,5,13,23,40 -noheader 185 | $line = 0 186 | $testCases = $result.ForEach({@{Result = $_; Line = $line++}}) 187 | } 188 | 189 | It "Specifying column offset breaks string properly for Line: ''" -TestCases $testCases { 190 | param ( $Result, $Line ) 191 | foreach ($expected in $expectedResult) { 192 | $Result.$($expected.Name) | Should -Be $expected.Value 193 | } 194 | } 195 | 196 | } 197 | 198 | 199 | } 200 | -------------------------------------------------------------------------------- /test/assets/attrib.01.txt: -------------------------------------------------------------------------------- 1 | A C:\windows\system32\mmgaserver.exe 2 | A C:\windows\system32\mobsync.exe 3 | A C:\windows\system32\mountvol.exe 4 | A C:\windows\system32\mpnotify.exe 5 | C:\windows\system32\MpSigStub.exe 6 | A C:\windows\system32\MRINFO.EXE 7 | A C:\windows\system32\MRT-KB890830.exe 8 | A C:\windows\system32\MRT.exe 9 | A C:\windows\system32\MSchedExe.exe 10 | A C:\windows\system32\msconfig.exe 11 | A C:\windows\system32\msdt.exe 12 | A C:\windows\system32\msdtc.exe 13 | -------------------------------------------------------------------------------- /test/assets/columns.01.txt: -------------------------------------------------------------------------------- 1 | S123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 2 | S123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 3 | S123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 4 | S123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 5 | S123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 6 | S123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 7 | S123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 8 | S123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 9 | S123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 10 | S123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 11 | S123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 12 | -------------------------------------------------------------------------------- /test/assets/df.01.txt: -------------------------------------------------------------------------------- 1 | Filesystem 512-blocks Used Available Capacity iused ifree %iused Mounted on 2 | /dev/disk4s1s1 3907805752 17463888 1387159800 2% 349475 4291443272 0% / 3 | devfs 427 427 0 100% 739 0 100% /dev 4 | /dev/disk4s3 3907805752 3606904 1387159800 1% 3084 6935799000 0% /System/Volumes/Preboot 5 | /dev/disk4s5 3907805752 40 1387159800 1% 0 6935799000 0% /System/Volumes/VM 6 | /dev/disk4s6 3907805752 16864 1387159800 1% 20 6935799000 0% /System/Volumes/Update 7 | /dev/disk4s2 3907805752 2496758616 1387159800 65% 5089355 6935799000 0% /System/Volumes/Data 8 | map auto_home 0 0 0 100% 0 0 100% /System/Volumes/Data/home 9 | /dev/disk5s1 7812714496 3045995928 4765770992 39% 2347862 23828854960 0% /Volumes/Sabrent 10 | /dev/disk8s1 976735232 555696128 421039104 57% 2170688 1644684 57% /Volumes/Samsung500 11 | /dev/disk7s2 3906619488 3649692040 256341328 94% 3760967 1281706640 0% /Volumes/TOSHIBA EXT 12 | -------------------------------------------------------------------------------- /test/assets/docker.01.txt: -------------------------------------------------------------------------------- 1 | REPOSITORY TAG IMAGE ID CREATED SIZE 2 | docker101tutorial latest 234e26cd95c2 5 weeks ago 28.9MB 3 | mcr.microsoft.com/powershell preview-7.3-mariner-2.0 4e9617ada198 5 weeks ago 235MB 4 | mcr.microsoft.com/powershell latest 4bcdf53ee67b 5 weeks ago 339MB 5 | alpine/git latest 692618a0d74d 6 weeks ago 43.4MB 6 | mcr.microsoft.com/mssql/server 2022-latest 97a21961f76d 7 weeks ago 1.6GB 7 | mcr.microsoft.com/powershell/test-deps ubi-8.4 02214dbfb621 2 months ago 640MB 8 | alpine latest 9c6f07244728 2 months ago 5.54MB 9 | mcr.microsoft.com/mssql/server 2019-latest e3afdc6d8e5c 2 months ago 1.47GB 10 | -------------------------------------------------------------------------------- /test/assets/docker.02.txt: -------------------------------------------------------------------------------- 1 | NAME DESCRIPTION STARS OFFICIAL AUTOMATED 2 | centos/powershell PowerShell is a cross-platform (Windows, Lin… 8 [OK] 3 | quickbreach/powershell-ntlm Read more https://blog.quickbreach.io/ps-rem… 3 [OK] 4 | rahuldevdockerservice/powershellscriptrunner run PowerShell script in docker 3 5 | tylerl0706/powershell-code-server Coder.com's code-server, PowerShell, and the… 2 6 | pshorg/powershellcommunity PowerShell for every system! Community Imag… 2 7 | fxinnovation/powershell Alpine Linux based powershell image 1 8 | demisto/powershell 1 9 | scrthq/powershell Ubuntu 18.04 containers (pwsh & pwsh-preview… 1 10 | truecharts/powershelluniversal 0 11 | joeltimothyoh/powershell PowerShell on Docker with tools, based on m… 0 12 | mbiregistry/powershell 0 13 | franciscogamino/powershell72 0 14 | clowa/powershell-core Cross platform docker image of powershell co… 0 15 | devtestdemisto/powershell-ubuntu 0 16 | demisto/powershell-ubuntu 0 17 | demisto/powershell-core 0 18 | relaysh/powershell-step-run Relay step for running PowerShell script 0 19 | powershellduzero/github_repo Listing site for my GitHub Repositories 0 20 | devtestdemisto/powershell 0 21 | dispatchframework/powershell-base 0 22 | powershellduzero/api 0 23 | centeredge/powershell.git Linux image with Powershell and Git available 0 24 | zoilus/powershell 0 25 | ephesoft/powershell.git Powershell image with Git pre-installed 0 26 | fxinnovation/powershell-build 0 27 | -------------------------------------------------------------------------------- /test/assets/docker.03.txt: -------------------------------------------------------------------------------- 1 | NAME DESCRIPTION STARS OFFICIAL AUTOMATED 2 | centos/powershell PowerShell is a cross-platform (Windows, Linux and OS X) automation and configuration tool/framework 8 [OK] 3 | quickbreach/powershell-ntlm Read more https://blog.quickbreach.io/ps-remote-from-linux-to-windows/ 3 [OK] 4 | rahuldevdockerservice/powershellscriptrunner run PowerShell script in docker 3 5 | tylerl0706/powershell-code-server Coder.com's code-server, PowerShell, and the PowerShell extension for vscode 2 6 | pshorg/powershellcommunity PowerShell for every system! Community Images! 2 7 | fxinnovation/powershell Alpine Linux based powershell image 1 8 | demisto/powershell 1 9 | scrthq/powershell Ubuntu 18.04 containers (pwsh & pwsh-preview) for PowerShell module building and testing. 1 10 | truecharts/powershelluniversal 0 11 | joeltimothyoh/powershell PowerShell on Docker with tools, based on mcr.microsoft.com/powershell. 🐳 0 12 | mbiregistry/powershell 0 13 | franciscogamino/powershell72 0 14 | clowa/powershell-core Cross platform docker image of powershell core 0 15 | devtestdemisto/powershell-ubuntu 0 16 | demisto/powershell-ubuntu 0 17 | demisto/powershell-core 0 18 | relaysh/powershell-step-run Relay step for running PowerShell script 0 19 | powershellduzero/github_repo Listing site for my GitHub Repositories 0 20 | devtestdemisto/powershell 0 21 | dispatchframework/powershell-base 0 22 | powershellduzero/api 0 23 | centeredge/powershell.git Linux image with Powershell and Git available 0 24 | zoilus/powershell 0 25 | ephesoft/powershell.git Powershell image with Git pre-installed 0 26 | fxinnovation/powershell-build 0 27 | -------------------------------------------------------------------------------- /test/assets/docker.04.txt: -------------------------------------------------------------------------------- 1 | DRIVER VOLUME NAME 2 | local 6bf5c897a2cdcf0bfe5da45a795fa7fe94032f79b98d2f63563578ed40d0f0c6 3 | -------------------------------------------------------------------------------- /test/assets/getmac.01.txt: -------------------------------------------------------------------------------- 1 | 2 | Physical Address Transport Name 3 | =================== ========================================================== 4 | 0C-C4-7A-28-C7-12 \Device\Tcpip_{E18CCFE3-A60F-48CB-B223-3F38DED8A124} 5 | 00-25-90-10-83-F5 \Device\Tcpip_{C16BBA38-CFD1-4FE5-9143-064095F5268F} 6 | 0C-C4-7A-28-C7-13 \Device\Tcpip_{8234FC65-751E-4B56-AB8A-0758A4C18889} 7 | 0C-C4-7A-28-C7-12 N/A 8 | 0C-C4-7A-28-C7-13 Media disconnected 9 | -------------------------------------------------------------------------------- /test/assets/kmutil.01.txt: -------------------------------------------------------------------------------- 1 | Index Refs Address Size Wired Name (Version) UUID 2 | 1 161 0 0 0 com.apple.kpi.bsd (22.3.0) 10E5D254-4A37-3A2A-B560-E6956A093ADE <> 3 | 2 12 0 0 0 com.apple.kpi.dsep (22.3.0) 10E5D254-4A37-3A2A-B560-E6956A093ADE <> 4 | 3 206 0 0 0 com.apple.kpi.iokit (22.3.0) 10E5D254-4A37-3A2A-B560-E6956A093ADE <> 5 | 4 0 0 0 0 com.apple.kpi.kasan (22.3.0) 10E5D254-4A37-3A2A-B560-E6956A093ADE <> 6 | 5 0 0 0 0 com.apple.kpi.kcov (22.3.0) 10E5D254-4A37-3A2A-B560-E6956A093ADE <> 7 | 6 212 0 0 0 com.apple.kpi.libkern (22.3.0) 10E5D254-4A37-3A2A-B560-E6956A093ADE <> 8 | 7 190 0 0 0 com.apple.kpi.mach (22.3.0) 10E5D254-4A37-3A2A-B560-E6956A093ADE <> 9 | 8 128 0 0 0 com.apple.kpi.private (22.3.0) 10E5D254-4A37-3A2A-B560-E6956A093ADE <> 10 | 9 124 0 0 0 com.apple.kpi.unsupported (22.3.0) 10E5D254-4A37-3A2A-B560-E6956A093ADE <> 11 | 10 16 0xffffff800367b000 0x78ff0 0x78ff0 com.apple.kec.corecrypto (12.0) CADEE2DB-DF62-3630-A9F9-BC8B75D43579 <9 8 7 6 3 1> 12 | 11 0 0xffffff8001812000 0x3000 0x3000 com.apple.kec.AppleEncryptedArchive (1) 801B530A-4BDE-3DA7-A4EB-595E19C2183F <10 8 7 6> 13 | 12 0 0xffffff8001d23000 0x1ffd 0x1ffd com.apple.kec.Compression (1) AAD85675-9300-3DD1-A6EE-DA2188B031A6 <10 8 7 6> 14 | 207 0 0xffffff7f95ff2000 0x9ffc 0x9ffc com.apple.driver.AppleBridgeAudioController (300.10) 747999A0-EEDE-3055-9F27-45AAE351615D <17 9 8 7 6 3 1> 15 | 208 0 0xffffff7f8d72b000 0x2ffb 0x2ffb com.apple.kext.AMDRadeonX6000HWServices (4.0.9) 18243619-48C2-3C79-A855-1845FF65D0F1 <147 17 16 9 7 6 3 1> 16 | 209 0 0xffffff7f80fb5000 0x2ff8 0x2ff8 com.apple.kext.AMDRadeonServiceManager (4.0.9) 3376CF7B-83E6-39D4-BC79-1166F3D023C4 <17 6 3 1> 17 | 210 0 0xffffff7f8d264000 0x171000 0x171000 com.apple.kext.AMDRadeonX6000 (4.0.9) 32106E48-FADE-38FC-A544-A410B04DE09E <153 147 97 17 9 7 6 3 1> 18 | 211 0 0xffffff7f900ec000 0x3ab000 0x3ab000 com.apple.kext.AMDRadeonX6200HWLibs (1.0) 5C49C020-89C4-3C65-8241-C24606BB8721 <17 7 6 3 1> 19 | 212 0 0xffffff7f95fcf000 0x3000 0x3000 com.apple.driver.AppleUpstreamUserClient (3.6.9) D87ECE3E-9289-3365-92B3-447D3CE3CF60 <147 17 16 9 7 6 3 1> 20 | 213 0 0xffffff8001841000 0xffd 0xffd com.apple.driver.AppleHIDALSService (1) 3075C57F-90CA-3F66-A7D9-CE089F9B800A <25 6 3> 21 | 214 0 0xffffff7f965e4000 0x8000 0x8000 com.apple.filesystems.autofs (3.0) CF00080B-43BD-3228-B53D-BE5A3E0DCC84 <188 9 8 7 6 3 2 1> 22 | 215 0 0xffffff7f95fde000 0x3000 0x3000 com.apple.driver.AudioAUUC (1.70) 405B4B39-337C-3D86-945F-EF423DB76751 <200 147 17 16 9 7 6 3 1> 23 | 216 1 0xffffff7f96320000 0x6000 0x6000 com.apple.driver.X86PlatformShim (1.0.0) E5997FC7-5A3F-389B-94A3-71E4363D3602 <158 140 18 9 6 3> 24 | 217 0 0xffffff7f95228000 0x1eff9 0x1eff9 com.apple.driver.AGPM (131) 6E5501C1-EE76-3A48-B256-A706C1654080 <159 152 147 140 17 8 7 6 3 1> 25 | 218 0 0xffffff7f95e9a000 0x1fff 0x1fff com.apple.driver.ApplePlatformEnabler (2.7.0d0) EBD0CB5E-069E-31D3-86AE-F50016424C39 <9 7 6 3> 26 | 219 0 0xffffff800184c000 0x1000 0x1000 com.apple.driver.AppleBluetoothHIDKeyboard (231) 57781374-1C81-3943-8E43-F93A73C4F3D9 <130 126 58 6 3> 27 | 221 0 0xffffff7f966ed000 0x81ff1 0x81ff1 com.apple.filesystems.smbfs (5.0) A47AE6DA-E8FF-3348-A45F-BC77C4A74D05 <188 10 9 8 7 6 3 1> 28 | 222 1 0xffffff7f96601000 0xcff7 0xcff7 com.apple.filesystems.exfat (1.4) D13CB989-1F42-3002-865C-9F5ADB1BA635 <9 8 7 6 3 1> 29 | 223 0 0xffffff7f965d6000 0xbffe 0xbffe com.apple.nke.asp_tcp (8.3) E4AD657A-2612-3AF4-B82B-504DD0F1DC42 <9 8 7 6 3 1> 30 | 224 1 0xffffff7f95ebf000 0xc000 0xc000 com.apple.security.SecureRemotePassword (1.0) 3328BC1F-AE4D-33C3-87D0-BA29AE290DB2 <8 7 6 1> 31 | 225 0 0xffffff7f96589000 0x45ff4 0x45ff4 com.apple.filesystems.afpfs (11.4) 3A234FAA-F76E-3CE3-8C49-53FF3924558E <224 95 9 8 7 6 3 1> 32 | -------------------------------------------------------------------------------- /test/assets/ls.01.txt: -------------------------------------------------------------------------------- 1 | total 1656 2 | -rw-r--r-- 1 james staff 2687 Oct 12 16:58 NativeTableParser.deps.json 3 | -rw-r--r-- 1 james staff 12288 Oct 12 16:58 NativeTableParser.dll 4 | -rw-r--r-- 1 james staff 14512 Oct 12 16:58 NativeTableParser.pdb 5 | -rwxr--r-- 1 james staff 354304 Mar 7 2019 System.Management.Automation.dll 6 | -rwxr--r-- 1 james staff 457864 Aug 19 12:49 System.Text.Json.dll 7 | -------------------------------------------------------------------------------- /test/assets/ls.02.txt: -------------------------------------------------------------------------------- 1 | total 1656 2 | -rw-r--r-- 1 james 2687 Oct 12 16:58 NativeTableParser.deps.json 3 | -rw-r--r-- 1 james 12288 Oct 12 16:58 NativeTableParser.dll 4 | -rw-r--r-- 1 james 14512 Oct 12 16:58 NativeTableParser.pdb 5 | -rwxr--r-- 1 james 354304 Mar 7 2019 System.Management.Automation.dll 6 | -rwxr--r-- 1 james 457864 Aug 19 12:49 System.Text.Json.dll 7 | -------------------------------------------------------------------------------- /test/assets/ls.03.txt: -------------------------------------------------------------------------------- 1 | total 1656 2 | -rw-r--r-- 1 2687 Oct 12 16:58 NativeTableParser.deps.json 3 | -rw-r--r-- 1 12288 Oct 12 16:58 NativeTableParser.dll 4 | -rw-r--r-- 1 14512 Oct 12 16:58 NativeTableParser.pdb 5 | -rwxr--r-- 1 354304 Mar 7 2019 System.Management.Automation.dll 6 | -rwxr--r-- 1 457864 Aug 19 12:49 System.Text.Json.dll 7 | -------------------------------------------------------------------------------- /test/assets/ps.01.txt: -------------------------------------------------------------------------------- 1 | PID TTY TIME CMD 2 | 2596 ttys000 1:59.45 /usr/local/bin/pwsh -l 3 | 2601 ttys001 0:44.13 /usr/local/bin/pwsh -l 4 | 2661 ttys002 0:23.53 /usr/local/bin/pwsh 5 | 2669 ttys003 0:23.04 /usr/local/bin/pwsh 6 | 2674 ttys004 0:23.32 /usr/local/bin/pwsh 7 | 2676 ttys005 0:23.16 /usr/local/bin/pwsh 8 | -------------------------------------------------------------------------------- /test/assets/ps.02.txt: -------------------------------------------------------------------------------- 1 | UID PID PPID C STIME TTY TIME CMD 2 | 0 1 0 0 9:34AM ?? 8:24.94 /sbin/launchd 3 | 0 98 1 0 9:34AM ?? 1:54.65 /usr/libexec/logd 4 | 0 99 1 0 9:34AM ?? 0:00.27 /usr/libexec/smd 5 | 0 100 1 0 9:34AM ?? 0:06.71 /usr/libexec/UserEventAgent (System) 6 | 0 103 1 0 9:34AM ?? 0:01.79 /System/Library/PrivateFrameworks/Uninstall.framework/Resources/uninstalld 7 | 0 104 1 0 9:34AM ?? 17:16.62 /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/FSEvents.framework/Versions/A/Support/fseventsd 8 | 0 105 1 0 9:34AM ?? 0:08.17 /System/Library/PrivateFrameworks/MediaRemote.framework/Support/mediaremoted 9 | 0 107 1 0 9:34AM ?? 0:13.62 /usr/sbin/systemstats --daemon 10 | 0 109 1 0 9:34AM ?? 0:10.76 /usr/libexec/configd 11 | 0 110 1 0 9:34AM ?? 0:00.29 endpointsecurityd 12 | 0 111 1 0 9:34AM ?? 1:46.52 /System/Library/CoreServices/powerd.bundle/powerd 13 | 289 112 1 0 9:34AM ?? 0:02.96 /System/Library/PrivateFrameworks/BiomeStreams.framework/Support/biomed 14 | 0 114 1 0 9:34AM ?? 0:03.86 /usr/libexec/amfid 15 | 0 116 1 0 9:34AM ?? 0:08.00 /usr/libexec/remoted 16 | 0 118 1 0 9:34AM ?? 0:00.04 /usr/libexec/keybagd -t 15 17 | 200 119 1 0 9:34AM ?? 0:00.57 /System/Library/PrivateFrameworks/MobileSoftwareUpdate.framework/Support/softwareupdated 18 | 0 121 1 0 9:34AM ?? 0:02.85 /usr/libexec/watchdogd 19 | 240 126 1 0 9:34AM ?? 0:01.15 /System/Library/CoreServices/iconservicesd 20 | 0 127 1 0 9:34AM ?? 0:17.44 /usr/libexec/kernelmanagerd 21 | 0 128 1 0 9:34AM ?? 0:05.77 /usr/libexec/diskarbitrationd 22 | 0 132 1 0 9:34AM ?? 0:48.28 /usr/libexec/coreduetd 23 | 0 133 1 0 9:34AM ?? 0:04.97 /usr/sbin/syslogd 24 | 501 15257 1 0 11:28AM ?? 0:00.02 /System/Library/Frameworks/PCSC.framework/Versions/A/XPCServices/com.apple.ctkpcscd.xpc/Contents/MacOS/com.apple.ctkpcscd 25 | 0 16834 1 0 11:47AM ?? 0:01.48 /System/Library/PrivateFrameworks/PackageKit.framework/Versions/A/XPCServices/package_script_service.xpc/Contents/MacOS/package_script_service 26 | 501 16956 1 0 11:47AM ?? 0:00.25 /usr/libexec/appleaccountd 27 | 501 19881 1 0 11:49AM ?? 0:00.65 /System/Library/PrivateFrameworks/Lookup.framework/Versions/A/XPCServices/LookupViewService.xpc/Contents/MacOS/LookupViewService 28 | 501 19927 1 0 1:41AM ?? 0:01.68 /System/Library/PrivateFrameworks/PhotoAnalysis.framework/Versions/A/Support/photoanalysisd 29 | 0 34545 1 0 4:56AM ?? 2:26.12 /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Support/mds 30 | 0 34546 1 0 4:56AM ?? 0:00.01 /System/Library/Frameworks/NetFS.framework/Versions/A/XPCServices/PlugInLibraryService.xpc/Contents/MacOS/PlugInLibraryService 31 | 0 34547 1 0 4:56AM ?? 5:52.37 /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Versions/A/Support/mds_stores 32 | 89 34910 1 0 5:00AM ?? 0:11.79 /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Versions/A/Support/mdworker -s mdworker-sizing -c MDSSizingWorker -m com.apple.mdworker.sizing 33 | 501 35665 1 0 5:08AM ?? 0:00.37 /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Versions/A/Support/mdworker -s mdworker-sizing -c MDSSizingWorker -m com.apple.mdworker.sizing 34 | 0 36835 1 0 12:03PM ?? 0:00.01 /System/Library/Frameworks/NetFS.framework/Versions/A/XPCServices/PlugInLibraryService.xpc/Contents/MacOS/PlugInLibraryService 35 | 501 36858 1 0 12:04PM ?? 0:00.05 /System/Library/PrivateFrameworks/KerberosHelper/Helpers/DiskUnmountWatcher 36 | 501 36892 1 0 12:04PM ?? 0:00.10 /System/Library/Frameworks/Metal.framework/Versions/A/XPCServices/MTLCompilerService.xpc/Contents/MacOS/MTLCompilerService 37 | 501 37656 1 0 12:10PM ?? 0:00.03 /System/Library/Frameworks/AudioToolbox.framework/XPCServices/com.apple.audio.SandboxHelper.xpc/Contents/MacOS/com.apple.audio.SandboxHelper 38 | 499 37932 376 0 5:36AM ?? 35:05.96 /Applications/Microsoft Defender.app/Contents/MacOS/wdavdaemon_unprivileged.app/Contents/MacOS/wdavdaemon_unprivileged unprivileged 22 27 58 60 20 --log_level info 39 | 501 38408 1 0 12:17PM ?? 0:01.27 /System/Cryptexes/App/System/Library/CoreServices/SafariSupport.bundle/Contents/MacOS/SafariBookmarksSyncAgent 40 | 501 38426 1 0 12:17PM ?? 0:07.45 /usr/libexec/backgroundassets.user 41 | 501 38451 1 0 12:18PM ?? 0:00.37 /usr/libexec/proactiveeventtrackerd 42 | 501 43617 1 0 1:22PM ?? 0:00.33 /System/Library/CoreServices/rcd.app/Contents/MacOS/rcd 43 | 501 46487 1 0 1:56PM ?? 0:00.90 /System/Library/Frameworks/QuickLookUI.framework/Versions/A/XPCServices/QuickLookUIService.xpc/Contents/MacOS/QuickLookUIService 44 | 501 46519 1 0 1:56PM ?? 0:00.01 /System/Library/PrivateFrameworks/ToneLibrary.framework/Versions/A/XPCServices/com.apple.tonelibraryd.xpc/Contents/MacOS/com.apple.tonelibraryd 45 | 501 48190 1 0 2:12PM ?? 0:10.33 /Applications/Docker.app/Contents/MacOS/Docker 46 | 501 48191 48190 0 2:12PM ?? 3:09.64 /Applications/Docker.app/Contents/MacOS/com.docker.backend -watchdog -native-api 47 | 501 48197 48191 0 2:12PM ?? 0:02.30 /Applications/Docker.app/Contents/MacOS/com.docker.backend -watchdog -native-api 48 | 501 48228 48191 0 2:12PM ?? 0:29.18 /Applications/Docker.app/Contents/MacOS/Docker Desktop.app/Contents/MacOS/Docker Desktop --name=dashboard 49 | 501 48247 48191 0 2:12PM ?? 0:04.36 vpnkit-bridge --disable wsl2-cross-distro-service,wsl2-bootstrap-expose-ports,transfused,osxfs-data --addr-fd fd:3 --addr unix+listen+fd:// host 50 | 501 48248 48191 0 2:12PM ?? 0:01.62 com.docker.driver.amd64-linux -addr fd:3 -debug -native-api 51 | 501 48249 48191 0 2:12PM ?? 0:03.22 com.docker.extensions -address extension-manager.sock -watchdog 52 | 501 48250 48191 0 2:12PM ?? 0:00.81 com.docker.dev-envs 53 | 501 48251 48244 0 2:12PM ?? 0:00.00 54 | 501 48273 1 0 2:12PM ?? 35:30.06 /System/Library/Frameworks/Virtualization.framework/Versions/A/XPCServices/com.apple.Virtualization.VirtualMachine.xpc/Contents/MacOS/com.apple.Virtualization.VirtualMachine 55 | 501 48278 1 0 2:12PM ?? 0:00.09 /System/Library/Frameworks/VideoToolbox.framework/Versions/A/XPCServices/VTDecoderXPCService.xpc/Contents/MacOS/VTDecoderXPCService 56 | 501 54642 1 0 2:35PM ?? 0:00.39 /System/Library/Frameworks/QuickLook.framework/Versions/A/XPCServices/ExternalQuickLookSatellite-x86_64.xpc/Contents/MacOS/ExternalQuickLookSatellite-x86_64 57 | 501 56167 1 0 2:54PM ?? 0:00.03 /System/Library/Frameworks/AudioToolbox.framework/XPCServices/com.apple.audio.SandboxHelper.xpc/Contents/MacOS/com.apple.audio.SandboxHelper 58 | 501 56184 1 0 2:54PM ?? 0:01.26 /System/Library/PrivateFrameworks/CallHistory.framework/Support/CallHistorySyncHelper 59 | 0 58795 1 0 3:24PM ?? 0:00.11 /usr/libexec/dprivacyd 60 | 0 60829 1 0 3:50PM ?? 0:00.02 /Library/Apple/System/Library/CoreServices/XProtect.app/Contents/MacOS/XProtect 61 | 0 60830 1 0 3:50PM ?? 0:02.14 /Library/Apple/System/Library/CoreServices/XProtect.app/Contents/XPCServices/XProtectPluginService.xpc/Contents/MacOS/XProtectPluginService 62 | 501 60834 1 0 3:50PM ?? 0:00.02 /Library/Apple/System/Library/CoreServices/XProtect.app/Contents/MacOS/XProtect 63 | 501 60835 1 0 3:50PM ?? 0:01.99 /Library/Apple/System/Library/CoreServices/XProtect.app/Contents/XPCServices/XProtectPluginService.xpc/Contents/MacOS/XProtectPluginService 64 | 501 61051 1 0 3:52PM ?? 0:00.21 /System/Applications/Messages.app/Contents/PlugIns/MobileSMSSpotlightImporterCatalyst.appex/Contents/MacOS/MobileSMSSpotlightImporterCatalyst -AppleLanguages ("en-US") 65 | 501 61052 1 0 3:52PM ?? 0:00.56 /System/Library/PrivateFrameworks/MediaConversionService.framework/Versions/A/XPCServices/com.apple.photos.ImageConversionService.xpc/Contents/MacOS/com.apple.photos.ImageConversionService 66 | 501 61053 1 0 3:52PM ?? 0:00.59 /System/Library/PrivateFrameworks/MessagesBlastDoorSupport.framework/Versions/A/XPCServices/MessagesBlastDoorService.xpc/Contents/MacOS/MessagesBlastDoorService 67 | 501 62406 1 0 4:10PM ?? 0:00.11 /System/Library/CoreServices/OSDUIHelper.app/Contents/MacOS/OSDUIHelper 68 | 501 68318 1 0 8:09AM ?? 0:00.71 /usr/libexec/remindd 69 | 501 69604 1 0 8:24AM ?? 0:00.05 /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Versions/A/Support/mdworker_shared -s mdworker -c MDSImporterWorker -m com.apple.mdworker.shared 70 | 501 69735 1 0 8:24AM ?? 0:00.05 /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Versions/A/Support/mdworker_shared -s mdworker -c MDSImporterWorker -m com.apple.mdworker.shared 71 | 501 69769 1 0 8:25AM ?? 0:00.05 /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Versions/A/Support/mdworker_shared -s mdworker -c MDSImporterWorker -m com.apple.mdworker.shared 72 | 0 69827 1 0 8:25AM ?? 0:00.01 /System/Library/PrivateFrameworks/UserFS.framework/livefileproviderd 73 | 501 69998 1 0 5:42PM ?? 0:00.06 /System/Library/PrivateFrameworks/IMDPersistence.framework/IMAutomaticHistoryDeletionAgent.app/Contents/MacOS/IMAutomaticHistoryDeletionAgent 74 | 501 75548 1 0 6:54PM ?? 0:03.61 /System/Library/PrivateFrameworks/IntelligencePlatformCore.framework/Versions/A/knowledgeconstructiond 75 | 501 82319 1 0 8:21PM ?? 0:00.01 /System/Library/Frameworks/NetFS.framework/Versions/A/XPCServices/PlugInLibraryService.xpc/Contents/MacOS/PlugInLibraryService 76 | 0 87412 1 0 9:28PM ?? 0:00.02 /usr/libexec/griddatad 77 | 501 87439 1 0 9:28PM ?? 0:00.03 /System/Library/PrivateFrameworks/DeviceCheckInternal.framework/devicecheckd 78 | 501 87490 1 0 9:28PM ?? 0:00.10 /System/Library/CoreServices/EscrowSecurityAlert.app/Contents/MacOS/EscrowSecurityAlert 79 | 0 87536 1 0 9:29PM ?? 0:00.01 /usr/libexec/periodic-wrapper daily 80 | 0 87692 1 0 9:30PM ?? 0:00.15 /usr/libexec/applessdstatistics 81 | 0 87749 1 0 9:30PM ?? 0:00.03 /usr/bin/sysdiagnose 82 | 501 87806 1 0 9:31PM ?? 0:00.05 /usr/libexec/proactived 83 | 501 2596 2587 0 9:45AM ttys000 2:00.20 /usr/local/bin/pwsh -l 84 | 0 69835 2596 0 8:25AM ttys000 0:00.01 /bin/ps -ef 85 | 501 2601 2597 0 9:45AM ttys001 0:44.13 /usr/local/bin/pwsh -l 86 | 501 2661 2658 0 9:45AM ttys002 0:23.54 /usr/local/bin/pwsh 87 | 501 2669 2658 0 9:45AM ttys003 0:23.04 /usr/local/bin/pwsh 88 | 501 2674 2658 0 9:45AM ttys004 0:23.32 /usr/local/bin/pwsh 89 | 501 2676 2658 0 9:45AM ttys005 0:23.16 /usr/local/bin/pwsh 90 | -------------------------------------------------------------------------------- /test/assets/ps.03.txt: -------------------------------------------------------------------------------- 1 | UID PID PPID F CPU PRI NI SZ RSS WCHAN S ADDR TTY TIME CMD 2 | 501 2596 2587 4006 0 33 0 39662748 167544 - S+ 0 ttys000 2:01.35 /usr/local/bin/pwsh -l 3 | 501 2601 2597 4006 0 33 0 39659028 142632 - S+ 0 ttys001 0:44.13 /usr/local/bin/pwsh -l 4 | 501 2661 2658 4006 0 33 0 39657836 135988 - Ss+ 0 ttys002 0:23.54 /usr/local/bin/pwsh 5 | 501 2669 2658 4006 0 33 0 39658348 135396 - Ss+ 0 ttys003 0:23.05 /usr/local/bin/pwsh 6 | 501 2674 2658 4006 0 33 0 39658348 136844 - Ss+ 0 ttys004 0:23.32 /usr/local/bin/pwsh 7 | 501 2676 2658 4006 0 33 0 39658344 136596 - Ss+ 0 ttys005 0:23.17 /usr/local/bin/pwsh 8 | -------------------------------------------------------------------------------- /test/assets/ps.04.txt: -------------------------------------------------------------------------------- 1 | PID TTY TIME CMD 2 | 1 ?? 10:14.30 launchd 3 | 98 ?? 2:22.73 logd 4 | 99 ?? 0:00.32 smd 5 | 100 ?? 0:07.62 UserEventAgent 6 | 103 ?? 0:02.18 uninstalld 7 | 104 ?? 19:06.64 fseventsd 8 | 105 ?? 0:11.72 mediaremoted 9 | 107 ?? 0:16.55 systemstats 10 | 109 ?? 0:12.40 configd 11 | 110 ?? 0:00.33 endpointsecurityd 12 | 111 ?? 2:16.74 powerd 13 | 112 ?? 0:03.55 biomed 14 | 114 ?? 0:04.27 amfid 15 | 116 ?? 0:09.78 remoted 16 | 118 ?? 0:00.04 keybagd 17 | 119 ?? 0:00.67 softwareupdated 18 | 121 ?? 0:03.45 watchdogd 19 | 126 ?? 0:01.21 iconservicesd 20 | 127 ?? 0:17.47 kernelmanagerd 21 | 128 ?? 0:07.12 diskarbitrationd 22 | 132 ?? 1:08.84 coreduetd 23 | 133 ?? 0:05.66 syslogd 24 | 136 ?? 0:00.02 thermalmonitord 25 | 137 ?? 1:42.61 opendirectoryd 26 | 138 ?? 0:07.52 apsd 27 | 139 ?? 3:12.00 launchservicesd 28 | 140 ?? 0:00.93 timed 29 | 141 ?? 0:00.80 usbmuxd 30 | 142 ?? 0:14.69 securityd 31 | 143 ?? 0:00.01 auditd 32 | 147 ?? 0:00.04 autofsd 33 | 148 ?? 0:00.58 displaypolicyd 34 | 149 ?? 0:25.19 dasd 35 | 152 ?? 0:26.94 distnoted 36 | 153 ?? 0:00.06 AppleCredentialManagerDaemon 37 | 155 ?? 0:00.02 dirhelper 38 | 156 ?? 0:00.11 logind 39 | 157 ?? 0:00.31 revisiond 40 | 158 ?? 0:00.02 KernelEventAgent 41 | 159 ?? 0:03.59 usermanagerd 42 | 162 ?? 3:32.80 notifyd 43 | 163 ?? 0:06.75 sandboxd 44 | 164 ?? 0:05.84 corebrightnessd 45 | 165 ?? 0:02.17 AirPlayXPCHelper 46 | 166 ?? 0:00.74 com.apple.cmio.registerassistantservice 47 | 168 ?? 1:00.54 cfprefsd 48 | 169 ?? 5:00.20 syspolicyd 49 | 170 ?? 0:02.14 logd_helper 50 | 171 ?? 0:00.05 aslmanager 51 | 172 ?? 188:45.35 WindowServer 52 | 173 ?? 0:45.10 tccd 53 | 178 ?? 0:20.43 analyticsd 54 | 195 ?? 0:03.15 authd 55 | 209 ?? 1:04.69 runningboardd 56 | 212 ?? 0:00.31 sysextd 57 | 214 ?? 1:33.11 lsd 58 | 215 ?? 0:05.67 coreservicesd 59 | 224 ?? 0:01.99 distnoted 60 | 233 ?? 0:20.19 loginwindow 61 | 240 ?? 1:10.13 mDNSResponder 62 | 243 ?? 0:02.08 distnoted 63 | 247 ?? 0:01.56 backgroundtaskmanagementd 64 | 248 ?? 1:20.21 trustd 65 | 258 ?? 0:00.01 multiversed 66 | 259 ?? 0:00.04 com.apple.ifdreader 67 | 262 ?? 0:09.03 nehelper 68 | 263 ?? 0:06.85 nsurlsessiond 69 | 264 ?? 0:00.06 apfsd 70 | 266 ?? 0:00.05 trustdFileHelper 71 | 268 ?? 0:20.70 airportd 72 | 274 ?? 0:16.27 contextstored 73 | 276 ?? 100:00.33 coreaudiod 74 | 278 ?? 0:00.09 usbd 75 | 279 ?? 0:00.02 installerdiagwatcher 76 | 280 ?? 1:02.34 ioupsd 77 | 282 ?? 0:00.02 ethcheck 78 | 283 ?? 0:00.10 VDCAssistant 79 | 287 ?? 0:00.01 csnameddatad 80 | 288 ?? 104:43.99 backupd 81 | 291 ?? 0:00.54 nesessionmanager 82 | 292 ?? 0:02.15 distnoted 83 | 293 ?? 0:00.10 systemstatusd 84 | 294 ?? 0:00.06 awdd 85 | 295 ?? 1:10.40 mobileassetd 86 | 297 ?? 0:40.05 symptomsd 87 | 298 ?? 0:00.05 cryptexd 88 | 299 ?? 0:00.03 tzd 89 | 300 ?? 0:01.42 com.apple.CodeSigningHelper 90 | 302 ?? 0:00.03 PowerUIAgent 91 | 303 ?? 0:02.95 mDNSResponderHelper 92 | 306 ?? 0:02.85 distnoted 93 | 307 ?? 0:02.58 com.apple.geod 94 | 308 ?? 0:17.12 softwareupdated 95 | 309 ?? 0:00.14 cron 96 | 310 ?? 0:00.16 secinitd 97 | 311 ?? 0:00.04 cfprefsd 98 | 312 ?? 0:00.33 trustd 99 | 314 ?? 0:00.65 findmydeviced 100 | 315 ?? 0:02.22 distnoted 101 | 316 ?? 0:00.61 com.apple.MobileSoftwareUpdate.CleanupPreparePathService 102 | 317 ?? 0:00.05 containermanagerd 103 | 328 ?? 0:02.26 distnoted 104 | 337 ?? 0:16.49 backupd-helper 105 | 345 ?? 3:39.31 UVCAssistant 106 | 346 ?? 0:00.09 containermanagerd 107 | 347 ?? 0:00.04 suhelperd 108 | 348 ?? 0:00.19 wifip2pd 109 | 351 ?? 0:01.69 diskmanagementd 110 | 353 ?? 0:00.02 WiFiCloudAssetsXPCService 111 | 357 ?? 0:21.14 storagekitd 112 | 359 ?? 0:41.32 Core Audio Driver (MSTeamsAudioDevice.driver) 113 | 362 ?? 0:00.07 writeconfig 114 | 366 ?? 0:00.37 aned 115 | 367 ?? 0:21.84 locationd 116 | 368 ?? 0:02.46 iconservicesagent 117 | 369 ?? 3:21.98 XprotectService 118 | 370 ?? 0:00.04 containermanagerd 119 | 372 ?? 0:00.07 AudioComponentRegistrar 120 | 376 ?? 79:51.65 wdavdaemon 121 | 378 ?? 1:14.22 com.spitfireaudio.LibraryManagerHelper 122 | 380 ?? 17:16.27 dlpdaemon 123 | 382 ?? 0:04.57 IntuneMdmDaemon 124 | 384 ?? 0:13.85 licenseDaemon 125 | 385 ?? 14:27.18 epsext 126 | 393 ?? 0:00.03 com.apple.audio.SandboxHelper 127 | 394 ?? 0:21.24 searchpartyd 128 | 400 ?? 0:35.74 Core Audio Driver (ZoomAudioDevice.driver) 129 | 409 ?? 0:02.86 rtcreportingd 130 | 413 ?? 0:00.02 ReportCrash 131 | 448 ?? 1:26.78 netext 132 | 465 ?? 0:00.14 com.apple.audio.DriverHelper 133 | 468 ?? 0:33.72 audioclocksyncd 134 | 469 ?? 0:00.85 coresymbolicationd 135 | 483 ?? 0:00.55 aceagent 136 | 492 ?? 0:00.16 kdc 137 | 499 ?? 0:02.31 distnoted 138 | 501 ?? 0:00.38 secinitd 139 | 504 ?? 0:01.07 netbiosd 140 | 505 ?? 0:00.60 corekdld 141 | 506 ?? 0:00.52 bosUpdateProxy 142 | 507 ?? 0:00.79 SubmitDiagInfo 143 | 509 ?? 85:12.03 wdavdaemon_enterprise 144 | 510 ?? 0:00.03 CVMServer 145 | 511 ?? 0:02.25 distnoted 146 | 516 ?? 0:00.02 com.apple.DriverKit-IOUserDockChannelSerial 147 | 517 ?? 2:14.10 com.apple.DriverKit.AppleUserECM 148 | 518 ?? 15:21.73 com.apple.AppleUserHIDDrivers 149 | 519 ?? 0:00.01 com.apple.DriverKit.AppleUserECM 150 | 525 ?? 1:19.62 telemetryd_v2 151 | 526 ?? 0:00.09 siriinferenced 152 | 530 ?? 2:48.62 dlp_agent 153 | 535 ?? 0:00.19 securityd_service 154 | 537 ?? 0:02.20 distnoted 155 | 538 ?? 0:41.10 CAReportingService 156 | 540 ?? 0:00.34 thermald 157 | 556 ?? 0:02.80 distnoted 158 | 561 ?? 0:00.13 hidd 159 | 568 ?? 0:02.08 distnoted 160 | 570 ?? 0:24.24 lsd 161 | 572 ?? 0:00.01 csnameddatad 162 | 573 ?? 0:01.89 trustd 163 | 574 ?? 0:00.37 wifianalyticsd 164 | 579 ?? 0:00.03 BlueTool 165 | 587 ?? 0:00.76 mobileactivationd 166 | 603 ?? 0:00.05 appinstalld 167 | 604 ?? 0:00.02 com.apple.MobileInstallationHelperService 168 | 605 ?? 0:02.03 distnoted 169 | 607 ?? 0:00.06 secd 170 | 610 ?? 0:00.05 online-authd 171 | 615 ?? 0:00.21 colorsync.displayservices 172 | 616 ?? 0:00.02 com.apple.ColorSyncXPCAgent 173 | 617 ?? 0:00.09 colorsyncd 174 | 618 ?? 0:00.59 MTLCompilerService 175 | 619 ?? 9:34.15 sysmond 176 | 620 ?? 0:01.13 appleeventsd 177 | 622 ?? 0:00.21 symptomsd-diag 178 | 623 ?? 0:00.71 systemstats 179 | 624 ?? 0:00.20 sharedfilelistd 180 | 625 ?? 0:00.03 bootinstalld 181 | 639 ?? 0:00.04 com.apple.AccountPolicyHelper 182 | 654 ?? 0:00.08 coreauthd 183 | 655 ?? 0:00.09 AppSSODaemon 184 | 657 ?? 0:00.83 biometrickitd 185 | 658 ?? 0:54.23 distnoted 186 | 662 ?? 1:03.48 secd 187 | 663 ?? 12:51.25 cfprefsd 188 | 664 ?? 0:00.31 TrustedPeersHelper 189 | 667 ?? 0:04.29 com.apple.AmbientDisplayAgent 190 | 668 ?? 0:00.01 com.apple.ColorSyncXPCAgent 191 | 672 ?? 0:20.26 UserEventAgent 192 | 673 ?? 0:04.15 gamecontrollerd 193 | 674 ?? 2:05.72 ContinuityCaptureAgent 194 | 675 ?? 2:12.29 knowledge-agent 195 | 679 ?? 0:01.14 com.apple.sbd 196 | 680 ?? 0:01.82 universalaccessd 197 | 682 ?? 0:00.66 BackgroundTaskManagementAgent 198 | 683 ?? 1:05.60 lsd 199 | 684 ?? 0:54.49 AXVisualSupportAgent 200 | 685 ?? 0:36.08 tccd 201 | 686 ?? 0:57.23 rapportd 202 | 687 ?? 0:00.02 csnameddatad 203 | 688 ?? 1:45.51 trustd 204 | 689 ?? 0:28.90 accountsd 205 | 690 ?? 0:04.28 homed 206 | 693 ?? 0:00.64 pboard 207 | 694 ?? 0:14.22 identityservicesd 208 | 695 ?? 0:01.90 distnoted 209 | 696 ?? 0:03.06 usernoted 210 | 698 ?? 0:04.44 donotdisturbd 211 | 699 ?? 0:11.34 containermanagerd 212 | 700 ?? 0:19.59 BiomeAgent 213 | 701 ?? 1:15.76 nearbyd 214 | 702 ?? 0:03.66 WirelessRadioManagerd 215 | 703 ?? 3:37.11 ControlCenter 216 | 704 ?? 0:21.77 ContextStoreAgent 217 | 705 ?? 1:19.68 sharingd 218 | 706 ?? 0:03.16 gamecontrolleragentd 219 | 710 ?? 0:00.05 followupd 220 | 712 ?? 0:25.82 secinitd 221 | 714 ?? 1:35.29 contactsd 222 | 715 ?? 0:01.60 sharedfilelistd 223 | 718 ?? 0:04.67 bird 224 | 720 ?? 0:00.49 ScreenTimeAgent 225 | 721 ?? 0:51.38 WindowManager 226 | 723 ?? 0:18.79 cloudd 227 | 724 ?? 0:03.60 filecoordinationd 228 | 725 ?? 1:02.10 fileproviderd 229 | 729 ?? 0:22.44 nsurlsessiond 230 | 730 ?? 0:00.01 com.apple.DictionaryServiceHelper 231 | 731 ?? 0:00.27 keyboardservicesd 232 | 735 ?? 0:00.94 dmd 233 | 736 ?? 0:09.67 pkd 234 | 738 ?? 0:01.66 familycircled 235 | 739 ?? 0:43.48 axassetsd 236 | 740 ?? 0:02.08 pbs 237 | 742 ?? 0:00.52 AudioComponentRegistrar 238 | 744 ?? 0:01.02 systemsoundserverd 239 | 746 ?? 0:02.82 akd 240 | 750 ?? 0:00.03 USBAgent 241 | 752 ?? 0:01.60 adid 242 | 755 ?? 0:28.56 spindump 243 | 756 ?? 0:00.01 spindump_agent 244 | 757 ?? 0:00.80 cdpd 245 | 758 ?? 0:00.20 CarbonComponentScannerXPC 246 | 768 ?? 0:00.82 talagent 247 | 769 ?? 0:00.01 PlugInLibraryService 248 | 770 ?? 0:01.39 siriactionsd 249 | 771 ?? 0:01.08 CoreLocationAgent 250 | 772 ?? 0:11.11 calaccessd 251 | 774 ?? 0:01.89 distnoted 252 | 775 ?? 0:09.89 syncdefaultsd 253 | 776 ?? 0:03.12 transparencyd 254 | 777 ?? 0:00.32 ctkd 255 | 778 ?? 0:02.97 CommCenter 256 | 779 ?? 25:47.12 corespotlightd 257 | 780 ?? 0:15.18 NotificationCenter 258 | 781 ?? 0:00.03 APFSUserAgent 259 | 783 ?? 0:35.20 fontd 260 | 784 ?? 0:06.55 routined 261 | 786 ?? 0:00.80 WiFiAgent 262 | 787 ?? 0:01.07 fontworker 263 | 788 ?? 0:10.59 callservicesd 264 | 789 ?? 0:03.04 appstored 265 | 790 ?? 0:02.39 ContextService 266 | 791 ?? 0:00.08 replayd 267 | 792 ?? 0:01.74 sociallayerd 268 | 793 ?? 0:12.42 iconservicesagent 269 | 794 ?? 0:02.52 com.apple.hiservices-xpcservice 270 | 795 ?? 7:09.68 suggestd 271 | 796 ?? 0:06.67 com.apple.geod 272 | 798 ?? 0:01.82 fmfd 273 | 800 ?? 0:02.16 mobiletimerd 274 | 801 ?? 0:05.40 ViewBridgeAuxiliary 275 | 802 ?? 0:00.99 CoreServicesUIAgent 276 | 803 ?? 0:04.02 ContainerMetadataExtractor 277 | 804 ?? 0:00.01 LoginUserService 278 | 806 ?? 0:00.24 Keychain Circle Notification 279 | 807 ?? 0:00.13 ProtectedCloudKeySyncing 280 | 809 ?? 0:00.86 com.apple.StreamingUnzipService 281 | 810 ?? 0:00.24 CloudKeychainProxy 282 | 811 ?? 0:01.77 neagent 283 | 813 ?? 0:00.74 akd 284 | 814 ?? 0:01.02 AssetCacheLocatorService 285 | 815 ?? 0:00.05 installcoordinationd 286 | 816 ?? 0:00.07 AssetCache 287 | 817 ?? 0:01.84 distnoted 288 | 818 ?? 0:00.05 AssetCacheTetheratorService 289 | 819 ?? 0:02.01 AppSSOAgent 290 | 821 ?? 0:07.69 CMFSyncAgent 291 | 833 ?? 0:04.66 progressd 292 | 836 ?? 0:04.07 amsaccountsd 293 | 838 ?? 0:14.76 amsengagementd 294 | 844 ?? 0:01.38 com.apple.CloudPhotosConfiguration 295 | 845 ?? 0:01.16 iCloudNotificationAgent 296 | 847 ?? 0:08.20 networkserviceproxy 297 | 848 ?? 5:02.97 photolibraryd 298 | 849 ?? 0:00.30 SoftwareUpdateNotificationManager 299 | 851 ?? 0:01.56 ScopedBookmarkAgent 300 | 854 ?? 0:00.28 nfcd 301 | 863 ?? 0:00.05 seld 302 | 873 ?? 0:01.80 distnoted 303 | 875 ?? 0:00.70 cloudphotod 304 | 877 ?? 0:00.81 cloudpaird 305 | 879 ?? 0:00.57 remotemanagementd 306 | 885 ?? 0:00.05 InteractiveLegacyProfilesSubscriber 307 | 886 ?? 0:01.80 distnoted 308 | 887 ?? 0:00.04 LegacyProfilesSubscriber 309 | 888 ?? 0:00.04 PasscodeSettingsSubscriber 310 | 890 ?? 0:00.03 AccountSubscriber 311 | 891 ?? 0:00.03 ManagementTestSubscriber 312 | 892 ?? 0:00.01 PlugInLibraryService 313 | 893 ?? 0:00.14 XProtectBehaviorService 314 | 894 ?? 0:56.66 mdbulkimport 315 | 895 ?? 0:09.11 swcd 316 | 897 ?? 0:21.06 assistantd 317 | 898 ?? 0:01.37 linkd 318 | 899 ?? 0:00.03 com.apple.audio.ComponentTagHelper 319 | 900 ?? 0:17.87 siriknowledged 320 | 901 ?? 0:00.03 ctkd 321 | 902 ?? 0:00.27 coreauthd 322 | 904 ?? 0:00.08 extensionkitservice 323 | 905 ?? 0:01.36 com.apple.siri.embeddedspeech 324 | 906 ?? 0:00.17 FindMyWidgetItems 325 | 907 ?? 0:00.08 PhotosReliveWidget 326 | 908 ?? 0:00.45 NewsToday2 327 | 909 ?? 0:00.10 com.apple.Notes.WidgetExtension 328 | 910 ?? 0:00.10 CalendarWidgetExtension 329 | 912 ?? 0:00.17 WeatherWidget 330 | 913 ?? 0:05.05 triald 331 | 914 ?? 0:00.12 PodcastsWidget 332 | 915 ?? 0:00.10 RemindersWidgetExtension 333 | 916 ?? 0:00.12 FindMyWidgetPeople 334 | 917 ?? 0:00.12 StocksWidget 335 | 918 ?? 0:00.05 TipsAppWidget-macOSExtension 336 | 919 ?? 0:00.11 ScreenTimeWidgetExtension 337 | 920 ?? 0:00.09 HomeWidget 338 | 921 ?? 0:00.13 WorldClockWidget 339 | 923 ?? 0:00.42 NewsTag 340 | 924 ?? 0:00.70 StatusKitAgent 341 | 925 ?? 0:03.96 imagent 342 | 926 ?? 0:00.13 com.apple.FaceTime.FTConversationService 343 | 927 ?? 9:36.72 IMDPersistenceAgent 344 | 928 ?? 0:00.10 GSSCred 345 | 929 ?? 0:19.02 useractivityd 346 | 930 ?? 0:00.51 mediaremoteagent 347 | 931 ?? 0:08.77 avconferenced 348 | 932 ?? 0:00.99 SidecarRelay 349 | 933 ?? 1:11.40 UniversalControl 350 | 934 ?? 0:13.46 biomesyncd 351 | 941 ?? 0:00.06 mediasharingd 352 | 943 ?? 0:15.29 deleted 353 | 950 ?? 0:01.64 com.apple.siri.embeddedspeech 354 | 955 ?? 0:09.75 searchpartyuseragent 355 | 956 ?? 0:00.73 UIKitSystem 356 | 959 ?? 0:00.12 fairplayd 357 | 961 ?? 0:00.01 ReportCrash 358 | 968 ?? 0:00.50 RemoteManagementAgent 359 | 969 ?? 0:00.06 InteractiveLegacyProfilesSubscriber 360 | 970 ?? 0:00.04 LegacyProfilesSubscriber 361 | 971 ?? 0:00.04 PasscodeSettingsSubscriber 362 | 972 ?? 0:00.05 AccountSubscriber 363 | 973 ?? 0:00.03 ManagementTestSubscriber 364 | 980 ?? 0:01.45 csimporter 365 | 1013 ?? 0:13.12 trustd 366 | 1014 ?? 0:47.46 mdbulkimport 367 | 1017 ?? 0:00.01 csnameddatad 368 | 1048 ?? 0:00.13 containermanagerd 369 | 1062 ?? 0:08.45 Google Chrome Helper (Renderer) 370 | 1064 ?? 0:00.46 maild 371 | 1066 ?? 0:00.50 financed 372 | 1067 ?? 0:00.03 extensionkitservice 373 | 1069 ?? 0:00.04 CalendarFocusConfigurationExtension 374 | 1070 ?? 0:00.05 SafariLinkExtension 375 | 1071 ?? 0:00.03 MailShortcutsExtension 376 | 1072 ?? 0:00.03 MessagesActionExtension 377 | 1079 ?? 0:00.34 UsageTrackingAgent 378 | 1080 ?? 0:01.85 adprivacyd 379 | 1082 ?? 0:17.43 corespeechd 380 | 1083 ?? 0:00.83 com.apple.siri.embeddedspeech 381 | 1084 ?? 2:10.78 assistant_service 382 | 1088 ?? 0:01.33 parsecd 383 | 1090 ?? 0:10.90 itunescloudd 384 | 1165 ?? 0:01.23 ndoagent 385 | 1187 ?? 0:00.18 diagnosticextensionsd 386 | 1188 ?? 0:10.36 CoreSpotlightService 387 | 1221 ?? 0:00.44 avatarsd 388 | 1298 ?? 0:00.01 installerdiagd 389 | 1314 ?? 0:00.37 intelligenceplatformd 390 | 1325 ?? 0:00.34 sirittsd 391 | 1326 ?? 0:10.93 MTLAssetUpgraderD 392 | 1333 ?? 0:03.22 com.apple.quicklook.ThumbnailsAgent 393 | 1334 ?? 0:01.22 ThumbnailExtension_macOS 394 | 1335 ?? 0:03.88 QuickLookSatellite 395 | 1339 ?? 4:07.68 Mail 396 | 1348 ?? 0:00.04 ASPCarryLog 397 | 1349 ?? 0:09.16 appstoreagent 398 | 1350 ?? 0:00.03 metrickitd 399 | 1351 ?? 0:00.03 com.apple.AppStoreDaemon.StorePrivilegedTaskService 400 | 1352 ?? 0:01.10 promotedcontentd 401 | 1357 ?? 0:03.52 osanalyticshelper 402 | 1358 ?? 0:01.41 diagnostics_agent 403 | 1359 ?? 0:00.02 CrashReporterSupportHelper 404 | 1555 ?? 0:00.03 localizationswitcherd 405 | 1597 ?? 0:00.52 mapspushd 406 | 1603 ?? 0:00.02 spotlightknowledged 407 | 1612 ?? 2:50.70 media-indexer 408 | 1615 ?? 2:29.08 AMPLibraryAgent 409 | 1621 ?? 0:00.08 PodcastContentService 410 | 1622 ?? 0:00.16 com.apple.BKAgentService 411 | 1623 ?? 0:00.08 com.apple.audio.SandboxHelper 412 | 1624 ?? 0:00.19 AMPArtworkAgent 413 | 1625 ?? 0:00.03 mlruntimed 414 | 2165 ?? 0:00.02 microstackshot 415 | 2403 ?? 0:16.16 Spotlight 416 | 2404 ?? 0:02.02 commerce 417 | 2515 ?? 0:03.75 System Settings 418 | 2517 ?? 6:27.97 Teams 419 | 2521 ?? 5:20.45 Terminal 420 | 2523 ?? 6:01.88 Music 421 | 2524 ?? 15:11.31 Microsoft Remote Desktop 422 | 2525 ?? 10:51.71 Messages 423 | 2527 ?? 7:54.41 Activity Monitor 424 | 2528 ?? 6:05.01 Microsoft Edge 425 | 2529 ?? 1:29.90 iTerm2 426 | 2533 ?? 0:53.53 Dock 427 | 2534 ?? 3:16.14 SystemUIServer 428 | 2535 ?? 8:58.44 Finder 429 | 2540 ?? 0:00.36 QuickLookUIService 430 | 2549 ?? 0:00.04 automountd 431 | 2551 ?? 0:00.08 extensionkitservice 432 | 2552 ?? 0:00.25 VTDecoderXPCService 433 | 2553 ?? 0:00.27 AMPDeviceDiscoveryAgent 434 | 2555 ?? 0:00.24 ACCFinderSync 435 | 2556 ?? 0:00.25 deleted_helper 436 | 2557 ?? 0:00.92 Appearance 437 | 2560 ?? 0:00.10 ctkahp 438 | 2561 ?? 0:00.06 ctkahp 439 | 2563 ?? 0:00.20 imklaunchagent 440 | 2564 ?? 0:00.07 geodMachServiceBridge 441 | 2565 ?? 0:27.79 installd 442 | 2566 ?? 0:00.11 storedownloadd 443 | 2567 ?? 0:00.71 cloudd 444 | 2568 ?? 0:00.09 system_installd 445 | 2572 ?? 0:01.27 PAH_Extension 446 | 2573 ?? 0:00.44 UserNotificationCenter 447 | 2575 ?? 0:00.27 TextInputSwitcher 448 | 2576 ?? 0:06.88 AppleIDSettings 449 | 2580 ?? 0:00.08 PlugInLibraryService 450 | 2581 ?? 0:00.26 colorsync.useragent 451 | 2582 ?? 0:00.01 com.apple.ColorSyncXPCAgent 452 | 2583 ?? 0:00.02 SafeEjectGPUAgent 453 | 2584 ?? 0:00.03 SafeEjectGPUService 454 | 2586 ?? 0:00.62 contentlinkingd 455 | 2588 ?? 0:00.04 com.apple.audio.SandboxHelper 456 | 2589 ?? 0:00.01 com.apple.HasTRB 457 | 2590 ?? 0:02.41 OneDrive File Provider 458 | 2591 ?? 0:00.42 Touch ID & Password 459 | 2592 ?? 0:00.49 HeadphoneSettingsExtension 460 | 2593 ?? 0:48.20 PowerPreferences 461 | 2594 ?? 0:00.39 FollowUpSettingsExtension 462 | 2595 ?? 0:02.04 FamilySettings 463 | 2598 ?? 0:00.43 TrackpadExtension 464 | 2600 ?? 0:00.40 ClassKitSettings 465 | 2604 ?? 0:28.93 dataaccessd 466 | 2608 ?? 0:00.05 AssetCacheManagerService 467 | 2609 ?? 0:00.38 VisualizerService 468 | 2610 ?? 0:00.08 storelegacy 469 | 2611 ?? 0:00.45 WalletSettingsExtension 470 | 2613 ?? 0:00.73 storeuid 471 | 2614 ?? 0:00.73 ClassroomSettings 472 | 2625 ?? 0:03.80 studentd 473 | 2631 ?? 0:00.46 MouseExtension 474 | 2632 ?? 0:00.34 recentsd 475 | 2634 ?? 0:03.12 com.apple.dock.extra 476 | 2635 ?? 0:07.67 com.apple.WebKit.WebContent 477 | 2636 ?? 0:00.06 com.apple.accessibility.mediaaccessibilityd 478 | 2637 ?? 0:00.05 com.apple.audio.SandboxHelper 479 | 2639 ?? 0:00.13 QuickLookSatellite 480 | 2640 ?? 0:01.28 reversetemplated 481 | 2641 ?? 0:01.76 com.apple.WebKit.Networking 482 | 2642 ?? 0:00.90 CallHistoryPluginHelper 483 | 2644 ?? 0:01.59 passd 484 | 2646 ?? 1:14.13 com.apple.Safari.SafeBrowsing.Service 485 | 2648 ?? 0:00.07 msedge_crashpad_handler 486 | 2651 ?? 0:00.01 PlugInLibraryService 487 | 2654 ?? 0:00.77 peopled 488 | 2657 ?? 0:00.40 VPN 489 | 2658 ?? 0:00.02 iTermServer-3.4.19 490 | 2660 ?? 0:04.46 gamed 491 | 2662 ?? 1:59.13 Microsoft Edge Helper (GPU) 492 | 2664 ?? 2:02.89 Microsoft Edge Helper 493 | 2665 ?? 0:00.07 chrome_crashpad_handler 494 | 2670 ?? 0:01.65 pwSafe 495 | 2675 ?? 0:00.44 GameControllerMacSettings 496 | 2678 ?? 0:10.15 Microsoft Edge Helper 497 | 2680 ?? 40:51.88 Microsoft Teams Helper (GPU) 498 | 2685 ?? 0:00.02 misagent 499 | 2686 ?? 0:01.59 VTDecoderXPCService 500 | 2687 ?? 0:24.04 Microsoft Teams Helper 501 | 2688 ?? 0:00.02 pidinfo 502 | 2689 ?? 0:00.15 VTDecoderXPCService 503 | 2692 ?? 0:02.20 storekitagent 504 | 2694 ?? 0:00.09 SafariLaunchAgent 505 | 2698 ?? 0:01.75 Microsoft Edge Helper (Renderer) 506 | 2699 ?? 0:00.02 PlugInLibraryService 507 | 2704 ?? 0:00.71 Microsoft Teams Helper (Renderer) 508 | 2708 ?? 0:01.72 Microsoft Edge Helper (Renderer) 509 | 2710 ?? 0:05.94 Microsoft Edge Helper (Renderer) 510 | 2711 ?? 0:00.43 CDs & DVDs Settings Extension 511 | 2716 ?? 0:01.14 lskdd 512 | 2718 ?? 0:02.64 com.apple.appkit.xpc.openAndSavePanelService 513 | 2719 ?? 0:02.27 Microsoft Teams Helper 514 | 2721 ?? 0:00.15 VTEncoderXPCService 515 | 2723 ?? 0:00.40 QuickLookUIService 516 | 2727 ?? 39:30.76 Microsoft Teams Helper (Renderer) 517 | 2733 ?? 0:08.06 AppleSpell 518 | 2734 ?? 0:00.93 naturallanguaged 519 | 2737 ?? 0:14.86 heard 520 | 2739 ?? 0:01.59 IntuneMdmAgent 521 | 2741 ?? 0:08.76 Microsoft Defender Helper 522 | 2744 ?? 0:47.33 PanGPS 523 | 2746 ?? 0:28.45 ChromaCamHelper 524 | 2748 ?? 0:00.05 sh 525 | 2749 ?? 0:13.94 dlpagent 526 | 2750 ?? 0:00.56 icdd 527 | 2751 ?? 0:28.43 GlobalProtect 528 | 2752 ?? 0:09.10 Alertus Desktop 529 | 2753 ?? 1:49.11 AvidLink 530 | 2754 ?? 0:02.10 askpermissiond 531 | 2757 ?? 0:15.19 AGMService 532 | 2758 ?? 0:00.16 AirPlayUIAgent 533 | 2763 ?? 0:00.05 bluetoothuserd 534 | 2765 ?? 0:01.98 TextInputMenuAgent 535 | 2766 ?? 0:00.70 Amazon Music Helper 536 | 2767 ?? 5:52.63 Stream Deck 537 | 2774 ?? 0:01.09 NIHardwareAgent 538 | 2786 ?? 0:00.06 com.apple.audio.SandboxHelper 539 | 2791 ?? 13:22.95 Time Out 540 | 2796 ?? 0:00.02 PlugInLibraryService 541 | 2801 ?? 0:00.02 taskgated 542 | 2811 ?? 0:07.25 Microsoft Edge Helper 543 | 2813 ?? 0:00.15 VTEncoderXPCService 544 | 2814 ?? 0:43.47 Microsoft Edge Helper (Renderer) 545 | 2818 ?? 0:00.06 com.apple.audio.SandboxHelper 546 | 2856 ?? 140:06.94 Microsoft Teams Helper (Renderer) 547 | 2857 ?? 0:00.02 CrashHandler 548 | 2885 ?? 0:00.78 nsattributedstringagent 549 | 2922 ?? 2:10.28 mysqld 550 | 2931 ?? 9:10.75 Microsoft Teams Helper (Renderer) 551 | 2943 ?? 0:09.94 Microsoft Edge Helper (Renderer) 552 | 2958 ?? 0:48.01 AdobeIPCBroker 553 | 2982 ?? 0:02.37 tipsd 554 | 3041 ?? 0:58.20 Adobe Desktop Service 555 | 3044 ?? 0:01.84 QtWebEngineProcess 556 | 3053 ?? 0:00.02 CrashHandler 557 | 3059 ?? 0:53.19 Adobe Crash Handler 558 | 3068 ?? 0:00.74 vcxpc 559 | 3070 ?? 0:00.16 VTDecoderXPCService 560 | 3072 ?? 0:15.47 Creative Cloud Helper 561 | 3073 ?? 0:17.59 QtWebEngineProcess 562 | 3074 ?? 0:00.16 VTEncoderXPCService 563 | 3075 ?? 0:00.62 QtWebEngineProcess 564 | 3089 ?? 0:00.02 CrashHandler 565 | 3093 ?? 0:52.85 Adobe Crash Handler 566 | 3103 ?? 0:14.45 node 567 | 3105 ?? 0:00.02 ChromaCamKitAssistant 568 | 3119 ?? 0:01.00 Plugin 569 | 3120 ?? 0:01.46 ESDDiscord 570 | 3121 ?? 0:00.50 QtWebEngineProcess 571 | 3122 ?? 0:18.80 QtWebEngineProcess 572 | 3123 ?? 0:10.04 com.nicollasr.streamdeckvsc 573 | 3125 ?? 0:00.02 TwitchStudioStreamDeck 574 | 3126 ?? 0:57.40 se.trevligaspel.midi 575 | 3127 ?? 0:00.52 QtWebEngineProcess 576 | 3136 ?? 0:00.93 QtWebEngineProcess 577 | 3142 ?? 0:01.65 QtWebEngineProcess 578 | 3143 ?? 0:01.87 QtWebEngineProcess 579 | 3144 ?? 0:02.14 QtWebEngineProcess 580 | 3145 ?? 0:01.66 QtWebEngineProcess 581 | 3149 ?? 0:11.67 Creative Cloud Helper 582 | 3152 ?? 0:00.02 CrashHandler 583 | 3158 ?? 0:53.06 Adobe Crash Handler 584 | 3161 ?? 0:00.19 IDSBlastDoorService 585 | 3162 ?? 0:00.14 BTLEServerAgent 586 | 3172 ?? 1:53.09 Core Sync 587 | 3187 ?? 0:00.19 com.adobe.acc.installer.v2 588 | 3199 ?? 0:00.11 MessagesBlastDoorService 589 | 3219 ?? 0:00.36 IMTranscoderAgent 590 | 3220 ?? 0:00.27 MessagesBlastDoorService 591 | 3225 ?? 0:00.44 QtWebEngineProcess 592 | 3231 ?? 0:00.33 Adobe Installer 593 | 3238 ?? 0:38.31 MIDIServer 594 | 3252 ?? 0:00.01 PlugInLibraryService 595 | 3290 ?? 0:00.03 loginitemregisterd 596 | 3417 ?? 0:00.08 check_afp 597 | 3463 ?? 0:01.21 NIHostIntegrationAgent 598 | 3474 ?? 0:00.01 PlugInLibraryService 599 | 3811 ?? 0:00.01 PlugInLibraryService 600 | 3817 ?? 0:00.04 com.apple.audio.SandboxHelper 601 | 3842 ?? 0:03.77 VTDecoderXPCService 602 | 3892 ?? 0:04.37 com.apple.WebKit.WebContent 603 | 4064 ?? 0:03.52 newsd 604 | 4299 ?? 0:00.01 ssh-agent 605 | 4792 ?? 0:00.26 MTLCompilerService 606 | 5189 ?? 4:26.24 wdavdaemon_unprivileged 607 | 5231 ?? 1:20.97 Adobe_CCXProcess.node 608 | 6661 ?? 0:00.15 com.apple.iCloudHelper 609 | 6847 ?? 0:00.08 mdworker_shared 610 | 6901 ?? 0:00.09 Google Chrome Helper (Renderer) 611 | 6907 ?? 0:00.01 livefileproviderd 612 | 6910 ?? 0:00.04 mdworker_shared 613 | 6911 ?? 0:00.08 Microsoft Teams Helper (Renderer) 614 | 6919 ?? 0:00.33 weatherd 615 | 6965 ?? 0:04.58 PasswordBreachAgent 616 | 7051 ?? 0:00.08 CategoriesService 617 | 7154 ?? 21:40.07 Google Chrome 618 | 7158 ?? 0:00.05 chrome_crashpad_handler 619 | 7168 ?? 17:22.59 Google Chrome Helper (GPU) 620 | 7169 ?? 4:07.80 Google Chrome Helper 621 | 7172 ?? 0:09.23 Google Chrome Helper 622 | 7179 ?? 0:32.81 VTDecoderXPCService 623 | 7276 ?? 1:05.98 Google Chrome Helper 624 | 7277 ?? 0:00.10 VTEncoderXPCService 625 | 7278 ?? 0:00.05 com.apple.audio.SandboxHelper 626 | 8037 ?? 0:06.03 com.apple.WebKit.WebContent 627 | 8154 ?? 0:00.03 memoryanalyticsd 628 | 8587 ?? 0:22.49 PerfPowerServices 629 | 9855 ?? 0:00.95 Google Chrome Helper (Renderer) 630 | 9860 ?? 2:20.71 Google Chrome Helper (Renderer) 631 | 11391 ?? 0:13.75 Google Chrome Helper (Renderer) 632 | 11392 ?? 1:13.21 Google Chrome Helper (Renderer) 633 | 12262 ?? 0:05.35 Google Chrome Helper (Renderer) 634 | 12299 ?? 0:01.03 Google Chrome Helper (Renderer) 635 | 12391 ?? 0:01.56 DockHelper 636 | 12517 ?? 1:32.66 Discord 637 | 12519 ?? 0:00.06 chrome_crashpad_handler 638 | 12520 ?? 11:07.90 Discord Helper (GPU) 639 | 12521 ?? 0:08.02 Discord Helper 640 | 12522 ?? 0:00.10 VTDecoderXPCService 641 | 12524 ?? 0:00.09 VTEncoderXPCService 642 | 12525 ?? 55:33.27 Discord Helper (Renderer) 643 | 12538 ?? 0:01.33 Discord Helper 644 | 12559 ?? 0:00.03 com.apple.audio.SandboxHelper 645 | 12780 ?? 0:00.05 MTLCompilerService 646 | 13091 ?? 0:46.04 VTDecoderXPCService 647 | 14791 ?? 0:01.53 Microsoft Edge Helper (Renderer) 648 | 15236 ?? 0:00.04 com.apple.audio.SandboxHelper 649 | 15237 ?? 0:00.17 printtool 650 | 15249 ?? 0:05.11 com.apple.SafariPlatformSupport.Helper 651 | 15257 ?? 0:00.03 com.apple.ctkpcscd 652 | 16834 ?? 0:01.61 package_script_service 653 | 16956 ?? 0:00.25 appleaccountd 654 | 19881 ?? 0:00.81 LookupViewService 655 | 19927 ?? 0:02.32 photoanalysisd 656 | 34545 ?? 3:53.79 mds 657 | 34546 ?? 0:00.01 PlugInLibraryService 658 | 34547 ?? 7:26.80 mds_stores 659 | 34910 ?? 0:16.03 mdworker 660 | 35665 ?? 0:01.20 mdworker 661 | 35956 ?? 0:03.20 Google Chrome Helper (Renderer) 662 | 36179 ?? 0:04.89 Google Chrome Helper (Renderer) 663 | 36835 ?? 0:00.01 PlugInLibraryService 664 | 36858 ?? 0:00.06 DiskUnmountWatcher 665 | 36892 ?? 0:00.12 MTLCompilerService 666 | 37656 ?? 0:00.03 com.apple.audio.SandboxHelper 667 | 38408 ?? 0:01.62 SafariBookmarksSyncAgent 668 | 38426 ?? 0:09.63 backgroundassets.user 669 | 38451 ?? 0:00.38 proactiveeventtrackerd 670 | 43617 ?? 0:00.51 rcd 671 | 45219 ?? 0:19.25 MacVim 672 | 46487 ?? 0:01.06 QuickLookUIService 673 | 46519 ?? 0:00.01 com.apple.tonelibraryd 674 | 47161 ?? 3:09.65 Google Chrome Helper (Renderer) 675 | 48190 ?? 0:12.88 Docker 676 | 48191 ?? 4:00.51 com.docker.backend 677 | 48197 ?? 0:02.95 com.docker.backend 678 | 48228 ?? 0:37.31 Docker Desktop 679 | 48244 ?? 0:18.96 com.docker.vpnkit 680 | 48245 ?? 0:07.16 docker 681 | 48247 ?? 0:05.61 vpnkit-bridge 682 | 48248 ?? 0:02.05 com.docker.driver.amd64-linux 683 | 48249 ?? 0:03.66 com.docker.extensions 684 | 48250 ?? 0:01.04 com.docker.dev-envs 685 | 48251 ?? 0:00.00 686 | 48267 ?? 0:01.16 com.docker.virtualization 687 | 48273 ?? 44:33.09 com.apple.Virtualization.VirtualMachine 688 | 48276 ?? 0:02.62 Docker Desktop Helper (GPU) 689 | 48278 ?? 0:00.09 VTDecoderXPCService 690 | 48279 ?? 0:00.01 chrome_crashpad_handler 691 | 48280 ?? 0:00.21 Docker Desktop Helper 692 | 48282 ?? 102:20.33 Docker Desktop Helper (Renderer) 693 | 54642 ?? 0:00.39 ExternalQuickLookSatellite-x86_64 694 | 56167 ?? 0:00.03 com.apple.audio.SandboxHelper 695 | 56184 ?? 0:01.51 CallHistorySyncHelper 696 | 58119 ?? 0:09.07 Google Chrome Helper (Renderer) 697 | 58680 ?? 1:15.18 Google Chrome Helper (Renderer) 698 | 58795 ?? 0:00.12 dprivacyd 699 | 60829 ?? 0:00.02 XProtect 700 | 60830 ?? 0:02.14 XProtectPluginService 701 | 60834 ?? 0:00.02 XProtect 702 | 60835 ?? 0:01.99 XProtectPluginService 703 | 61051 ?? 0:00.21 MobileSMSSpotlightImporterCatalyst 704 | 61052 ?? 0:00.56 com.apple.photos.ImageConversionService 705 | 61053 ?? 0:00.59 MessagesBlastDoorService 706 | 62406 ?? 0:00.38 OSDUIHelper 707 | 69998 ?? 0:00.06 IMAutomaticHistoryDeletionAgent 708 | 71756 ?? 5:47.48 Google Chrome Helper (Renderer) 709 | 71932 ?? 0:00.40 Google Chrome Helper (Renderer) 710 | 71934 ?? 0:09.02 Google Chrome Helper (Renderer) 711 | 71935 ?? 0:09.62 Google Chrome Helper (Renderer) 712 | 71936 ?? 2:32.75 Google Chrome Helper (Renderer) 713 | 71945 ?? 0:30.75 Google Chrome Helper (Renderer) 714 | 71947 ?? 0:03.10 Google Chrome Helper (Renderer) 715 | 71948 ?? 0:03.27 Google Chrome Helper (Renderer) 716 | 71949 ?? 0:00.37 Google Chrome Helper (Renderer) 717 | 71950 ?? 0:03.83 Google Chrome Helper (Renderer) 718 | 71952 ?? 0:02.99 Google Chrome Helper (Renderer) 719 | 71954 ?? 0:03.32 Google Chrome Helper (Renderer) 720 | 71955 ?? 0:03.89 Google Chrome Helper (Renderer) 721 | 71956 ?? 0:00.35 Google Chrome Helper (Renderer) 722 | 71957 ?? 0:04.67 Google Chrome Helper (Renderer) 723 | 71958 ?? 0:04.04 Google Chrome Helper (Renderer) 724 | 71959 ?? 0:00.36 Google Chrome Helper (Renderer) 725 | 71960 ?? 0:02.95 Google Chrome Helper (Renderer) 726 | 71968 ?? 0:03.44 Google Chrome Helper (Renderer) 727 | 71969 ?? 1:29.94 Google Chrome Helper (Renderer) 728 | 71970 ?? 0:00.97 Google Chrome Helper (Renderer) 729 | 72680 ?? 1:46.97 bluetoothd 730 | 72703 ?? 0:00.01 IOUserBluetoothSerialDriver 731 | 73627 ?? 0:12.27 Google Chrome Helper (Renderer) 732 | 75548 ?? 0:03.74 knowledgeconstructiond 733 | 76900 ?? 0:01.81 Google Chrome Helper (Renderer) 734 | 78475 ?? 0:00.92 QtWebEngineProcess 735 | 78476 ?? 0:00.92 QtWebEngineProcess 736 | 82319 ?? 0:00.01 PlugInLibraryService 737 | 84170 ?? 0:00.03 CalendarWidgetExtension 738 | 87412 ?? 0:00.02 griddatad 739 | 87439 ?? 0:00.03 devicecheckd 740 | 87490 ?? 0:00.10 EscrowSecurityAlert 741 | 87536 ?? 0:00.01 periodic-wrapper 742 | 87692 ?? 0:00.15 applessdstatistics 743 | 87749 ?? 0:00.03 sysdiagnose 744 | 87806 ?? 0:00.05 proactived 745 | 90659 ?? 0:00.33 nbagent 746 | 90662 ?? 0:00.03 nbstated 747 | 90884 ?? 0:00.68 contactsdonationagent 748 | 92805 ?? 0:00.01 chrome_crashpad_handler 749 | 94130 ?? 0:53.23 Electron 750 | 94134 ?? 0:00.01 chrome_crashpad_handler 751 | 94135 ?? 3:09.45 Code Helper (GPU) 752 | 94136 ?? 0:00.20 Code Helper 753 | 94137 ?? 0:00.10 VTDecoderXPCService 754 | 94138 ?? 5:26.03 Code Helper (Renderer) 755 | 94152 ?? 0:16.74 Code Helper (Renderer) 756 | 94153 ?? 1:44.58 Code Helper (Plugin) 757 | 94154 ?? 0:13.43 Code Helper (Renderer) 758 | 94163 ?? 0:00.60 Code Helper (Renderer) 759 | 94191 ?? 0:35.64 Code Helper (Plugin) 760 | 94227 ?? 2:06.71 dotnet 761 | 94286 ?? 0:00.50 Code Helper (Plugin) 762 | 97977 ?? 4:53.90 Google Chrome Helper (Renderer) 763 | 98046 ?? 0:02.69 Google Chrome Helper (Renderer) 764 | 98053 ?? 0:22.99 Google Chrome Helper (Renderer) 765 | 98054 ?? 0:05.17 Google Chrome Helper (Renderer) 766 | 98058 ?? 0:02.85 Google Chrome Helper (Renderer) 767 | 98059 ?? 0:02.85 Google Chrome Helper (Renderer) 768 | 98060 ?? 0:02.74 Google Chrome Helper (Renderer) 769 | 98061 ?? 0:03.55 Google Chrome Helper (Renderer) 770 | 98062 ?? 0:02.95 Google Chrome Helper (Renderer) 771 | 98067 ?? 0:02.95 Google Chrome Helper (Renderer) 772 | 98076 ?? 0:02.66 Google Chrome Helper (Renderer) 773 | 98080 ?? 0:02.82 Google Chrome Helper (Renderer) 774 | 98366 ?? 0:04.48 Google Chrome Helper (Renderer) 775 | 2587 ttys000 0:00.03 login 776 | 2596 ttys000 4:07.88 pwsh 777 | 5350 ttys000 0:11.76 pwsh 778 | 6924 ttys000 0:00.01 ps 779 | 2597 ttys001 0:00.02 login 780 | 2601 ttys001 0:48.31 pwsh 781 | 2661 ttys002 0:27.98 pwsh 782 | 2669 ttys003 0:27.37 pwsh 783 | 2674 ttys004 0:27.75 pwsh 784 | 2676 ttys005 0:27.57 pwsh 785 | 94197 ttys006 1:07.57 pwsh 786 | 94200 ttys007 0:05.13 pwsh 787 | -------------------------------------------------------------------------------- /test/assets/tasklist.01.txt: -------------------------------------------------------------------------------- 1 | 2 | Image Name PID Session Name Session# Mem Usage 3 | ========================= ======== ================ =========== ============ 4 | System Idle Process 0 Services 0 8 K 5 | System 4 Services 0 8,240 K 6 | Secure System 104 Services 0 73,736 K 7 | Registry 172 Services 0 169,772 K 8 | smss.exe 800 Services 0 1,228 K 9 | csrss.exe 944 Services 0 4,984 K 10 | svchost.exe 2380 Services 0 9,032 K 11 | svchost.exe 3584 Services 0 9,668 K 12 | svchost.exe 3808 Services 0 8,132 K 13 | svchost.exe 3892 Services 0 7,812 K 14 | spoolsv.exe 4000 Services 0 26,872 K 15 | svchost.exe 3572 Services 0 13,732 K 16 | vmms.exe 2956 Services 0 84,248 K 17 | dfsrs.exe 4360 Services 0 114,964 K 18 | ismserv.exe 4368 Services 0 4,920 K 19 | ssh-agent.exe 4376 Services 0 3,504 K 20 | TCPSVCS.EXE 4384 Services 0 2,960 K 21 | TFSJobAgent.exe 4392 Services 0 118,204 K 22 | sqlwriter.exe 4400 Services 0 21,088 K 23 | sshd.exe 4408 Services 0 5,328 K 24 | Microsoft.ActiveDirectory 4416 Services 0 46,780 K 25 | inetinfo.exe 4504 Services 0 30,960 K 26 | smartscreen.exe 6248 RDP-Tcp#33 2 29,940 K 27 | svchost.exe 10088 Services 0 9,840 K 28 | svchost.exe 9740 Services 0 19,360 K 29 | svchost.exe 2100 Services 0 10,784 K 30 | SecurityHealthService.exe 3276 Services 0 12,824 K 31 | mmc.exe 9760 RDP-Tcp#33 2 62,316 K 32 | pwsh.exe 8660 RDP-Tcp#33 2 112,700 K 33 | conhost.exe 8060 RDP-Tcp#33 2 23,048 K 34 | WmiPrvSE.exe 9372 Services 0 10,928 K 35 | WmiPrvSE.exe 8084 Services 0 43,156 K 36 | vmconnect.exe 6352 RDP-Tcp#33 2 242,068 K 37 | vmwp.exe 9444 Services 0 48,084 K 38 | powershell.exe 11132 RDP-Tcp#33 2 177,552 K 39 | conhost.exe 2744 RDP-Tcp#33 2 28,044 K 40 | powershell.exe 4592 RDP-Tcp#33 2 127,172 K 41 | conhost.exe 11316 RDP-Tcp#33 2 8,440 K 42 | svchost.exe 8104 Services 0 8,016 K 43 | MsMpEng.exe 10232 Services 0 247,404 K 44 | NisSrv.exe 11852 Services 0 11,500 K 45 | dllhost.exe 11552 RDP-Tcp#33 2 12,572 K 46 | TrustedInstaller.exe 4652 Services 0 7,276 K 47 | TiWorker.exe 9996 Services 0 8,992 K 48 | tasklist.exe 10660 RDP-Tcp#33 2 7,976 K 49 | -------------------------------------------------------------------------------- /test/assets/tasklist.02.txt: -------------------------------------------------------------------------------- 1 | 2 | Image Name PID Session Name Session# Mem Usage 3 | ========================= ======== ================ =========== ============ 4 | System Idle Process 0 Services 0 8 K 5 | System 4 Services 0 8,240 K 6 | Secure System 104 Services 0 73,736 K 7 | Registry 172 Services 0 169,772 K 8 | smss.exe 800 Services 0 1,228 K 9 | csrss.exe 944 Services 0 4,984 K 10 | csrss.exe 1020 Console 1 3,948 K 11 | wininit.exe 128 Services 0 5,296 K 12 | winlogon.exe 876 Console 1 7,924 K 13 | services.exe 948 Services 0 18,948 K 14 | LsaIso.exe 1044 Services 0 2,404 K 15 | lsass.exe 1056 Services 0 197,156 K 16 | svchost.exe 1340 Services 0 2,932 K 17 | svchost.exe 1364 Services 0 24,896 K 18 | svchost.exe 1412 Services 0 18,576 K 19 | svchost.exe 1456 Services 0 12,284 K 20 | LogonUI.exe 1536 Console 1 40,880 K 21 | dwm.exe 1544 Console 1 32,964 K 22 | svchost.exe 1568 Services 0 144,208 K 23 | svchost.exe 1600 Services 0 9,444 K 24 | mmc.exe 9760 RDP-Tcp#33 2 62,316 K 25 | pwsh.exe 8660 RDP-Tcp#33 2 112,700 K 26 | conhost.exe 8060 RDP-Tcp#33 2 23,048 K 27 | WmiPrvSE.exe 9372 Services 0 10,928 K 28 | WmiPrvSE.exe 8084 Services 0 43,156 K 29 | vmconnect.exe 6352 RDP-Tcp#33 2 242,068 K 30 | vmwp.exe 9444 Services 0 48,084 K 31 | powershell.exe 11132 RDP-Tcp#33 2 177,552 K 32 | conhost.exe 2744 RDP-Tcp#33 2 28,044 K 33 | powershell.exe 4592 RDP-Tcp#33 2 127,172 K 34 | conhost.exe 11316 RDP-Tcp#33 2 8,440 K 35 | svchost.exe 8104 Services 0 8,016 K 36 | MsMpEng.exe 10232 Services 0 247,404 K 37 | NisSrv.exe 11852 Services 0 11,500 K 38 | dllhost.exe 11552 RDP-Tcp#33 2 12,572 K 39 | TrustedInstaller.exe 4652 Services 0 7,276 K 40 | TiWorker.exe 9996 Services 0 8,992 K 41 | tasklist.exe 10660 RDP-Tcp#33 2 7,976 K 42 | -------------------------------------------------------------------------------- /test/assets/who.01.txt: -------------------------------------------------------------------------------- 1 | reboot ~ Sep 14 10:10 00:04 1 2 | james console Sep 14 10:11 old 283 3 | james ttys000 Sep 26 13:12 00:09 50821 term=0 exit=0 4 | james ttys001 Oct 12 16:58 . 73518 5 | james ttys002 Oct 5 16:36 . 90609 term=0 exit=0 6 | james ttys006 Oct 11 15:41 . 25351 term=0 exit=0 7 | -------------------------------------------------------------------------------- /test/assets/who.02.txt: -------------------------------------------------------------------------------- 1 | NAME LINE TIME FROM 2 | james console Feb 14 09:35 3 | james ttys000 Feb 14 09:45 4 | james ttys001 Feb 14 09:45 5 | -------------------------------------------------------------------------------- /yaml/ci.yml: -------------------------------------------------------------------------------- 1 | name: $(Date:yyyyMMdd)$(Rev:.rr) 2 | trigger: 3 | # Batch merge builds together while a merge build is running 4 | batch: true 5 | branches: 6 | include: 7 | - main 8 | - release* 9 | pr: 10 | branches: 11 | include: 12 | - main 13 | - release* 14 | 15 | resources: 16 | repositories: 17 | - repository: ComplianceRepo 18 | type: github 19 | endpoint: ComplianceGHRepo 20 | name: PowerShell/compliance 21 | 22 | stages: 23 | - stage: Build 24 | displayName: Build Microsoft.PowerShell.TextUtility 25 | jobs: 26 | - job: Build 27 | displayName: Build 28 | pool: 29 | vmImage: windows-latest 30 | steps: 31 | - pwsh: | 32 | ./build.ps1 -Clean 33 | displayName: Build 34 | - publish: "out/" 35 | artifact: out 36 | 37 | - stage: Test 38 | displayName: Test Microsoft.PowerShell.TextUtility 39 | jobs: 40 | - template: template/runtest.yml 41 | parameters: 42 | vmImageName: windows-latest 43 | jobName: run_test_windows 44 | jobDisplayName: Run tests Windows 45 | 46 | - template: template/runtest.yml 47 | parameters: 48 | vmImageName: ubuntu-latest 49 | jobName: run_test_ubuntu 50 | jobDisplayName: Run tests Ubuntu 51 | 52 | - template: template/runtest.yml 53 | parameters: 54 | vmImageName: macos-latest 55 | jobName: run_test_macos 56 | jobDisplayName: Run tests macOS 57 | 58 | - stage: Compliance 59 | displayName: Compliance Microsoft.PowerShell.TextUtility 60 | dependsOn: Build 61 | jobs: 62 | - job: Compliance_Job 63 | pool: 64 | vmImage: windows-latest 65 | steps: 66 | - checkout: self 67 | - checkout: ComplianceRepo 68 | - template: ci-compliance.yml@ComplianceRepo 69 | -------------------------------------------------------------------------------- /yaml/releaseBuild.yml: -------------------------------------------------------------------------------- 1 | # release build 2 | name: TextUtility-Release-$(Date:yyyyMMdd)$(Rev:.rr) 3 | trigger: none 4 | 5 | pr: none 6 | 7 | variables: 8 | DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 9 | DOTNET_CLI_TELEMETRY_OPTOUT: 1 10 | POWERSHELL_TELEMETRY_OPTOUT: 1 11 | 12 | resources: 13 | repositories: 14 | - repository: ComplianceRepo 15 | type: github 16 | endpoint: ComplianceGHRepo 17 | name: PowerShell/compliance 18 | ref: master 19 | 20 | stages: 21 | - stage: BuildAndSign 22 | displayName: Build and Sign 23 | pool: 24 | name: PowerShell1ES 25 | demands: 26 | - ImageOverride -equals PSMMS2019-Secure 27 | jobs: 28 | - job: 'BuildAndSign' 29 | displayName: Build and Sign 30 | variables: 31 | - group: ESRP 32 | steps: 33 | - checkout: self 34 | 35 | - task: UseDotNet@2 36 | displayName: 'Use .NET Core sdk' 37 | inputs: 38 | packageType: sdk 39 | includePreviewVersions: true 40 | version: 6.x 41 | 42 | - pwsh: | 43 | Get-ChildItem -Path env: 44 | displayName: Capture environment 45 | condition: succeededOrFailed() 46 | 47 | - pwsh: | 48 | Set-Location "$(Build.SourcesDirectory)/TextUtility" 49 | Get-ChildItem -Recurse -File -Name | Write-Verbose -Verbose 50 | ./build.ps1 51 | Get-ChildItem -Recurse -File -Name | Write-Verbose -Verbose 52 | 53 | displayName: Execute Build 54 | 55 | - pwsh: | 56 | Set-Location "$(Build.SourcesDirectory)/TextUtility" 57 | $signSrcPath = "$(Build.SourcesDirectory)/TextUtility/out" 58 | # Set signing src path variable 59 | $vstsCommandString = "vso[task.setvariable variable=signSrcPath]${signSrcPath}" 60 | Write-Host ("sending " + $vstsCommandString) 61 | Write-Host "##$vstsCommandString" 62 | 63 | $signOutPath = "$(Build.SourcesDirectory)/TextUtility/signed" 64 | $null = New-Item -ItemType Directory -Path $signOutPath 65 | # Set signing out path variable 66 | $vstsCommandString = "vso[task.setvariable variable=signOutPath]${signOutPath}" 67 | Write-Host "sending " + $vstsCommandString 68 | Write-Host "##$vstsCommandString" 69 | 70 | # Set path variable for guardian codesign validation 71 | $vstsCommandString = "vso[task.setvariable variable=GDN_CODESIGN_TARGETDIRECTORY]${signOutPath}" 72 | Write-Host "sending " + $vstsCommandString 73 | Write-Host "##$vstsCommandString" 74 | 75 | $packageVersion = ./build.ps1 -GetPackageVersion 76 | $vstsCommandString = "vso[task.setvariable variable=PackageVersion]$packageVersion" 77 | Write-Host ("sending " + $vstsCommandString) 78 | Write-Host "##$vstsCommandString" 79 | 80 | displayName: Setup variables for signing 81 | 82 | - publish: "$(Build.SourcesDirectory)/TextUtility/out/" 83 | artifact: out 84 | 85 | displayName: Publish unsigned module files 86 | 87 | - checkout: ComplianceRepo 88 | 89 | - template: EsrpSign.yml@ComplianceRepo 90 | parameters: 91 | # the folder which contains the binaries to sign 92 | buildOutputPath: $(signSrcPath) 93 | # the location to put the signed output 94 | signOutputPath: $(signOutPath) 95 | # the certificate ID to use 96 | certificateId: "CP-230012" 97 | # The file pattern to use 98 | # If not using minimatch: comma separated, with * supported 99 | # If using minimatch: newline separated, with !, **, and * supported. 100 | # See link in the useMinimatch comments. 101 | pattern: '*.dll,*.psd1,*.psm1,*.ps1xml' 102 | # decides if the task should use minimatch for the pattern matching. 103 | # https://github.com/isaacs/minimatch#features 104 | useMinimatch: false 105 | 106 | # 107 | - pwsh: | 108 | $repoRoot = "$(Build.SourcesDirectory)/TextUtility" 109 | Set-Location $repoRoot 110 | Get-ChildItem -Path ${repoRoot} -File -Recurse | Out-String -Str | Write-Verbose -Verbose 111 | Copy-Item -Path "${repoRoot}/src/dictionary.txt" "${repoRoot}/signed/Microsoft.PowerShell.TextUtility" 112 | 113 | displayName: Copy dictionary.txt 114 | 115 | - template: Sbom.yml@ComplianceRepo 116 | parameters: 117 | BuildDropPath: $(Build.SourcesDirectory)/TextUtility/signed/Microsoft.PowerShell.TextUtility 118 | Build_Repository_Uri: 'https://github.com/powershell/textutility' 119 | PackageName: 'Microsoft.PowerShell.TextUtility' 120 | PackageVersion: $(PackageVersion) 121 | 122 | - pwsh: | 123 | set-location $(Build.SourcesDirectory)/TextUtility 124 | ./build.ps1 -Package -Signed -NoBuild 125 | New-Item -Type Directory nupkg 126 | Copy-Item *.nupkg nupkg -ErrorAction Ignore -Verbose 127 | Get-ChildItem -Recurse -File -Name | out-string -str | Write-Verbose -Verbose 128 | 129 | displayName: Construct Signed Module with SBOM 130 | 131 | - pwsh: | 132 | New-Item -Path $(Build.SourcesDirectory)/TextUtility/SignedZip -ItemType Directory -ErrorAction Ignore 133 | Compress-Archive -Path $(Build.SourcesDirectory)/TextUtility/signed/Microsoft.PowerShell.TextUtility -DestinationPath $(Build.SourcesDirectory)/TextUtility/SignedZip/Microsoft.PowerShell.TextUtility.zip -Force 134 | 135 | displayName: 'Compress archive' 136 | condition: succeededOrFailed() 137 | 138 | - task: PublishPipelineArtifact@1 139 | inputs: 140 | targetpath: $(Build.SourcesDirectory)/TextUtility/signed/Microsoft.PowerShell.TextUtility 141 | artifactName: Signed 142 | 143 | - task: PublishPipelineArtifact@1 144 | inputs: 145 | targetpath: $(Build.SourcesDirectory)/TextUtility/SignedZip 146 | artifactName: SignedZip 147 | 148 | - task: PublishPipelineArtifact@1 149 | inputs: 150 | targetpath: $(Build.SourcesDirectory)/TextUtility/nupkg 151 | artifactName: nupkg 152 | 153 | - stage: compliance 154 | displayName: Compliance 155 | dependsOn: BuildAndSign 156 | jobs: 157 | - job: Compliance_Job 158 | pool: 159 | name: PowerShell1ES 160 | demands: 161 | - ImageOverride -equals PSMMS2019-Secure 162 | steps: 163 | - checkout: self 164 | - checkout: ComplianceRepo 165 | - download: current 166 | artifact: Signed 167 | 168 | - pwsh: | 169 | Get-ChildItem -Path "$(Pipeline.Workspace)\Signed" -Recurse 170 | 171 | displayName: Capture downloaded artifacts 172 | 173 | - template: assembly-module-compliance.yml@ComplianceRepo 174 | parameters: 175 | # binskim 176 | AnalyzeTarget: '$(Pipeline.Workspace)\*.dll' 177 | AnalyzeSymPath: 'SRV*' 178 | # component-governance 179 | sourceScanPath: '$(Build.SourcesDirectory)' 180 | # credscan 181 | suppressionsFile: '' 182 | # TermCheck 183 | optionsRulesDBPath: '' 184 | optionsFTPath: '' 185 | # tsa-upload 186 | codeBaseName: 'textutility_202305' 187 | # selections 188 | APIScan: false # set to false when not using Windows APIs. 189 | -------------------------------------------------------------------------------- /yaml/template/runtest.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | vmImageName: 'windows-latest' 3 | jobName: 'run_test_windows' 4 | jobDisplayName: 'Run test' 5 | 6 | jobs: 7 | - job: '${{ parameters.jobName }}_netstandard20' 8 | pool: 9 | vmImage: ${{ parameters.vmImageName }} 10 | displayName: ${{ parameters.jobDisplayName }} - Test 11 | steps: 12 | - task: DownloadPipelineArtifact@2 13 | inputs: 14 | artifactName: out 15 | targetPath: '$(Build.SourcesDirectory)/out' 16 | - pwsh: | 17 | Import-Module ./out/Microsoft.PowerShell.TextUtility 18 | Invoke-Pester -Path ./test -OutputFormat NUnitXml -EnableExit 19 | condition: succeeded() 20 | --------------------------------------------------------------------------------