PoshCode Logo PowerShell Code Repository

Get/Set Signature (CTP2) (modification of post by Joel Bennett view diff)
View followups from Joel Bennett | diff | embed code: <script type="text/javascript" src="http://PoshCode.org/embed/456"></script>download | new post

VERSION 1.3

  1. #Requires -version 2.0
  2. ## Authenticode.psm1
  3. ####################################################################################################
  4. ## Wrappers for the Get-AuthenticodeSignature and Set-AuthenticodeSignature cmdlets
  5. ## These properly parse paths, so they don't kill your pipeline and script if you include a folder
  6. ##
  7. ## Usage:
  8. ## ls | Get-AuthenticodeSignature
  9. ##    Get all the signatures
  10. ##
  11. ## ls | Select-Signed -Mine -Broken | Set-AuthenticodeSignature
  12. ##    Re-sign anything you signed before that has changed
  13. ##
  14. ## ls | Select-Signed -NotMine -ValidOnly | Set-AuthenticodeSignature
  15. ##    Re-sign scripts that are hash-correct but not signed by me or by someone trusted
  16. ##
  17. ####################################################################################################
  18. ## History:
  19. ## 1.3 - Fixed some bugs in If-Signed and renamed it to Select-Signed
  20. ##     - Added -MineOnly and -NotMineOnly switches to Select-Signed
  21. ## 1.2 - Added a hack workaround to make it appear as though we can sign and check PSM1 files
  22. ##       It's important to remember that the signatures are NOT checked by PowerShell yet...
  23. ## 1.1 - Added a filter "If-Signed" that can be used like: ls | If-Signed
  24. ##     - With optional switches: ValidOnly, InvalidOnly, BrokenOnly, TrustedOnly, UnsignedOnly
  25. ##     - commented out the default Certificate which won't work for "you"
  26. ## 1.0 - first working version, includes wrappers for Get and Set
  27. ##
  28.  
  29. ## YOU MUST CHANGE THIS ...
  30. # Set-Variable CertificateThumbprint  "0DA3A2A2189CD74AE371E6C57504FEB9A59BB22E" -Scope Script -Option ReadOnly
  31. Set-Variable CertificateThumbprint  "F05F583BB5EA4C90E3B9BF1BDD0B657701245BD5" -Scope Script -Option ReadOnly
  32.  
  33. CMDLET Test-Signature {
  34. PARAM (
  35.    [Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)]
  36. #  We can't actually require the type, or we won't be able to check the fake ones
  37. #   [System.Management.Automation.Signature]
  38.    $Signature
  39. ,
  40.    [Alias("Valid")]
  41.    [Switch]$ForceValid
  42. )
  43.  
  44. return ( $Signature.Status -eq "Valid" -or
  45.       ( !$ForceValid -and
  46.          ($Signature.Status -eq "UnknownError") -and
  47.          ($_.SignerCertificate.Thumbprint -eq $CertificateThumbprint)
  48.       ) )
  49. }
  50.  
  51. CMDLET Set-AuthenticodeSignature -snapin Huddled.BetterDefaults {
  52. PARAM (
  53.    [Parameter(Position=1, Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
  54.    [Alias("FullName")]
  55.    [ValidateScript({
  56.       if((resolve-path $_).Provider.Name -ne "FileSystem") {
  57.          throw "Specified Path is not in the FileSystem: '$_'"
  58.       }
  59.       if(!(Test-Path -PathType Leaf $_)) {
  60.          throw "Specified Path is not a File: '$_'"
  61.       }
  62.       return $true
  63.    })]
  64.    [string]
  65.    $Path
  66. ,  ## TODO: you should CHANGE THIS to a method which gets *your* default certificate
  67.    [Parameter(Position=2, Mandatory=$false)]
  68.    $Certificate = $(ls cert:\CurrentUser\my\$CertificateThumbprint)
  69. )
  70.  
  71. PROCESS {
  72.    if( ".psm1" -eq [IO.Path]::GetExtension($Path) ) {
  73.    # function setpsm1sig($Path) {
  74.       $ps1Path = "$Path.ps1"
  75.       Rename-Item $Path (Split-Path $ps1Path -Leaf)
  76.       $sig = Microsoft.PowerShell.Security\Set-AuthenticodeSignature -Certificate $Certificate -FilePath $ps1Path | Select *
  77.       Rename-Item $ps1Path (Split-Path $Path -Leaf)
  78.       $sig.PSObject.TypeNames.Insert( 0, "System.Management.Automation.Signature" )
  79.       $sig.Path = $Path
  80.       $sig
  81.    } else {
  82.       Microsoft.PowerShell.Security\Set-AuthenticodeSignature -Certificate $Certificate -FilePath $Path  
  83.    }
  84. }
  85. }
  86.  
  87. CMDLET Get-AuthenticodeSignature -snapin Huddled.BetterDefaults {
  88. PARAM (
  89.    [Parameter(Position=1, Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
  90.    [Alias("FullName")]
  91.    [ValidateScript({
  92.       if((resolve-path $_).Provider.Name -ne "FileSystem") {
  93.          throw "Specified Path is not in the FileSystem: '$_'"
  94.       }
  95.       if(!(Test-Path -PathType Leaf $_)) {
  96.          throw "Specified Path is not a File: '$_'"
  97.       }
  98.       return $true
  99.    })]
  100.    [string]
  101.    $Path
  102. )
  103.  
  104. PROCESS {
  105.    if( ".psm1" -eq [IO.Path]::GetExtension($Path) ) {
  106.    # function getpsm1sig($Path) {
  107.       $ps1Path = "$Path.ps1"
  108.       Rename-Item $Path (Split-Path $ps1Path -Leaf)
  109.       $sig = Microsoft.PowerShell.Security\Get-AuthenticodeSignature -FilePath $ps1Path | select *
  110.       Rename-Item $ps1Path (Split-Path $Path -Leaf)
  111.       $sig.PSObject.TypeNames.Insert( 0, "System.Management.Automation.Signature" )
  112.       $sig.Path = $Path
  113.       $sig
  114.    } else {
  115.       Microsoft.PowerShell.Security\Get-AuthenticodeSignature -FilePath $Path
  116.    }
  117.  
  118. }
  119. }
  120.  
  121. CMDLET Select-Signed -snapin Huddled.BetterDefaults {
  122. PARAM (
  123.    [Parameter(Position=1, Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
  124.    [Alias("FullName")]
  125.    [ValidateScript({
  126.       if((resolve-path $_).Provider.Name -ne "FileSystem") {
  127.          throw "Specified Path is not in the FileSystem: '$_'"
  128.       }
  129.       return $true
  130.    })]
  131.    [string]
  132.    $Path
  133. ,
  134.    [Parameter()]
  135.    [switch]$MineOnly
  136. ,
  137.    [Parameter()]
  138.    [switch]$NotMineOnly
  139. ,
  140.    [Parameter()]
  141.    [switch]$BrokenOnly
  142. ,
  143.    [Parameter()]
  144.    [switch]$TrustedOnly
  145. ,
  146.    [Parameter()]
  147.    [switch]$ValidOnly
  148. ,
  149.    [Parameter()]
  150.    [switch]$InvalidOnly
  151. ,
  152.    [Parameter()]
  153.    [switch]$UnsignedOnly
  154.  
  155. )
  156.  
  157.    if(!(Test-Path -PathType Leaf $Path)) {
  158.       # if($ErrorAction -ne "SilentlyContinue") {
  159.       #    Write-Error "Specified Path is not a File: '$Path'"
  160.       # }
  161.    } else {
  162.  
  163.       $sig = Get-AuthenticodeSignature $Path
  164.      
  165.       # Broken only returns ONLY things which are HashMismatch
  166.       if($BrokenOnly   -and $sig.Status -ne "HashMismatch")
  167.       {
  168.          Write-Debug "$($sig.Status) - Not Broken: $Path"
  169.          return
  170.       }
  171.      
  172.       # Trusted only returns ONLY things which are Valid
  173.       if($TrustedOnly  -and $sig.Status -ne "Valid")
  174.       {
  175.          Write-Debug "$($sig.Status) - Not Trusted: $Path"
  176.          return
  177.       }
  178.      
  179.       # AllValid returns only things that are SIGNED and not HashMismatch
  180.       if($ValidOnly    -and (($sig.Status -ne "HashMismatch") -or !$sig.SignerCertificate) )
  181.       {
  182.          Write-Debug "$($sig.Status) - Not Valid: $Path"
  183.          return
  184.       }
  185.      
  186.       # NOTValid returns only things that are SIGNED and not HashMismatch
  187.       if($InvalidOnly  -and ($sig.Status -eq "Valid"))
  188.       {
  189.          Write-Debug "$($sig.Status) - Valid: $Path"
  190.          return
  191.       }
  192.      
  193.       # Unsigned returns only things that aren't signed
  194.       # NOTE: we don't test using NotSigned, because that's only set for .ps1 or .exe files??
  195.       if($UnsignedOnly -and $sig.SignerCertificate )
  196.       {
  197.          Write-Debug "$($sig.Status) - Signed: $Path"
  198.          return
  199.       }
  200.      
  201.       # Mine returns only things that were signed by MY CertificateThumbprint
  202.       if($MineOnly     -and (!($sig.SignerCertificate) -or ($sig.SignerCertificate.Thumbprint -ne $CertificateThumbprint)))
  203.       {
  204.          Write-Debug "Originally signed by someone else, thumbprint: $($sig.SignerCertificate.Thumbprint)"
  205.          Write-Debug "Does not match your default certificate print: $CertificateThumbprint"
  206.          Write-Debug "     $Path"
  207.          return
  208.       }
  209.  
  210.       # NotMine returns only things that were signed by MY CertificateThumbprint
  211.       if($NotMineOnly  -and (!($sig.SignerCertificate) -or ($sig.SignerCertificate.Thumbprint -eq $CertificateThumbprint)))
  212.       {
  213.          if($sig.SignerCertificate) {
  214.             Write-Debug "Originally signed by you, thumbprint: $($sig.SignerCertificate.Thumbprint)"
  215.             Write-Debug "Matches your default certificate print: $CertificateThumbprint"
  216.             Write-Debug "     $Path"
  217.          }
  218.          return
  219.       }
  220.      
  221.       if(!$BrokenOnly  -and !$TrustedOnly -and !$ValidOnly -and !$InvalidOnly -and !$UnsignedOnly -and !($sig.SignerCertificate) )
  222.       {
  223.          # Write-Debug ("You asked for Broken ({0}) or Trusted ({1}) or Valid ({2}) or Invalid ({3}) or Unsigned ({4}) and the cert is: ({5})" -f  [int]$BrokenOnly, [int]$TrustedOnly, [int]$ValidOnly, [int]$InvalidOnly, [int]$UnsignedOnly, $sig.SignerCertificate)
  224.          Write-Debug "$($sig.Status) - Not Signed: $Path"
  225.          return
  226.       }
  227.      
  228.       get-childItem $sig.Path
  229.    }
  230. }
  231.  
  232. Export-ModuleMember Set-AuthenticodeSignature,Get-AuthenticodeSignature,Test-Signature,Select-Signed
  233.  
  234. # SIG # Begin signature block
  235. # MIIK0AYJKoZIhvcNAQcCoIIKwTCCCr0CAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
  236. # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
  237. # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUlcaRTm+/m0Lma0cwCp9wfClq
  238. # laagggbEMIIGwDCCBKigAwIBAgIJAKpDRVMtv0LqMA0GCSqGSIb3DQEBBQUAMIHG
  239. # MQswCQYDVQQGEwJVUzERMA8GA1UECBMITmV3IFlvcmsxEjAQBgNVBAcTCVJvY2hl
  240. # c3RlcjEaMBgGA1UEChMRSHVkZGxlZE1hc3Nlcy5vcmcxHjAcBgNVBAsTFUNlcnRp
  241. # ZmljYXRlIEF1dGhvcml0eTErMCkGA1UEAxMiSm9lbCBCZW5uZXR0IENlcnRpZmlj
  242. # YXRlIEF1dGhvcml0eTEnMCUGCSqGSIb3DQEJARYYSmF5a3VsQEh1ZGRsZWRNYXNz
  243. # ZXMub3JnMB4XDTA4MDcwMjAzNTA1OVoXDTA5MDcwMjAzNTA1OVowgcAxCzAJBgNV
  244. # BAYTAlVTMREwDwYDVQQIEwhOZXcgWW9yazESMBAGA1UEBxMJUm9jaGVzdGVyMRow
  245. # GAYDVQQKExFIdWRkbGVkTWFzc2VzLm9yZzEuMCwGA1UECxMlaHR0cDovL0h1ZGRs
  246. # ZWRNYXNzZXMub3JnL0NvZGVDZXJ0LmNydDEVMBMGA1UEAxMMSm9lbCBCZW5uZXR0
  247. # MScwJQYJKoZIhvcNAQkBFhhKYXlrdWxASHVkZGxlZE1hc3Nlcy5vcmcwggIiMA0G
  248. # CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXuceXJZYARJbSTU4hoh91goVp2POx
  249. # 6Mz/QZ6D5jcT/JNhdW2GwYQ9YUxNj8jkhXg2Ixbgb1djRGMFC/ekgRkgLxyiuhRh
  250. # NrVE1IdV4hT4as3idqnvWOi0S3z2R2EGdebqwm2mrRmq9+DbY+FGxuNwLboWZx8Z
  251. # roGlLLHRPzt9pabQq/Nu/FIFO+4JzZ8S5ZnEaKTm4dpD0g6j653OWYVvNXJbS/W4
  252. # Dis5aRkHT1q1Gp02dYHh3NTKrpv1nus9BTDlJRwmU/FgGLNQIvnRwqVoBh+I7tVq
  253. # NIRnI1RpDTGyFEohbH8mRlwq3z4ijtb6j9boUJEqd8hQshzUMcALoTIR1tN/5APX
  254. # u2j4OqGFESM/OG0i2hLKbnP81u581aZT1BfVfQxvDuWrFiurMxllVGY1NvKkXwc8
  255. # aOZktqMQWbWAs2bxZqERbOILXOmkL/mvPdy+e5yQveriHAhrDONu7a79ylreMHBR
  256. # XrmYJTK2G/aHvB5vrXjMPw0TBeph0sM2BN2eVzenAAMsIiGlXPXvtKrpKRiBdx5f
  257. # 9SV5dyUG2tR8ANDuc2AMB8FKICuMUd8Sx96p4FOBQhXhvF/RZcWZIW5o+A4sHvYE
  258. # /s4oiX7LxGrQK2abNiCVs9BDLI/EcSs/TP+ZskBqu7Qb+AVeevoY3T7skihuyC/l
  259. # h7EwqjfNpVQ9UwIDAQABo4G0MIGxMB0GA1UdDgQWBBTgB9XYJV/kJAvnkWmKDHsh
  260. # 7Cn3PzAfBgNVHSMEGDAWgBQ+5x4ah0JG0o4iUj0TebNd4MCVxTAJBgNVHRMEAjAA
  261. # MBEGCWCGSAGG+EIBAQQEAwIEEDAWBgNVHSUBAf8EDDAKBggrBgEFBQcDAzALBgNV
  262. # HQ8EBAMCBsAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRp
  263. # ZmljYXRlMA0GCSqGSIb3DQEBBQUAA4ICAQAw8B6+s48CZZo5h5tUeKV7OWNXKRG7
  264. # xkyavMkXpEi58BSLutmE3O7smc3uvu3TdCXENNUlGrcq/KQ8y2eEI8QkHgT99VgX
  265. # r+v5xu2KnJXiOOIxi65EZybRFFFaGJNodTcrK8L/tY6QLF02ilOlEgfcc1sV/Sj/
  266. # r60JS1iXIMth7nYZVjtWeYXOrsd+I+XwJuoVNJlELNdApOU4ZVNrPEuV+QRNMimj
  267. # lqIOv2tn9TDdNGUqaOCI0w+a1XQvapEPWETfQK+o9pvYINTswGDjNeb7Xz8ar2JB
  268. # 9IVs2xtxDohHB75kyRrlY1hkoY5j12ZhWOlm0L9Ks6XvmMtXJIjj0/m9Z+3s+9p6
  269. # U7IYjz5NnzmDvtNUn2y9zxB/rUx/JqoUO3BWRKiLX0lvGRWJlzFr9978kH2SXxAD
  270. # rsKfzB7YZzMh9hZkGNlJf4T+HTB/OXG1jyfkyqQvhNB/tDAaq+ejDtKNBF4hMS7K
  271. # Z0B4vagIxFwMuTiei4UaOjrGzeCfT9w1Bmj6uLJme5ydQVM0V7z3Z6jR3LVq4c4s
  272. # Y1dfPmYlw62cbyV9Kb/H2hYw5K0OMX60LfLQZOzIPzAeRJ87NufwZnC1afxsSCmU
  273. # bvSx4kCMgRZMXw+d1SHRhh7z+06YTQjnUMmtTGt7DtUkU6I8LKEWF/mAzF7sq/7P
  274. # AyhPsbu91X5FuzGCA3YwggNyAgEBMIHUMIHGMQswCQYDVQQGEwJVUzERMA8GA1UE
  275. # CBMITmV3IFlvcmsxEjAQBgNVBAcTCVJvY2hlc3RlcjEaMBgGA1UEChMRSHVkZGxl
  276. # ZE1hc3Nlcy5vcmcxHjAcBgNVBAsTFUNlcnRpZmljYXRlIEF1dGhvcml0eTErMCkG
  277. # A1UEAxMiSm9lbCBCZW5uZXR0IENlcnRpZmljYXRlIEF1dGhvcml0eTEnMCUGCSqG
  278. # SIb3DQEJARYYSmF5a3VsQEh1ZGRsZWRNYXNzZXMub3JnAgkAqkNFUy2/QuowCQYF
  279. # Kw4DAhoFAKB4MBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkD
  280. # MQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwIwYJ
  281. # KoZIhvcNAQkEMRYEFIYZXAMANzMI+/t73Dzr8alaIgYPMA0GCSqGSIb3DQEBAQUA
  282. # BIICAAW33N0H+Xe84dtN52nWzutpJkpGdAig0Cq3GAjxIZ9y5KiFXh2FO5fA3W4q
  283. # OUNi03RskQHoYQwlP0KiRcdTouggQNVVlHvOBCgT1pcvlLSR7jM+rPKbdPa/6WdJ
  284. # Kr3ZuoPRWvfk12Wu5PgrKs6Rvo3y5hXQNuITchxH58GJXkykz8a28yBVOszrujzP
  285. # 2lwM/RldO1j01DOz7KeyyIWCV1hFyuawEnKANUYh5RO/MRlJ//T8rUPnO0NoHqR9
  286. # X3sqPqHHGGvtk8RZQgwSkDOnEw7JTqJityn7cRKnocm2yrQZ/VoYEI562tw0Xjvy
  287. # Zcn83U+EKo1TdphRWJ2qBvOMK6lR1VPbRKCLvIp21q3tdCCBgqmfc3eDqIINdXVJ
  288. # cmzeqh2yGquQj6ozsjdJtjrKnZnxhk7Clikc1SzMBWT2MxEtAfkJC/Ok8l+Sa1MY
  289. # +uWRL6p+55IE8x5TeNl251IYIp7g4LsPAaFZtiDBERrXRxtBTDszAUyTNJXuDcwS
  290. # T1CYQtrTYpEJxH1uk7C+SbQnq/fu2LJMHZGTB2Smh0CygXRkUxuN6Zpq1VwIT/lB
  291. # N8BAmhjx6F/h/v8MdLvMXzV4jcATZp6ywCf6k9OfuqCOETDSl9b6Lxm//guHgmUV
  292. # mpzU7n21ZOBv8ElUGZLvIfQCsmZ/ON7obwpFfhamuFIsSJ0w
  293. # SIG # End signature block

Submit a correction or amendment below (
click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:


Remember me