PSSystemProperties.psm1
Function Find-SystemPropertyName { [CmdletBinding(DefaultParameterSetName='UserInput')] param ( [Parameter(Mandatory=$true, ParameterSetName='UserInput')] [string]$Name, [Parameter(Mandatory=$true, ParameterSetName='List')] [switch]$All ) if ($PSCmdlet.ParameterSetName -eq 'List') { return (Get-Content -Path (Join-Path -Path $PSScriptRoot -ChildPath 'PropertyList.txt')) } else { $Regex = switch -Regex ($Name) { "([a-zA-Z]+\.)([a-zA-Z]+\.?){1,}" {[regex]::Escape($Name); break} "[a-zA-Z]+" {"([a-zA-Z]+\.){1,}([a-zA-Z]+)?$Name([a-zA-Z]+)?"; break} default {throw "Value for Parameter 'Name' contains Invalid characters"} } $Results = (Get-Content -Path (Join-Path -Path $PSScriptRoot -ChildPath 'PropertyList.txt')) -match $Regex $ExactMatch = $Results -match "^$Name$" if ($ExactMatch) {$ExactMatch} else {$Results} } } Function Get-SystemPropertyValue { [CmdletBinding()] param ( [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] [System.IO.FileInfo]$Path, [Parameter(Mandatory=$true)] [string[]]$Name ) begin { $PropertyList = Find-SystemPropertyName -All $Properties = $PropertyList | Where-Object {$_ -in $Name} if (-not $Properties) {throw ("No matching properties found for: {0}" -f ($Name -join ', '))} else { if ($Properties.Count -ne $Name.Count) {Write-Warning -Message 'Found {0}/{1} properties' -f $Properties.Count, $Name.Count} [System.Collections.ArrayList]$Results = @() } } Process { $Path | ForEach-Object { if (Test-Path -Path $_.FullName -PathType Leaf) { $ObjectPath = $_ $ObjectResults = [ordered]@{Path=$ObjectPath} $shellFile = [Microsoft.WindowsAPICodePack.Shell.ShellObject]::FromParsingName($ObjectPath.FullName) foreach ($Property in $Properties){ try {$ObjectResults.$Property = $shellFile.Properties.GetProperty($Property).Value} catch {$ObjectResults.$Property = $null} } [void]$Results.Add([PSCustomObject]$ObjectResults) } } } End {return $Results} } Function Set-SystemProperty { [CmdletBinding(DefaultParameterSetName='Set')] param ( [Parameter(Mandatory=$true)] [ValidateScript({if ($_.Exists) {[System.IO.FileInfo]$_} else {throw 'File does not exist.'}})] [System.IO.FileInfo]$Path, [Parameter(Mandatory=$true)] [ValidateScript({(Find-SystemPropertyName -Name $_).Count -eq 1})] [string]$Name, [Parameter(Mandatory=$true, ParameterSetName='Set')] [ValidateScript({if ($null -ne $_) {$_} else {throw "Value for parameter 'Value' cannot be null. Use switch '-Remove' instead."}})] [object]$Value, [Parameter(Mandatory=$false, ParameterSetName='Set')] [switch]$AllowTruncatedValue, [Parameter(Mandatory=$true, ParameterSetName='Remove')] [switch]$Remove ) $MatchingProperty = Find-SystemPropertyName -Name $Name if ($MatchingProperty.Count -eq 1) { $shellFile = [Microsoft.WindowsAPICodePack.Shell.ShellObject]::FromParsingName($Path.FullName) try {$ValidProperty = $shellFile.Properties.GetProperty($MatchingProperty)} catch {throw "Invalid Property name: '$MatchingProperty' not found for file: '$Path'."} if ($ValidProperty.ValueType.ToString() -match ([regex]::Escape($Value.GetType().Name))) { $ShellPropertyWriter = $shellFile.Properties.GetPropertyWriter() try { if ($PSCmdlet.ParameterSetName -eq 'Set'){$ShellPropertyWriter.WriteProperty($MatchingProperty, $Value, $AllowTruncatedValue.IsPresent)} else {$ShellPropertyWriter.WriteProperty($MatchingProperty, $null, $false)} } finally {$ShellPropertyWriter.Close()} } else {throw ("Value entered for parameter: 'Value' does not match the ValueType for Property '$MatchingProperty': {0}" -f $ValidProperty.ValueType)} } else {throw "A Property which matches the value entered for Parameter 'Property': $Name could not be found."} } |