DpkgPackage.psm1
#Region './prefix.ps1' 0 Import-Module -Name $PSScriptRoot\Modules\PSNativeCmdDevKit -ErrorAction Stop #EndRegion './prefix.ps1' 1 #Region './Classes/1.Package.ps1' 0 if (-not ('Package' -as [type])) { class Package { $Name $PackageType $Version $Vendor } } #EndRegion './Classes/1.Package.ps1' 11 #Region './Classes/DpkgPackage.ps1' 0 #using module Package class DpkgPackage : Package { # https://www.debian.org/doc/debian-policy/ch-controlfields.html # This field identifies the source package name. $Source # The package maintainer’s name and email address. # The name must come first, then the email address inside angle brackets <> (in RFC822 format). $Maintainer # List of the names and email addresses of co-maintainers of the package, if any. $Uploaders # The name and email address of the person who prepared this version of the package, # usually a maintainer. The syntax is the same as for the Maintainer field. $ChangedBy # This field specifies an application area into which the package has been classified. # See Sections. $Section # This field represents how important it is that the user have the package installed. # See Priorities. $Priority # The name of the binary package. # Binary package names must follow the same syntax and restrictions as source package names. # See Source for the details. # This also populates the Name property of the [Package] parent class $Package # Depending on context and the control file used, the Architecture field can include the following sets of values: # - A unique single word identifying a Debian machine architecture as described in Architecture specification strings. # (https://www.debian.org/doc/debian-policy/ch-customized-programs.html#s-arch-spec) # - An architecture wildcard identifying a set of Debian machine architectures, see Architecture wildcards. # (https://www.debian.org/doc/debian-policy/ch-customized-programs.html#s-arch-wildcard-spec) # `any` matches all Debian machine architectures and is the most frequently used. # - all, which indicates an architecture-independent package. # - source, which indicates a source package. $Architecture # This is a boolean field which may occur only in the control file of a binary package or # in a per-package fields paragraph of a source package control file. # If set to yes then the package management system will refuse to remove the package # (upgrading and replacing it is still possible). # The other possible value is no, which is the same as not having the field at all. $Essential #region Package interrelationship fields # These fields describe the package’s relationships with other packages. # Their syntax and semantics are described in Declaring relationships between packages. # (https://www.debian.org/doc/debian-policy/ch-relationships.html) $Depends $PreDepends $Recommends $Suggests $Breaks $Conflicts $Provides $Replaces $Enhances #endregion Package interrelationship fields $StandardsVersion # $Version # defined in Parent Class [Package] $Description $Distribution $Date $Format $Urgency $Changes $Binary $InstalledSize $Files $Closes $Homepage $ChecksumsSha1 $ChecksumsSha256 $DMUploadAllowed # obsolete $PackageList $PackageType $Dgit $TestSuite $RulesRequiresRoot # Additional Fields $Status $OriginalMaintainer $MultiArch $Conffiles $AdditionalFields = @{} } #EndRegion './Classes/DpkgPackage.ps1' 98 #Region './Private/Get-DpkgCmdArgument.ps1' 0 # Usage: dpkg [<option> ...] <command> # Commands: # -i|--install <.deb file name> ... | -R|--recursive <directory> ... # --unpack <.deb file name> ... | -R|--recursive <directory> ... # -A|--record-avail <.deb file name> ... | -R|--recursive <directory> ... # --configure <package> ... | -a|--pending # --triggers-only <package> ... | -a|--pending # -r|--remove <package> ... | -a|--pending # -P|--purge <package> ... | -a|--pending # -V|--verify <package> ... Verify the integrity of package(s). # --get-selections [<pattern> ...] Get list of selections to stdout. # --set-selections Set package selections from stdin. # --clear-selections Deselect every non-essential package. # --update-avail [<Packages-file>] Replace available packages info. # --merge-avail [<Packages-file>] Merge with info from file. # --clear-avail Erase existing available info. # --forget-old-unavail Forget uninstalled unavailable pkgs. # -s|--status <package> ... Display package status details. # -p|--print-avail <package> ... Display available version details. # -L|--listfiles <package> ... List files 'owned' by package(s). # -l|--list [<pattern> ...] List packages concisely. # -S|--search <pattern> ... Find package(s) owning file(s). # -C|--audit [<package> ...] Check for broken package(s). # --yet-to-unpack Print packages selected for installation. # --predep-package Print pre-dependencies to unpack. # --add-architecture <arch> Add <arch> to the list of architectures. # --remove-architecture <arch> Remove <arch> from the list of architectures. # --print-architecture Print dpkg architecture. # --print-foreign-architectures Print allowed foreign architectures. # --assert-<feature> Assert support for the specified feature. # --validate-<thing> <string> Validate a <thing>'s <string>. # --compare-versions <a> <op> <b> Compare version numbers - see below. # --force-help Show help on forcing. # -Dh|--debug=help Show help on debugging. # -?, --help Show this help message. # --version Show the version. # Assertable features: support-predepends, working-epoch, long-filenames, # multi-conrep, multi-arch, versioned-provides. # Validatable things: pkgname, archname, trigname, version. # Use dpkg with -b, --build, -c, --contents, -e, --control, -I, --info, # -f, --field, -x, --extract, -X, --vextract, --ctrl-tarfile, --fsys-tarfile # on archives (type dpkg-deb --help). # Options: # --admindir=<directory> Use <directory> instead of /var/lib/dpkg. # --root=<directory> Install on a different root directory. # --instdir=<directory> Change installation dir without changing admin dir. # --path-exclude=<pattern> Do not install paths which match a shell pattern. # --path-include=<pattern> Re-include a pattern after a previous exclusion. # -O|--selected-only Skip packages not selected for install/upgrade. # -E|--skip-same-version Skip packages whose same version is installed. # -G|--refuse-downgrade Skip packages with earlier version than installed. # -B|--auto-deconfigure Install even if it would break some other package. # --[no-]triggers Skip or force consequential trigger processing. # --verify-format=<format> Verify output format (supported: 'rpm'). # --no-debsig Do not try to verify package signatures. # --no-act|--dry-run|--simulate # Just say what we would do - don't do it. # -D|--debug=<octal> Enable debugging (see -Dhelp or --debug=help). # --status-fd <n> Send status change updates to file descriptor <n>. # --status-logger=<command> Send status change updates to <command>'s stdin. # --log=<filename> Log status changes and actions to <filename>. # --ignore-depends=<package>,... # Ignore dependencies involving <package>. # --force-... Override problems (see --force-help). # --no-force-...|--refuse-... # Stop when problems encountered. function Get-DpkgCmdArgument { [CmdletBinding()] param ( #Commands [Parameter()] $Info, [Parameter()] $Install, [Parameter()] $Unpack, [Parameter()] $RecordAvailble, [Parameter()] $Configure, [Parameter()] $TriggersOnly, [Parameter()] $Remove, [Parameter()] $Purge, [Parameter()] $Verify, [Parameter()] $GetSelections, [Parameter()] $SetSelections, [Parameter()] $UpdateAvailable, [Parameter()] $MergeAvailable, [Parameter()] $ClearAvailable, [Parameter()] $ForgetOldUnavailable, [Parameter()] [AllowNull()] [string] $Status, [Parameter()] $PrintAvailable, [Parameter()] $ListFiles, [Parameter()] [AllowNull()] [String] $List, [Parameter()] $Search, [Parameter()] $Audit, [Parameter()] $YetToUnpack, [Parameter()] $Predependencies, [Parameter()] $AddArchitecture, [Parameter()] $RemoveArchitecture, [Parameter()] $PrintArchitecture, [Parameter()] $PrintForeignArchitecture, [Parameter()] $Assert, [Parameter()] $Validate, [Parameter()] $CompareVersion, [Parameter()] $ForceHelp, [Parameter()] $DebugHelp, [Parameter()] $Help, # options [Parameter()] $AdminDir, [Parameter()] $RootDir, [Parameter()] $InstallDir, [Parameter()] $PathExclude, [Parameter()] $PathInclude, [Parameter()] $SelectedOnly, [Parameter()] $SkipSameVersion, [Parameter()] $RefuseDowngrade, [Parameter()] $AutoDeconfigure, [Parameter()] $NoTriggers, [Parameter()] $Triggers, [Parameter()] $VerifyFormat, [Parameter()] $NoDebsig, #WhatIf == --dry-run [Parameter()] $StatusFileDescriptor, [Parameter()] $StatusLogger, [Parameter()] $Log, [Parameter()] $IgnoreDepends, [Parameter()] $Force # Refuse / --no-force -eq ErrorAction Stop ) $dpkgOption = switch ($PSBoundParameters.Keys) { 'AdminDir' { throw 'Not Implemented Yet.' } 'RootDir' { throw 'Not Implemented Yet.' } 'InstallDir' { throw 'Not Implemented Yet.' } 'PathExclude' { throw 'Not Implemented Yet.' } 'PathInclude' { throw 'Not Implemented Yet.' } 'SelectedOnly' { throw 'Not Implemented Yet.' } 'SkipSameVersion' { throw 'Not Implemented Yet.' } 'RefuseDowngrade' { throw 'Not Implemented Yet.' } 'AutoDeconfigure' { throw 'Not Implemented Yet.' } 'NoTriggers' { throw 'Not Implemented Yet.' } 'Triggers' { throw 'Not Implemented Yet.' } 'VerifyFormat' { throw 'Not Implemented Yet.' } 'NoDebsig' { throw 'Not Implemented Yet.' } # WhatIf == --dry-run { throw 'Not Implemented Yet.' } 'StatusFileDescriptor' { throw 'Not Implemented Yet.' } 'StatusLogger' { throw 'Not Implemented Yet.' } 'Log' { throw 'Not Implemented Yet.' } 'IgnoreDepends' { throw 'Not Implemented Yet.' } 'Force' { throw 'Not Implemented Yet.' } # Refuse / --no-force -eq ErrorAction Stop } $dpkgCommand = switch ($PSBoundParameters.Keys) { 'Info' { "--info '$($Info -join "'")'" } 'Install' { throw 'Not Implemented Yet.'} 'Unpack' { throw 'Not Implemented Yet.'} 'RecordAvailble' { throw 'Not Implemented Yet.'} 'Configure' { throw 'Not Implemented Yet.'} 'TriggersOnly' { throw 'Not Implemented Yet.'} 'Remove' { throw 'Not Implemented Yet.'} 'Purge' { throw 'Not Implemented Yet.'} 'Verify' { throw 'Not Implemented Yet.'} 'GetSelections' { throw 'Not Implemented Yet.'} 'SetSelections' { throw 'Not Implemented Yet.'} 'UpdateAvailable' { throw 'Not Implemented Yet.'} 'MergeAvailable' { throw 'Not Implemented Yet.'} 'ClearAvailable' { throw 'Not Implemented Yet.'} 'ForgetOldUnavailable' { throw 'Not Implemented Yet.'} 'Status' { "-s$(if ($Status) {" '$Status'"})"} 'PrintAvailable' { throw 'Not Implemented Yet.'} 'ListFiles' { throw 'Not Implemented Yet.'} 'List' { "-l $List" } 'Search' { throw 'Not Implemented Yet.'} 'Audit' { throw 'Not Implemented Yet.'} 'YetToUnpack' { throw 'Not Implemented Yet.'} 'Predependencies' { throw 'Not Implemented Yet.'} 'AddArchitecture' { throw 'Not Implemented Yet.'} 'RemoveArchitecture' { throw 'Not Implemented Yet.'} 'PrintArchitecture' { throw 'Not Implemented Yet.'} 'PrintForeignArchitecture' { throw 'Not Implemented Yet.'} 'Assert' { throw 'Not Implemented Yet.'} 'Validate' { throw 'Not Implemented Yet.'} 'CompareVersion' { throw 'Not Implemented Yet.'} 'ForceHelp' { throw 'Not Implemented Yet.'} 'DebugHelp' { throw 'Not Implemented Yet.'} 'Help' { throw 'Not Implemented Yet.'} } return ($dpkgOption + $dpkgCommand) } #EndRegion './Private/Get-DpkgCmdArgument.ps1' 306 #Region './Private/Get-DpkgQueryCmdArgument.ps1' 0 # Usage: dpkg-query [<option> ...] <command> # Commands: # -s|--status <package> ... Display package status details. # -p|--print-avail <package> ... Display available version details. # -L|--listfiles <package> ... List files 'owned' by package(s). # -l|--list [<pattern> ...] List packages concisely. # -W|--show [<pattern> ...] Show information on package(s). # -S|--search <pattern> ... Find package(s) owning file(s). # --control-list <package> Print the package control file list. # --control-show <package> <file> # Show the package control file. # -c|--control-path <package> [<file>] # Print path for package control file. # -?, --help Show this help message. # --version Show the version. # Options: # --admindir=<directory> Use <directory> instead of /var/lib/dpkg. # --load-avail Use available file on --show and --list. # -f|--showformat=<format> Use alternative format for --show. # Format syntax: # A format is a string that will be output for each package. The format # can include the standard escape sequences \n (newline), \r (carriage # return) or \\ (plain backslash). Package information can be included # by inserting variable references to package fields using the ${var[;width]} # syntax. Fields will be right-aligned unless the width is negative in which # case left alignment will be used. function Get-DpkgQueryCmdArgument { [CmdletBinding()] param ( [Parameter()] $Show, [Parameter()] $List, [Parameter()] $ListFiles ) $dpkgOption = switch ($PSBoundParameters.Keys) { 'AdminDir' { throw 'Not Implemented Yet.' } } $dpkgCommand = switch ($PSBoundParameters.Keys) { # -s|--status <package> ... Display package status details. # -p|--print-avail <package> ... Display available version details. # -L|--listfiles <package> ... List files 'owned' by package(s). 'ListFiles' {"-L '$ListFiles"} # -l|--list [<pattern> ...] List packages concisely. 'List' { "-l $List"} # -W|--show [<pattern> ...] Show information on package(s). 'Show' { "-W '$($Show -join "' '")'"} # -S|--search <pattern> ... Find package(s) owning file(s). # --control-list <package> Print the package control file list. # --control-show <package> <file> # Show the package control file. # -c|--control-path <package> [<file>] # Print path for package control file. # -?, --help Show this help message. # --version Show the version. } return ($dpkgOption + $dpkgCommand) } #EndRegion './Private/Get-DpkgQueryCmdArgument.ps1' 76 #Region './Public/Get-DpkgInstalledPackage.ps1' 0 function Get-DpkgInstalledPackage { [CmdletBinding()] param ( [Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName, Position = 0)] [Alias('Package')] [string[]] $Name ) process { # Debian policy says Package name must be lowercase, making the user a service by forcing ToLower() # https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-source $Name = $Name.ForEach{$_.ToLower()} Invoke-NativeCommand -Executable 'dpkg-query' -Parameters (Get-DpkgQueryCmdArgument -Show $Name) | ForEach-Object { $dpkgPackage = $_ -split "`t" if ($_ -is [System.Management.Automation.ErrorRecord]) { switch -Regex ($_) { # this Adds a way to process the error stream in a customized way. # 'no\spackages\sfound' { throw "Package $($Name) not found." } # Use this if you wan to throw when this error is raised default { Write-Error "$_." } } } else { [PSCustomObject]@{ PSTypeName = 'DpkgPackage.Installed' Name = $dpkgPackage[0] Version = $dpkgPackage[1] } } } } } #EndRegion './Public/Get-DpkgInstalledPackage.ps1' 38 #Region './Public/Get-DpkgPackage.ps1' 0 function Get-DpkgPackage { [CmdletBinding(DefaultParameterSetName = 'dpkgInstalledPackage')] param ( [Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName, ParameterSetName = 'dpkgInstalledPackage', Position = 0)] [Alias('Package')] [string[]] $Name, [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'dpkgFile', Position = 0)] $Path ) process { switch ($PSCmdlet.ParameterSetName) { 'dpkgInstalledPackage' { $PackageToParse = { Get-DpkgInstalledPackage -Name $Name | Where-Object {$null -ne $_.Version} } } 'dpkgFile' { $PackageToParse = { Get-Item -Path $Path } } } &$PackageToParse | ForEach-Object { if ($_ -is [System.IO.FileInfo]) { # dpkg --info ./localpackage.deb for getting info of non-installed package $dpkgParams = (Get-DpkgCmdArgument -Info $_.FullName) } else { # dpkg --status packageName for having details of the installed package $dpkgParams = (Get-DpkgCmdArgument -Status $_.Name) } Write-Verbose "Fetching details for '$($_.Name)'" $GetPropertyHashFromListOutputParams = @{ AllowedPropertyName = ([DpkgPackage].GetProperties().Name) AddExtraPropertiesAsKey = 'AdditionalFields' ErrorVariable = 'packageError' } $properties = Invoke-NativeCommand -Executable 'dpkg' -Parameters $dpkgParams | Get-PropertyHashFromListOutput @GetPropertyHashFromListOutputParams # Making sure we replicate the package property to Name property # To correctly make the Base object (Package class) $properties['PackageType'] = 'dpkg' $properties.add('Name', $properties['Package']) if (-not $packageError) { [DpkgPackage]$properties } } } } #EndRegion './Public/Get-DpkgPackage.ps1' 62 |