PowerShell modules, digital signatures, NuGet nuspec and packages
d-fens GmbH General-Guisan-Strasse 6 CH-6300 Zug Switzerland
d-fens PowerShell modules, digital signatures, NuGet nuspec and packages | |
Copyright 2014 d-fens GmbH | |
This product includes software developed at | |
d-fens GmbH (http://d-fens.ch/). |
<?xml version="1.0" encoding="utf-8"?> | |
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> | |
<metadata> | |
<id>biz.dfch.PS.System.Utilities</id> | |
<version>1.0.4</version> | |
<title>biz.dfch.PS.System.Utilities</title> | |
<authors>d-fens GmbH</authors> | |
<owners>Ronald Rink</owners> | |
<licenseUrl>https://github.com/dfch/biz.dfch.PS.System.Utilities/blob/master/LICENSE</licenseUrl> | |
<projectUrl>https://github.com/dfch/biz.dfch.PS.System.Utilities</projectUrl> | |
<iconUrl>https://raw.githubusercontent.com/dfch/fragments/master/logo-32x32.png</iconUrl> | |
<requireLicenseAcceptance>true</requireLicenseAcceptance> | |
<description>biz.dfch.PS.System.Utilities | |
============================ | |
Modules: biz.dfch.PS.System.Utilities | |
d-fens GmbH, General-Guisan-Strasse 6, CH-6300 Zug, Switzerland | |
This Microsoft PowerShell module contains Cmdlets to perform various actions and utilties/convenience functions such as string conversion and formatting. | |
You can download this module via [NuGet](http://nuget.org) with [Install-Package biz.dfch.PS.System.Utilities](https://www.nuget.org/packages/biz.dfch.PS.System.Utilities/). | |
See [d-fens WebSite](http://d-fens.ch/2014/10/15/module-biz-dfch-ps-system-utilities/) or check the [Wiki](https://github.com/dfch/biz.dfch.PS.System.Utilities/wiki) for further description and examples on how to use the module. | |
</description> | |
<summary>This Microsoft PowerShell module contains Cmdlets to perform various actions and utilties/convenience functions such as string conversion and formatting.</summary> | |
<releaseNotes>20141130</releaseNotes> | |
<copyright>(c) 2014 d-fens GmbH</copyright> | |
<language>en-US</language> | |
<tags>PowerShell dfch</tags> | |
<dependencies> | |
<dependency id="biz.dfch.PS.System.Logging" version="1.0.3" /> | |
</dependencies> | |
</metadata> | |
<files xmlns=""> | |
<file src="biz.dfch.PS.System.Utilities.psm1" target="biz.dfch.PS.System.Utilities.psm1" /> | |
<file src="biz.dfch.PS.System.Utilities.psd1" target="biz.dfch.PS.System.Utilities.psd1" /> | |
<file src="biz.dfch.PS.System.Utilities.xml" target="biz.dfch.PS.System.Utilities.xml" /> | |
<file src="LICENSE" target="LICENSE" /> | |
<file src="NOTICE" target="NOTICE" /> | |
<file src="README.md" target="README.md" /> | |
<file src="biz.dfch.PS.System.Utilities_aaab9f3e-e544-4827-9db8-44bade441fc5_en-US_HelpContent.cab" target="biz.dfch.PS.System.Utilities_aaab9f3e-e544-4827-9db8-44bade441fc5_en-US_HelpContent.cab" /> | |
<file src="biz.dfch.PS.System.Utilities_aaab9f3e-e544-4827-9db8-44bade441fc5_HelpInfo.xml" target="biz.dfch.PS.System.Utilities_aaab9f3e-e544-4827-9db8-44bade441fc5_HelpInfo.xml" /> | |
<file src="New-CustomErrorRecord.ps1" target="New-CustomErrorRecord.ps1" /> | |
<file src="Format-Xml.ps1" target="Format-Xml.ps1" /> | |
<file src="ConvertFrom-UnicodeHexEncoding.ps1" target="ConvertFrom-UnicodeHexEncoding.ps1" /> | |
<file src="ConvertFrom-SecureStringDF.ps1" target="ConvertFrom-SecureStringDF.ps1" /> | |
<file src="New-SecurePassword.ps1" target="New-SecurePassword.ps1" /> | |
<file src="ConvertTo-UrlEncoded.ps1" target="ConvertTo-UrlEncoded.ps1" /> | |
<file src="ConvertFrom-UrlEncoded.ps1" target="ConvertFrom-UrlEncoded.ps1" /> | |
<file src="ConvertTo-Base64.ps1" target="ConvertTo-Base64.ps1" /> | |
<file src="ConvertFrom-Base64.ps1" target="ConvertFrom-Base64.ps1" /> | |
<file src="Get-ComObjectType.ps1" target="Get-ComObjectType.ps1" /> | |
<file src="Test-StringPattern.ps1" target="Test-StringPattern.ps1" /> | |
<file src="Import-Credential.ps1" target="Import-Credential.ps1" /> | |
<file src="Export-Credential.ps1" target="Export-Credential.ps1" /> | |
<file src="Get-Constructor.ps1" target="Get-Constructor.ps1" /> | |
<file src="Set-SslSecurityPolicy.ps1" target="Set-SslSecurityPolicy.ps1" /> | |
<file src="New-ActivityProgress.ps1" target="New-ActivityProgress.ps1" /> | |
<file src="Set-ActivityProgress.ps1" target="Set-ActivityProgress.ps1" /> | |
<file src="Remove-ActivityProgress.ps1" target="Remove-ActivityProgress.ps1" /> | |
<file src="ConvertFrom-CmdletHelp.ps1" target="ConvertFrom-CmdletHelp.ps1" /> | |
<file src="Expand-CompressedItem.ps1" target="Expand-CompressedItem.ps1" /> | |
<file src="Format-IpAddress.ps1" target="Format-IpAddress.ps1" /> | |
<file src="ConvertFrom-PSCustomObject.ps1" target="ConvertFrom-PSCustomObject.ps1" /> | |
<file src="ConvertFrom-Hashtable.ps1" target="ConvertFrom-Hashtable.ps1" /> | |
<file src="Test-CmdletDocumentation.ps1" target="Test-CmdletDocumentation.ps1" /> | |
<file src="Assert-CmdletDocumentation.ps1" target="Assert-CmdletDocumentation.ps1" /> | |
</files> | |
</package> |
function Update-Manifest { | |
<# | |
.SYNOPSIS | |
Updates the revision number of a PowerShell manifest. | |
.DESCRIPTION | |
Updates the revision number of a PowerShell manifest. | |
The revision of the specified manifest is checked against the files in the module folder. If the revision is older than the last write time the revision is updated. | |
.EXAMPLE | |
Update-Signature C:\scripts\myScript.ps1 | |
Checks the specified manifest. | |
.EXAMPLE | |
Update-Signature C:\scripts | |
Checks all manifest in the specified folder recursively. | |
#> | |
[CmdletBinding( | |
SupportsShouldProcess = $true | |
, | |
ConfirmImpact = "Low" | |
, | |
DefaultParameterSetName = 'path' | |
)] | |
PARAM | |
( | |
# Specifies a path to search for manifest files | |
[ValidateScript( { Test-Path($_) -PathType Container; } )] | |
[Parameter(Mandatory = $false, ParameterSetName = 'path')] | |
[System.IO.DirectoryInfo] $Path = 'C:\Github' | |
, | |
# Specifies one or more manifest files to check | |
[ValidateScript( { if($_) { foreach($item in $_) {Test-Path($item) -PathType Leaf -Include "*.psd1"; } } else { $true } } )] | |
[Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ParameterSetName = 'file')] | |
[AllowNull()] | |
[Alias('File')] | |
$InputObject | |
, | |
[Parameter(Mandatory = $false)] | |
[switch] $IncrementVersionMajor = $false | |
, | |
[Parameter(Mandatory = $false)] | |
[switch] $IncrementVersionMinor = $false | |
, | |
[Parameter(Mandatory = $false)] | |
[switch] $IncrementVersionBuild = $false | |
, | |
[Parameter(Mandatory = $false)] | |
[switch] $UpdateRevision = $true | |
) | |
BEGIN | |
{ | |
if($PSCmdlet.ParameterSetName -eq 'path') | |
{ | |
$InputObjectTemp = (Get-ChildItem $Path -Include "*.psd1" -Recurse); | |
if($InputObjectTemp) | |
{ | |
$InputObject = $InputObjectTemp; | |
Remove-Variable InputObjectTemp; | |
} | |
} | |
} | |
# BEGIN | |
PROCESS | |
{ | |
foreach($Object in $InputObject) | |
{ | |
try | |
{ | |
$Version = (Get-Content -Raw $Object | iex).ModuleVersion -as [Version]; | |
} | |
catch | |
{ | |
$Version = (Get-Content -Raw $Object | iex).ModuleVersion -as [Version]; | |
} | |
$VersionNew = $Version; | |
$Object = Get-Item $Object; | |
if($UpdateRevision) | |
{ | |
Write-Host ("{0}: Comparing against Version.Revision '{1}'" -f $Object.FullName, $Version.Revision); | |
$LastWriteTimes = (Get-ChildItem (Split-Path $Object)).LastWriteTime; | |
foreach($LastWriteTime in $LastWriteTimes) | |
{ | |
if( ($LastWriteTime.ToString('yyyyMMdd') -as [int]) -gt $Version.Revision) | |
{ | |
$VersionNew = New-Object Version($VersionNew.Major, $VersionNew.Minor, $VersionNew.Build, ($LastWriteTime.ToString('yyyyMMdd') -as [int])); | |
} | |
} | |
} | |
if($IncrementVersionMajor) | |
{ | |
Write-Host ("{0}: Incrementing Version.Major '{1}'" -f $Object.FullName, $Version.Major); | |
$VersionNew = New-Object Version(($VersionNew.Major +1), $VersionNew.Minor, $VersionNew.Build, $VersionNew.Revision); | |
} | |
if($IncrementVersionMinor) | |
{ | |
Write-Host ("{0}: Incrementing Version.Minor '{1}'" -f $Object.FullName, $Version.Minor); | |
$VersionNew = New-Object Version($VersionNew.Major, ($VersionNew.Minor +1), $VersionNew.Build, $VersionNew.Revision); | |
} | |
if($IncrementVersionBuild) | |
{ | |
Write-Host ("{0}: Incrementing Version.Build '{1}'" -f $Object.FullName, $Version.Build); | |
$VersionNew = New-Object Version($VersionNew.Major, $VersionNew.Minor, ($VersionNew.Build +1), $VersionNew.Revision); | |
} | |
if($Version.ToString() -ne $VersionNew.ToString()) | |
{ | |
if(!$PSCmdlet.ShouldProcess($Object)) | |
{ | |
continue; | |
} | |
Write-Host ("{0}: Updating manifest revision from '{1}' to '{2}' ..." -f $Object, $Version.ToString(), $VersionNew.ToString()); | |
(Get-Content -Raw $Object).Replace($Version.ToString(), $VersionNew.ToString()) | Out-File -Encoding default $Object -Confirm:$false; | |
$null = Update-Signature $Object.FullName -Confirm:$false; | |
$Object.FullName; | |
} | |
} | |
} | |
# PROCESS | |
END | |
{ | |
} | |
# END | |
} # function | |
if($MyInvocation.ScriptName -And ('.' -ne $MyInvocation.InvocationName)) { Export-ModuleMember -Function Update-Manifest; } | |
# | |
# Copyright 2014-2015 Ronald Rink, d-fens GmbH | |
# | |
# Licensed under the Apache License, Version 2.0 (the "License"); | |
# you may not use this file except in compliance with the License. | |
# You may obtain a copy of the License at | |
# | |
# http://www.apache.org/licenses/LICENSE-2.0 | |
# | |
# Unless required by applicable law or agreed to in writing, software | |
# distributed under the License is distributed on an "AS IS" BASIS, | |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
# See the License for the specific language governing permissions and | |
# limitations under the License. | |
# |
function Update-Nuspec { | |
<# | |
.SYNOPSIS | |
Updates the nuspec file of a PowerShell module. | |
.DESCRIPTION | |
Updates the nuspec file of a PowerShell module. | |
Checks the version and revision number of a PowerShell module manifest and | |
create a new nuspec file if necessary. The new nuspec file will be built from | |
a previous existing nuspec (with the highest available version number). | |
All files referenced in the manifest will be inserted into the nusepc file. | |
Optionally a nupkg will be created as well. | |
.EXAMPLE | |
Update-Nuspec C:\scripts\biz.dfch.PS.Module\biz.dfch.PS.Module.psd1 | |
Updates the given module manifest with a new nuspec file and also creates a package from it. | |
.EXAMPLE | |
Update-Nuspec C:\scripts | |
Updates all module manifests in the specified path with a new nuspec file and also creates a package from it. | |
#> | |
[CmdletBinding( | |
SupportsShouldProcess = $true | |
, | |
ConfirmImpact = "Low" | |
, | |
DefaultParameterSetName = 'path' | |
)] | |
PARAM | |
( | |
# Specifies a path to nuspec files to update | |
[ValidateScript( { Test-Path($_) -PathType Container; } )] | |
[Parameter(Mandatory = $false, ParameterSetName = 'path')] | |
[System.IO.DirectoryInfo] $Path = 'C:\Github' | |
, | |
# Specifies one ore more nuspec files to update | |
[ValidateScript( { if($_) { foreach($item in $_) {Test-Path($item) -PathType Leaf; } } else { $true } } )] | |
[Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ParameterSetName = 'file')] | |
[AllowNull()] | |
[Alias('File')] | |
$InputObject | |
, | |
# Specify whether to also create a package from the nuspec file | |
[Parameter(Mandatory = $false)] | |
[Alias('CreatePackage')] | |
[switch] $Pack = $true | |
, | |
# Specify whether to update an existing package | |
[Parameter(Mandatory = $false)] | |
[switch] $Force = $false | |
, | |
# Specifies the path to the NuGet.exe | |
[ValidateScript( { Test-Path($_); } )] | |
[Parameter(Mandatory = $false)] | |
[string] $NuGetExe = 'C:\SOFTWARE\NuGet.exe' | |
) | |
if($PSCmdlet.ParameterSetName -eq 'path') | |
{ | |
$InputObjectTemp = (Get-ChildItem $Path -Include "*.psd1" -Recurse); | |
if($InputObjectTemp) | |
{ | |
$InputObject = $InputObjectTemp; | |
Remove-Variable InputObjectTemp; | |
} | |
} | |
foreach($Object in $InputObject) | |
{ | |
$Object = Get-Item $Object; | |
$Manifest = (Get-Content -Raw $Object) | iex; | |
$Version = (($Manifest).ModuleVersion -as [Version]); | |
$NuspecVersion = '{0}.{1}.{2}' -f $Version.Major, $Version.Minor, $Version.Build; | |
$Revision = $Version.Revision; | |
$NuspecPathAndFile = Join-Path -Path (Split-Path $Object -Parent) -ChildPath ('{0}.{1}.nuspec' -f $Object.BaseName, $NuspecVersion); | |
if(Test-Path $NuspecPathAndFile) | |
{ | |
[xml] $NuGetXml = Get-Content -Raw $NuspecPathAndFile; | |
if($NuGetXml.package.metadata.releaseNotes -notmatch $Version.Revision) | |
{ | |
Write-Warning ("{0}: NuGet package already exists, but does not contain correct Revision '{1}'." -f $NuspecPathAndFile, $Revision); | |
if(!$Force) | |
{ | |
continue; | |
} | |
} | |
Write-Host ("{0}: NuGet package already exists." -f $NuspecPathAndFile); | |
if(!$Force) | |
{ | |
continue; | |
} | |
} | |
$NuspecPrevious = Get-ChildItem -Path (Split-Path $Object -Parent) -Include "*.nuspec" -Recurse | sort -Property Name, LastWriteTime -Descending | Select -First 1; | |
if(!$NuspecPrevious) | |
{ | |
Write-Warning ("{0}: No previous NuGet package exists. Skipping ..." -f $NuspecPathAndFile); | |
continue; | |
} | |
[xml] $NuGetXml = Get-Content -Raw $NuspecPrevious; | |
# set version | |
$NuGetXml.package.metadata.version = $NuspecVersion; | |
# set revision | |
$NuGetXml.package.metadata.releaseNotes = $Revision.ToString(); | |
# set the description | |
$NuGetXml.package.metadata.description = (Get-Content -Raw (Join-Path -Path (Split-Path $Object -Parent) -ChildPath 'README.md')).ToString(); | |
# set the files to be included | |
try | |
{ | |
$NuGetXml.package.files.RemoveAll(); | |
$xmlFiles = $NuGetXml.package.SelectSingleNode('files'); | |
} | |
catch | |
{ | |
$xmlFiles = $NuGetXml.CreateElement('files'); | |
} | |
foreach($item in $Manifest.RootModule,$Object.Name) | |
{ | |
$xmlFile = $NuGetXml.CreateElement('file'); | |
$xmlSrc = $NuGetXml.CreateAttribute('src'); | |
$xmlSrc.Value = $item; | |
$xmlTarget = $NuGetXml.CreateAttribute('target'); | |
$xmlTarget.Value = $item; | |
$null = $xmlFile.Attributes.Append($xmlSrc); | |
$null = $xmlFile.Attributes.Append($xmlTarget); | |
$null = $xmlFiles.AppendChild($xmlFile); | |
} | |
foreach($item in $Manifest.FileList) | |
{ | |
$xmlFile = $NuGetXml.CreateElement('file'); | |
$xmlSrc = $NuGetXml.CreateAttribute('src'); | |
$xmlSrc.Value = $item; | |
$xmlTarget = $NuGetXml.CreateAttribute('target'); | |
$xmlTarget.Value = $item; | |
$null = $xmlFile.Attributes.Append($xmlSrc); | |
$null = $xmlFile.Attributes.Append($xmlTarget); | |
$null = $xmlFiles.AppendChild($xmlFile); | |
} | |
foreach($item in $Manifest.NestedModules) | |
{ | |
$xmlFile = $NuGetXml.CreateElement('file'); | |
$xmlSrc = $NuGetXml.CreateAttribute('src'); | |
$xmlSrc.Value = $item; | |
$xmlTarget = $NuGetXml.CreateAttribute('target'); | |
$xmlTarget.Value = $item; | |
$null = $xmlFile.Attributes.Append($xmlSrc); | |
$null = $xmlFile.Attributes.Append($xmlTarget); | |
$null = $xmlFiles.AppendChild($xmlFile); | |
} | |
$null = $NuGetXml.package.AppendChild($xmlFiles); | |
if(!$PSCmdlet.ShouldProcess($Object)) | |
{ | |
continue; | |
} | |
Write-Host ("{0}: Creating NuSpec file ..." -f $NuspecPathAndFile); | |
$NuGetXml.OuterXml | fx | Out-File -Encoding default $NuspecPathAndFile; | |
if($Pack) | |
{ | |
Push-Location (Split-Path $Object -Parent); | |
Write-Host ("{0}: Creating NuPkg file ..." -f $NuspecPathAndFile); | |
Start-Process $NuGetExe -ArgumentList @( ("pack {0}" -f $NuspecPathAndFile),"-NonInteractive",'-Verbosity quiet') -NoNewWindow -Wait; | |
Pop-Location; | |
} | |
} | |
} # function | |
if($MyInvocation.ScriptName -And ('.' -ne $MyInvocation.InvocationName)) { Export-ModuleMember -Function Update-Nuspec; } | |
# | |
# Copyright 2014-2015 Ronald Rink, d-fens GmbH | |
# | |
# Licensed under the Apache License, Version 2.0 (the "License"); | |
# you may not use this file except in compliance with the License. | |
# You may obtain a copy of the License at | |
# | |
# http://www.apache.org/licenses/LICENSE-2.0 | |
# | |
# Unless required by applicable law or agreed to in writing, software | |
# distributed under the License is distributed on an "AS IS" BASIS, | |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
# See the License for the specific language governing permissions and | |
# limitations under the License. | |
# |
#Requires -Modules Microsoft.PowerShell.Security | |
function Update-Signature { | |
<# | |
.SYNOPSIS | |
Updates the digital signature of PowerShell scripts. | |
.DESCRIPTION | |
Updates the digital signature of PowerShell scripts. | |
You can either sign all scripts in a given folder or only individual files. | |
.EXAMPLE | |
Update-Signature C:\scripts\myScript.ps1 | |
Signs the specified script with the default certificate and timestamps it. | |
.EXAMPLE | |
Update-Signature C:\scripts | |
Signs the all scripts in the specified folder with the default certificate and timestamps it. | |
#> | |
[CmdletBinding( | |
SupportsShouldProcess = $true | |
, | |
ConfirmImpact = "Low" | |
, | |
DefaultParameterSetName = 'path' | |
)] | |
PARAM | |
( | |
# The path to script files to sign | |
[ValidateScript( { Test-Path($_) -PathType Container; } )] | |
[Parameter(Mandatory = $false, ParameterSetName = 'path')] | |
[System.IO.DirectoryInfo] $Path = 'C:\Github' | |
, | |
# A script file or array of script files to sign | |
[ValidateScript( { if($_) { foreach($item in $_) {Test-Path($item) -PathType Leaf -Include $IncludeExtensions; } } else { $true } } )] | |
[Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ParameterSetName = 'file')] | |
[AllowNull()] | |
[Alias('File')] | |
$InputObject | |
, | |
# The certificate to use for signing the specified scripts | |
[Parameter(Mandatory = $false, Position = 1)] | |
$Cert = (Select-Object -First 1 -InputObject (Get-ChildItem -Path cert:\CurrentUser\my -CodeSigningCert)) | |
, | |
# Specify wheter to timestamp (countersign) the script files | |
[Parameter(Mandatory = $false)] | |
[Alias('TimeStamp')] | |
[switch] $CounterSign = $true | |
, | |
# The timestamp server url | |
[Parameter(Mandatory = $false, Position = 2)] | |
[Uri] $TimestampServer = 'http://timestamp.globalsign.com/scripts/timstamp.dll' | |
, | |
# File extensions of the script files to sign | |
[Parameter(Mandatory = $false)] | |
$IncludeExtensions = @('*.ps1','*.psm1','*.psd1','*.dll','*.exe') | |
) | |
if($PSCmdlet.ParameterSetName -eq 'path') | |
{ | |
$InputObjectTemp = (Get-ChildItem $Path -Include $IncludeExtensions -Recurse | Get-AuthenticodeSignature |? { ($_.Status -eq 'HashMismatch') -Or (($_.TimeStamperCertificate -eq $null) -And ($_.Status -eq 'Valid')) }).Path; | |
if($InputObjectTemp) | |
{ | |
$InputObject = $InputObjectTemp; | |
Remove-Variable InputObjectTemp; | |
} | |
} | |
foreach($Object in $InputObject) | |
{ | |
if(!$PSCmdlet.ShouldProcess($Object)) | |
{ | |
continue; | |
} | |
if($CounterSign) | |
{ | |
Set-AuthenticodeSignature $Object -Certificate $cert -TimestampServer $TimestampServer -Confirm:$false; | |
} | |
else | |
{ | |
Set-AuthenticodeSignature $Object -Certificate $cert -Confirm:$false; | |
} | |
} | |
} # function | |
if($MyInvocation.ScriptName -And ('.' -ne $MyInvocation.InvocationName)) { Export-ModuleMember -Function Update-Signature; } | |
# | |
# Copyright 2014-2015 Ronald Rink, d-fens GmbH | |
# | |
# Licensed under the Apache License, Version 2.0 (the "License"); | |
# you may not use this file except in compliance with the License. | |
# You may obtain a copy of the License at | |
# | |
# http://www.apache.org/licenses/LICENSE-2.0 | |
# | |
# Unless required by applicable law or agreed to in writing, software | |
# distributed under the License is distributed on an "AS IS" BASIS, | |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
# See the License for the specific language governing permissions and | |
# limitations under the License. | |
# |