├── AST.psm1 ├── Accelerator.psm1 ├── CliXml.psm1 ├── ExtensionMethods.ps1xml ├── JoinObject.psm1 ├── ReadMe.md ├── Reflection.psd1 ├── Reflection.psm1 ├── ReleaseNotes.md └── license.txt /AST.psm1: -------------------------------------------------------------------------------- 1 | function Test-RestrictedLanguage { 2 | param( 3 | # The scriptblock to test against the restricted language rules 4 | [Parameter(Mandatory=$True)] 5 | [ScriptBlock]$Script, 6 | # Commands to allow 7 | [String[]]$AllowedCommands, 8 | # Variables to allow 9 | [String[]]$AllowedVariables, 10 | # If set, allows Environment Variables in the scriptblock 11 | [Switch]$AllowEnvironmentVariables 12 | ) 13 | 14 | $Script.CheckRestrictedLanguage($AllowedCommands, $AllowedVariables, $AllowEnvironmentVariables) 15 | } 16 | 17 | function Get-ParseResults { 18 | param( 19 | # The script or file path to parse 20 | [Parameter(Mandatory=$true, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)] 21 | [Alias("Path","PSPath")] 22 | $Script 23 | ) 24 | 25 | $ParseErrors = $null 26 | $Tokens = $null 27 | if(Test-Path "$Script" -ErrorAction SilentlyContinue) { 28 | $AST = [System.Management.Automation.Language.Parser]::ParseFile((Convert-Path $Script), [ref]$Tokens, [ref]$ParseErrors) 29 | } else { 30 | $AST = [System.Management.Automation.Language.Parser]::ParseInput([String]$Script, [ref]$Tokens, [ref]$ParseErrors) 31 | } 32 | 33 | New-Object PSObject -Property @{ 34 | ParseErrors = $ParseErrors 35 | Tokens = $Tokens 36 | AST = $AST 37 | } | % { $_.PSTypeNames.Insert(0, "System.Management.Automation.Language.ParseResults"); $_ } 38 | } 39 | 40 | function Find-Token { 41 | param( 42 | # test case (in the original FilterScript format used by Where-Object) 43 | [Parameter(Position=1)] 44 | [ScriptBlock]$FilterScript, 45 | 46 | # The AST to search for tokens 47 | [Parameter(Mandatory=$True, ValueFromPipeline=$true, ValueFromPipelineByPropertyName= $True)] 48 | [System.Management.Automation.Language.Ast]$AST, 49 | 50 | [Switch]$Recurse 51 | ) 52 | $AST.FindAll({param($ast) Where-Object -Input $ast -FilterScript $FilterScript }, $Recurse) 53 | } 54 | 55 | # SIG # Begin signature block 56 | # MIIXxAYJKoZIhvcNAQcCoIIXtTCCF7ECAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB 57 | # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR 58 | # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU8smZhKOPPvULFCUqns/cFBEA 59 | # MBugghL3MIID7jCCA1egAwIBAgIQfpPr+3zGTlnqS5p31Ab8OzANBgkqhkiG9w0B 60 | # AQUFADCBizELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIG 61 | # A1UEBxMLRHVyYmFudmlsbGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhh 62 | # d3RlIENlcnRpZmljYXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcg 63 | # Q0EwHhcNMTIxMjIxMDAwMDAwWhcNMjAxMjMwMjM1OTU5WjBeMQswCQYDVQQGEwJV 64 | # UzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xMDAuBgNVBAMTJ1N5bWFu 65 | # dGVjIFRpbWUgU3RhbXBpbmcgU2VydmljZXMgQ0EgLSBHMjCCASIwDQYJKoZIhvcN 66 | # AQEBBQADggEPADCCAQoCggEBALGss0lUS5ccEgrYJXmRIlcqb9y4JsRDc2vCvy5Q 67 | # WvsUwnaOQwElQ7Sh4kX06Ld7w3TMIte0lAAC903tv7S3RCRrzV9FO9FEzkMScxeC 68 | # i2m0K8uZHqxyGyZNcR+xMd37UWECU6aq9UksBXhFpS+JzueZ5/6M4lc/PcaS3Er4 69 | # ezPkeQr78HWIQZz/xQNRmarXbJ+TaYdlKYOFwmAUxMjJOxTawIHwHw103pIiq8r3 70 | # +3R8J+b3Sht/p8OeLa6K6qbmqicWfWH3mHERvOJQoUvlXfrlDqcsn6plINPYlujI 71 | # fKVOSET/GeJEB5IL12iEgF1qeGRFzWBGflTBE3zFefHJwXECAwEAAaOB+jCB9zAd 72 | # BgNVHQ4EFgQUX5r1blzMzHSa1N197z/b7EyALt0wMgYIKwYBBQUHAQEEJjAkMCIG 73 | # CCsGAQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMBIGA1UdEwEB/wQIMAYB 74 | # Af8CAQAwPwYDVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NybC50aGF3dGUuY29tL1Ro 75 | # YXd0ZVRpbWVzdGFtcGluZ0NBLmNybDATBgNVHSUEDDAKBggrBgEFBQcDCDAOBgNV 76 | # HQ8BAf8EBAMCAQYwKAYDVR0RBCEwH6QdMBsxGTAXBgNVBAMTEFRpbWVTdGFtcC0y 77 | # MDQ4LTEwDQYJKoZIhvcNAQEFBQADgYEAAwmbj3nvf1kwqu9otfrjCR27T4IGXTdf 78 | # plKfFo3qHJIJRG71betYfDDo+WmNI3MLEm9Hqa45EfgqsZuwGsOO61mWAK3ODE2y 79 | # 0DGmCFwqevzieh1XTKhlGOl5QGIllm7HxzdqgyEIjkHq3dlXPx13SYcqFgZepjhq 80 | # IhKjURmDfrYwggSjMIIDi6ADAgECAhAOz/Q4yP6/NW4E2GqYGxpQMA0GCSqGSIb3 81 | # DQEBBQUAMF4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3Jh 82 | # dGlvbjEwMC4GA1UEAxMnU3ltYW50ZWMgVGltZSBTdGFtcGluZyBTZXJ2aWNlcyBD 83 | # QSAtIEcyMB4XDTEyMTAxODAwMDAwMFoXDTIwMTIyOTIzNTk1OVowYjELMAkGA1UE 84 | # BhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMTQwMgYDVQQDEytT 85 | # eW1hbnRlYyBUaW1lIFN0YW1waW5nIFNlcnZpY2VzIFNpZ25lciAtIEc0MIIBIjAN 86 | # BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAomMLOUS4uyOnREm7Dv+h8GEKU5Ow 87 | # mNutLA9KxW7/hjxTVQ8VzgQ/K/2plpbZvmF5C1vJTIZ25eBDSyKV7sIrQ8Gf2Gi0 88 | # jkBP7oU4uRHFI/JkWPAVMm9OV6GuiKQC1yoezUvh3WPVF4kyW7BemVqonShQDhfu 89 | # ltthO0VRHc8SVguSR/yrrvZmPUescHLnkudfzRC5xINklBm9JYDh6NIipdC6Anqh 90 | # d5NbZcPuF3S8QYYq3AhMjJKMkS2ed0QfaNaodHfbDlsyi1aLM73ZY8hJnTrFxeoz 91 | # C9Lxoxv0i77Zs1eLO94Ep3oisiSuLsdwxb5OgyYI+wu9qU+ZCOEQKHKqzQIDAQAB 92 | # o4IBVzCCAVMwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAO 93 | # BgNVHQ8BAf8EBAMCB4AwcwYIKwYBBQUHAQEEZzBlMCoGCCsGAQUFBzABhh5odHRw 94 | # Oi8vdHMtb2NzcC53cy5zeW1hbnRlYy5jb20wNwYIKwYBBQUHMAKGK2h0dHA6Ly90 95 | # cy1haWEud3Muc3ltYW50ZWMuY29tL3Rzcy1jYS1nMi5jZXIwPAYDVR0fBDUwMzAx 96 | # oC+gLYYraHR0cDovL3RzLWNybC53cy5zeW1hbnRlYy5jb20vdHNzLWNhLWcyLmNy 97 | # bDAoBgNVHREEITAfpB0wGzEZMBcGA1UEAxMQVGltZVN0YW1wLTIwNDgtMjAdBgNV 98 | # HQ4EFgQURsZpow5KFB7VTNpSYxc/Xja8DeYwHwYDVR0jBBgwFoAUX5r1blzMzHSa 99 | # 1N197z/b7EyALt0wDQYJKoZIhvcNAQEFBQADggEBAHg7tJEqAEzwj2IwN3ijhCcH 100 | # bxiy3iXcoNSUA6qGTiWfmkADHN3O43nLIWgG2rYytG2/9CwmYzPkSWRtDebDZw73 101 | # BaQ1bHyJFsbpst+y6d0gxnEPzZV03LZc3r03H0N45ni1zSgEIKOq8UvEiCmRDoDR 102 | # EfzdXHZuT14ORUZBbg2w6jiasTraCXEQ/Bx5tIB7rGn0/Zy2DBYr8X9bCT2bW+IW 103 | # yhOBbQAuOA2oKY8s4bL0WqkBrxWcLC9JG9siu8P+eJRRw4axgohd8D20UaF5Mysu 104 | # e7ncIAkTcetqGVvP6KUwVyyJST+5z3/Jvz4iaGNTmr1pdKzFHTx/kuDDvBzYBHUw 105 | # ggUmMIIEDqADAgECAhACXbrxBhFj1/jVxh2rtd9BMA0GCSqGSIb3DQEBCwUAMHIx 106 | # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 107 | # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ 108 | # RCBDb2RlIFNpZ25pbmcgQ0EwHhcNMTUwNTA0MDAwMDAwWhcNMTYwNTExMTIwMDAw 109 | # WjBtMQswCQYDVQQGEwJVUzERMA8GA1UECBMITmV3IFlvcmsxFzAVBgNVBAcTDldl 110 | # c3QgSGVucmlldHRhMRgwFgYDVQQKEw9Kb2VsIEguIEJlbm5ldHQxGDAWBgNVBAMT 111 | # D0pvZWwgSC4gQmVubmV0dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB 112 | # AJfRKhfiDjMovUELYgagznWf+HFcDENk118Y/K6UkQDwKmVyVOvDyaVefjSmZZcV 113 | # NZqqYpm9d/Iajf2dauyC3pg3oay8KfXAADLHgbmbvYDc5zGuUNsTzMUOKlp9h13c 114 | # qsg898JwpRpI659xCQgJjZ6V83QJh+wnHvjA9ojjA4xkbwhGp4Eit6B/uGthEA11 115 | # IHcFcXeNI3fIkbwWiAw7ZoFtSLm688NFhxwm+JH3Xwj0HxuezsmU0Yc/po31CoST 116 | # nGPVN8wppHYZ0GfPwuNK4TwaI0FEXxwdwB+mEduxa5e4zB8DyUZByFW338XkGfc1 117 | # qcJJ+WTyNKFN7saevhwp02cCAwEAAaOCAbswggG3MB8GA1UdIwQYMBaAFFrEuXsq 118 | # CqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBQV0aryV1RTeVOG+wlr2Z2bOVFAbTAO 119 | # BgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwdwYDVR0fBHAwbjA1 120 | # oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJlZC1jcy1n 121 | # MS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEyLWFzc3Vy 122 | # ZWQtY3MtZzEuY3JsMEIGA1UdIAQ7MDkwNwYJYIZIAYb9bAMBMCowKAYIKwYBBQUH 123 | # AgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgYQGCCsGAQUFBwEBBHgw 124 | # djAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tME4GCCsGAQUF 125 | # BzAChkJodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEyQXNz 126 | # dXJlZElEQ29kZVNpZ25pbmdDQS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0B 127 | # AQsFAAOCAQEAIi5p+6eRu6bMOSwJt9HSBkGbaPZlqKkMd4e6AyKIqCRabyjLISwd 128 | # i32p8AT7r2oOubFy+R1LmbBMaPXORLLO9N88qxmJfwFSd+ZzfALevANdbGNp9+6A 129 | # khe3PiR0+eL8ZM5gPJv26OvpYaRebJTfU++T1sS5dYaPAztMNsDzY3krc92O27AS 130 | # WjTjWeILSryqRHXyj8KQbYyWpnG2gWRibjXi5ofL+BHyJQRET5pZbERvl2l9Bo4Z 131 | # st8CM9EQDrdG2vhELNiA6jwenxNPOa6tPkgf8cH8qpGRBVr9yuTMSHS1p9Rc+ybx 132 | # FSKiZkOw8iCR6ZQIeKkSVdwFf8V+HHPrETCCBTAwggQYoAMCAQICEAQJGBtf1btm 133 | # dVNDtW+VUAgwDQYJKoZIhvcNAQELBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoT 134 | # DERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UE 135 | # AxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoX 136 | # DTI4MTAyMjEyMDAwMFowcjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0 137 | # IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNl 138 | # cnQgU0hBMiBBc3N1cmVkIElEIENvZGUgU2lnbmluZyBDQTCCASIwDQYJKoZIhvcN 139 | # AQEBBQADggEPADCCAQoCggEBAPjTsxx/DhGvZ3cH0wsxSRnP0PtFmbE620T1f+Wo 140 | # ndsy13Hqdp0FLreP+pJDwKX5idQ3Gde2qvCchqXYJawOeSg6funRZ9PG+yknx9N7 141 | # I5TkkSOWkHeC+aGEI2YSVDNQdLEoJrskacLCUvIUZ4qJRdQtoaPpiCwgla4cSocI 142 | # 3wz14k1gGL6qxLKucDFmM3E+rHCiq85/6XzLkqHlOzEcz+ryCuRXu0q16XTmK/5s 143 | # y350OTYNkO/ktU6kqepqCquE86xnTrXE94zRICUj6whkPlKWwfIPEvTFjg/Bougs 144 | # UfdzvL2FsWKDc0GCB+Q4i2pzINAPZHM8np+mM6n9Gd8lk9ECAwEAAaOCAc0wggHJ 145 | # MBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoG 146 | # CCsGAQUFBwMDMHkGCCsGAQUFBwEBBG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29j 147 | # c3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdp 148 | # Y2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3J0MIGBBgNVHR8EejB4 149 | # MDqgOKA2hjRodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVk 150 | # SURSb290Q0EuY3JsMDqgOKA2hjRodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGln 151 | # aUNlcnRBc3N1cmVkSURSb290Q0EuY3JsME8GA1UdIARIMEYwOAYKYIZIAYb9bAAC 152 | # BDAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAoG 153 | # CGCGSAGG/WwDMB0GA1UdDgQWBBRaxLl7KgqjpepxA8Bg+S32ZXUOWDAfBgNVHSME 154 | # GDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkqhkiG9w0BAQsFAAOCAQEAPuwN 155 | # WiSz8yLRFcgsfCUpdqgdXRwtOhrE7zBh134LYP3DPQ/Er4v97yrfIFU3sOH20ZJ1 156 | # D1G0bqWOWuJeJIFOEKTuP3GOYw4TS63XX0R58zYUBor3nEZOXP+QsRsHDpEV+7qv 157 | # tVHCjSSuJMbHJyqhKSgaOnEoAjwukaPAJRHinBRHoXpoaK+bp1wgXNlxsQyPu6j4 158 | # xRJon89Ay0BEpRPw5mQMJQhCMrI2iiQC/i9yfhzXSUWW6Fkd6fp0ZGuy62ZD2rOw 159 | # jNXpDd32ASDOmTFjPQgaGLOBm0/GkxAG/AeB+ova+YJJ92JuoVP6EpQYhS6Skepo 160 | # bEQysmah5xikmmRR7zGCBDcwggQzAgEBMIGGMHIxCzAJBgNVBAYTAlVTMRUwEwYD 161 | # VQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAv 162 | # BgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EC 163 | # EAJduvEGEWPX+NXGHau130EwCQYFKw4DAhoFAKB4MBgGCisGAQQBgjcCAQwxCjAI 164 | # oAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIB 165 | # CzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFBps+IIcHHEJHaGZhICA 166 | # pWtZ9bEgMA0GCSqGSIb3DQEBAQUABIIBAIFUDDA6qEPI2LJFCJn6GikSd+6hYjsq 167 | # PjNfwT0sTNvSAbZsgBAX3FRZTnqWXBMbdx9SCVjvWQFHc8ZSEq2kcFh11Cfyj0nZ 168 | # N76aF1mTAfa1iobLMZQEURY/ZkOLwPmP74FV3JI0CEgsNY+/omBU2mH0tkk2h0Nw 169 | # noTa5cqWVPUME3Z0PO0yBMYxp42QQUWedUiEnzwzX8UVJoBqW8JfWvgoQ8CQ6dGu 170 | # p+jA4v3dwZR/RsSN9XAd8rdE2NTvmhx981T+APJdJkXju+iuLd3jLvhFcbGrrjgj 171 | # CZroDqB6HjChcDi2lQci4KWMszkKTuGdosvGdGj93ZubwZ0aXQvRIHmhggILMIIC 172 | # BwYJKoZIhvcNAQkGMYIB+DCCAfQCAQEwcjBeMQswCQYDVQQGEwJVUzEdMBsGA1UE 173 | # ChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xMDAuBgNVBAMTJ1N5bWFudGVjIFRpbWUg 174 | # U3RhbXBpbmcgU2VydmljZXMgQ0EgLSBHMgIQDs/0OMj+vzVuBNhqmBsaUDAJBgUr 175 | # DgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUx 176 | # DxcNMTUwNTA1MDU1ODQ0WjAjBgkqhkiG9w0BCQQxFgQUc5wc0Prsava7dBB5kLSm 177 | # 67gRss8wDQYJKoZIhvcNAQEBBQAEggEAP+woCRYmmcWZqX8O02drLyrlHdtC50Zr 178 | # y86E44elJ5Ik/aiKOiUaKtH8lDb6CwE39awVny8zGzTKgZK7ZiO2yNVOITtn/dst 179 | # 5bmt+aFGHnpQ33G5HXtsb7dEy7LuskApqPx3VV560N19r3F5MEfFnPzEBtjGE6F+ 180 | # QuS005UbTZOvbfUY+NAAFdH6hsQaX+NWWiFeXqM4qy3Xc8Lcm+Oe1XPKWATSNo74 181 | # czVQvzhZyiStJY3LpgCmbC4gU9ToRcDiFlH3CVEVl+Gyc36kXNH4IIjkd8nr4U2r 182 | # C9DyFPnkIvLqtGjgfb5798I68Plx6gHqMuJS5IVPcIM5ZaT9K9s0OA== 183 | # SIG # End signature block 184 | -------------------------------------------------------------------------------- /Accelerator.psm1: -------------------------------------------------------------------------------- 1 | # get a reference to the Type 2 | $xlr8r = [psobject].assembly.gettype("System.Management.Automation.TypeAccelerators") 3 | 4 | function Add-Accelerator { 5 | <# 6 | .Synopsis 7 | Add a type accelerator to the current session 8 | .Description 9 | The Add-Accelerator function allows you to add a simple type accelerator (like [regex]) for a longer type (like [System.Text.RegularExpressions.Regex]). 10 | .Example 11 | Add-Accelerator list System.Collections.Generic.List``1 12 | $list = New-Object list[string] 13 | 14 | Creates an accelerator for the generic List[T] collection type, and then creates a list of strings. 15 | .Example 16 | Add-Accelerator "List T", "GList" System.Collections.Generic.List``1 17 | $list = New-Object "list t[string]" 18 | 19 | Creates two accelerators for the Generic List[T] collection type. 20 | .Parameter Accelerator 21 | The short form accelerator should be just the name you want to use (without square brackets). 22 | .Parameter Type 23 | The type you want the accelerator to accelerate (without square brackets) 24 | .Notes 25 | When specifying multiple values for a parameter, use commas to separate the values. 26 | For example, "-Accelerator string, regex". 27 | 28 | PowerShell requires arguments that are "types" to NOT have the square bracket type notation, because of the way the parsing engine works. You can either just type in the type as System.Int64, or you can put parentheses around it to help the parser out: ([System.Int64]) 29 | 30 | Also see the help for Get-Accelerator and Remove-Accelerator 31 | .Link 32 | http://huddledmasses.org/powershell-2-ctp3-custom-accelerators-finally/ 33 | #> 34 | [CmdletBinding()] 35 | param( 36 | [Parameter(Position=0,ValueFromPipelineByPropertyName=$true)] 37 | [Alias("Key","Name")] 38 | [string[]]$Accelerator, 39 | 40 | [Parameter(Position=1,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 41 | [Alias("Value","FullName")] 42 | [type]$Type 43 | ) 44 | process { 45 | # add a user-defined accelerator 46 | foreach($a in $Accelerator) { 47 | Write-Verbose "Add [$a] = [$($Type.FullName)]" 48 | if($xlr8r::AddReplace) { 49 | $xlr8r::AddReplace( $a, $Type) 50 | } else { 51 | $null = $xlr8r::Remove( $a ) 52 | $xlr8r::Add( $a, $Type) 53 | } 54 | trap [System.Management.Automation.MethodInvocationException] { 55 | if($xlr8r::get.keys -contains $a) { 56 | if($xlr8r::get[$a] -ne $Type) { 57 | Write-Error "Cannot add accelerator [$a] for [$($Type.FullName)]`n [$a] is already defined as [$($xlr8r::get[$a].FullName)]" 58 | } 59 | Continue; 60 | } 61 | throw 62 | } 63 | } 64 | } 65 | } 66 | 67 | function Get-Accelerator { 68 | <# 69 | .Synopsis 70 | Get one or more type accelerator definitions 71 | .Description 72 | The Get-Accelerator function allows you to look up the type accelerators (like [regex]) defined on your system by their short form or by type 73 | .Example 74 | Get-Accelerator System.String 75 | 76 | Returns the KeyValue pair for the [System.String] accelerator(s) 77 | .Example 78 | Get-Accelerator ps*,wmi* 79 | 80 | Returns the KeyValue pairs for the matching accelerator definition(s) 81 | .Parameter Accelerator 82 | One or more short form accelerators to search for (Accept wildcard characters). 83 | .Parameter Type 84 | One or more types to search for. 85 | .Notes 86 | When specifying multiple values for a parameter, use commas to separate the values. 87 | For example, "-Accelerator string, regex". 88 | 89 | Also see the help for Add-Accelerator and Remove-Accelerator 90 | .Link 91 | http://huddledmasses.org/powershell-2-ctp3-custom-accelerators-finally/ 92 | #> 93 | [CmdletBinding(DefaultParameterSetName="ByType")] 94 | param( 95 | [Parameter(Position=0, ParameterSetName="ByAccelerator", ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] 96 | [Alias("Key","Name")] 97 | [string[]]$Accelerator, 98 | 99 | [Parameter(Position=0, ParameterSetName="ByType", ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] 100 | [Alias("Value","FullName")] 101 | [type[]]$Type 102 | ) 103 | process { 104 | # add a user-defined accelerator 105 | switch($PSCmdlet.ParameterSetName) { 106 | "ByAccelerator" { 107 | $xlr8r::get.GetEnumerator() | % { 108 | foreach($a in $Accelerator) { 109 | if($_.Key -like $a) { $_ } 110 | } 111 | } 112 | break 113 | } 114 | "ByType" { 115 | if($Type -and $Type.Count) { 116 | $xlr8r::get.GetEnumerator() | ? { $Type -contains $_.Value } 117 | } 118 | else { 119 | $xlr8r::get.GetEnumerator() | %{ $_ } 120 | } 121 | break 122 | } 123 | } 124 | } 125 | } 126 | 127 | function Remove-Accelerator { 128 | <# 129 | .Synopsis 130 | Remove a type accelerator from the current session 131 | .Description 132 | The Remove-Accelerator function allows you to remove a simple type accelerator (like [regex]) from the current session. You can pass one or more accelerators, and even wildcards, but you should be aware that you can remove even the built-in accelerators. 133 | 134 | .Example 135 | Remove-Accelerator int 136 | Add-Accelerator int Int64 137 | 138 | Removes the "int" accelerator for Int32 and adds a new one for Int64. I can't recommend doing this, but it's pretty cool that it works: 139 | 140 | So now, "$(([int]3.4).GetType().FullName)" would return "System.Int64" 141 | .Example 142 | Get-Accelerator System.Single | Remove-Accelerator 143 | 144 | Removes both of the default accelerators for System.Single: [float] and [single] 145 | .Example 146 | Get-Accelerator System.Single | Remove-Accelerator -WhatIf 147 | 148 | Demonstrates that Remove-Accelerator supports -Confirm and -Whatif. Will Print: 149 | What if: Removes the alias [float] for type [System.Single] 150 | What if: Removes the alias [single] for type [System.Single] 151 | .Parameter Accelerator 152 | The short form accelerator that you want to remove (Accept wildcard characters). 153 | .Notes 154 | When specifying multiple values for a parameter, use commas to separate the values. 155 | For example, "-Accel string, regex". 156 | 157 | Also see the help for Add-Accelerator and Get-Accelerator 158 | .Link 159 | http://huddledmasses.org/powershell-2-ctp3-custom-accelerators-finally/ 160 | #> 161 | [CmdletBinding(SupportsShouldProcess=$true)] 162 | param( 163 | [Parameter(Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] 164 | [Alias("Key","FullName")] 165 | [string[]]$Accelerator 166 | ) 167 | process { 168 | foreach($a in $Accelerator) { 169 | foreach($key in $xlr8r::Get.Keys -like $a) { 170 | if($PSCmdlet.ShouldProcess( "Removes the alias [$($Key)] for type [$($xlr8r::Get[$key].FullName)]", 171 | "Remove the alias [$($Key)] for type [$($xlr8r::Get[$key].FullName)]?", 172 | "Removing Type Accelerator" )) { 173 | # remove a user-defined accelerator 174 | $xlr8r::remove($key) 175 | } 176 | } 177 | } 178 | } 179 | } 180 | 181 | function Import-Namespace { 182 | [CmdletBinding()] 183 | param( 184 | [Parameter(ValueFromPipeline=$true)] 185 | [string]$Namespace, 186 | 187 | [Switch]$Force 188 | ) 189 | end { 190 | Get-Type -Namespace $Namespace -Force:$Force | Add-Accelerator 191 | } 192 | } 193 | 194 | Add-Accelerator list System.Collections.Generic.List``1 195 | Add-Accelerator dictionary System.Collections.Generic.Dictionary``2 196 | 197 | # SIG # Begin signature block 198 | # MIIXxAYJKoZIhvcNAQcCoIIXtTCCF7ECAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB 199 | # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR 200 | # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUx/AXZvf9khH/P65NiHEiv8Xt 201 | # aTKgghL3MIID7jCCA1egAwIBAgIQfpPr+3zGTlnqS5p31Ab8OzANBgkqhkiG9w0B 202 | # AQUFADCBizELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIG 203 | # A1UEBxMLRHVyYmFudmlsbGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhh 204 | # d3RlIENlcnRpZmljYXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcg 205 | # Q0EwHhcNMTIxMjIxMDAwMDAwWhcNMjAxMjMwMjM1OTU5WjBeMQswCQYDVQQGEwJV 206 | # UzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xMDAuBgNVBAMTJ1N5bWFu 207 | # dGVjIFRpbWUgU3RhbXBpbmcgU2VydmljZXMgQ0EgLSBHMjCCASIwDQYJKoZIhvcN 208 | # AQEBBQADggEPADCCAQoCggEBALGss0lUS5ccEgrYJXmRIlcqb9y4JsRDc2vCvy5Q 209 | # WvsUwnaOQwElQ7Sh4kX06Ld7w3TMIte0lAAC903tv7S3RCRrzV9FO9FEzkMScxeC 210 | # i2m0K8uZHqxyGyZNcR+xMd37UWECU6aq9UksBXhFpS+JzueZ5/6M4lc/PcaS3Er4 211 | # ezPkeQr78HWIQZz/xQNRmarXbJ+TaYdlKYOFwmAUxMjJOxTawIHwHw103pIiq8r3 212 | # +3R8J+b3Sht/p8OeLa6K6qbmqicWfWH3mHERvOJQoUvlXfrlDqcsn6plINPYlujI 213 | # fKVOSET/GeJEB5IL12iEgF1qeGRFzWBGflTBE3zFefHJwXECAwEAAaOB+jCB9zAd 214 | # BgNVHQ4EFgQUX5r1blzMzHSa1N197z/b7EyALt0wMgYIKwYBBQUHAQEEJjAkMCIG 215 | # CCsGAQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMBIGA1UdEwEB/wQIMAYB 216 | # Af8CAQAwPwYDVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NybC50aGF3dGUuY29tL1Ro 217 | # YXd0ZVRpbWVzdGFtcGluZ0NBLmNybDATBgNVHSUEDDAKBggrBgEFBQcDCDAOBgNV 218 | # HQ8BAf8EBAMCAQYwKAYDVR0RBCEwH6QdMBsxGTAXBgNVBAMTEFRpbWVTdGFtcC0y 219 | # MDQ4LTEwDQYJKoZIhvcNAQEFBQADgYEAAwmbj3nvf1kwqu9otfrjCR27T4IGXTdf 220 | # plKfFo3qHJIJRG71betYfDDo+WmNI3MLEm9Hqa45EfgqsZuwGsOO61mWAK3ODE2y 221 | # 0DGmCFwqevzieh1XTKhlGOl5QGIllm7HxzdqgyEIjkHq3dlXPx13SYcqFgZepjhq 222 | # IhKjURmDfrYwggSjMIIDi6ADAgECAhAOz/Q4yP6/NW4E2GqYGxpQMA0GCSqGSIb3 223 | # DQEBBQUAMF4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3Jh 224 | # dGlvbjEwMC4GA1UEAxMnU3ltYW50ZWMgVGltZSBTdGFtcGluZyBTZXJ2aWNlcyBD 225 | # QSAtIEcyMB4XDTEyMTAxODAwMDAwMFoXDTIwMTIyOTIzNTk1OVowYjELMAkGA1UE 226 | # BhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMTQwMgYDVQQDEytT 227 | # eW1hbnRlYyBUaW1lIFN0YW1waW5nIFNlcnZpY2VzIFNpZ25lciAtIEc0MIIBIjAN 228 | # BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAomMLOUS4uyOnREm7Dv+h8GEKU5Ow 229 | # mNutLA9KxW7/hjxTVQ8VzgQ/K/2plpbZvmF5C1vJTIZ25eBDSyKV7sIrQ8Gf2Gi0 230 | # jkBP7oU4uRHFI/JkWPAVMm9OV6GuiKQC1yoezUvh3WPVF4kyW7BemVqonShQDhfu 231 | # ltthO0VRHc8SVguSR/yrrvZmPUescHLnkudfzRC5xINklBm9JYDh6NIipdC6Anqh 232 | # d5NbZcPuF3S8QYYq3AhMjJKMkS2ed0QfaNaodHfbDlsyi1aLM73ZY8hJnTrFxeoz 233 | # C9Lxoxv0i77Zs1eLO94Ep3oisiSuLsdwxb5OgyYI+wu9qU+ZCOEQKHKqzQIDAQAB 234 | # o4IBVzCCAVMwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAO 235 | # BgNVHQ8BAf8EBAMCB4AwcwYIKwYBBQUHAQEEZzBlMCoGCCsGAQUFBzABhh5odHRw 236 | # Oi8vdHMtb2NzcC53cy5zeW1hbnRlYy5jb20wNwYIKwYBBQUHMAKGK2h0dHA6Ly90 237 | # cy1haWEud3Muc3ltYW50ZWMuY29tL3Rzcy1jYS1nMi5jZXIwPAYDVR0fBDUwMzAx 238 | # oC+gLYYraHR0cDovL3RzLWNybC53cy5zeW1hbnRlYy5jb20vdHNzLWNhLWcyLmNy 239 | # bDAoBgNVHREEITAfpB0wGzEZMBcGA1UEAxMQVGltZVN0YW1wLTIwNDgtMjAdBgNV 240 | # HQ4EFgQURsZpow5KFB7VTNpSYxc/Xja8DeYwHwYDVR0jBBgwFoAUX5r1blzMzHSa 241 | # 1N197z/b7EyALt0wDQYJKoZIhvcNAQEFBQADggEBAHg7tJEqAEzwj2IwN3ijhCcH 242 | # bxiy3iXcoNSUA6qGTiWfmkADHN3O43nLIWgG2rYytG2/9CwmYzPkSWRtDebDZw73 243 | # BaQ1bHyJFsbpst+y6d0gxnEPzZV03LZc3r03H0N45ni1zSgEIKOq8UvEiCmRDoDR 244 | # EfzdXHZuT14ORUZBbg2w6jiasTraCXEQ/Bx5tIB7rGn0/Zy2DBYr8X9bCT2bW+IW 245 | # yhOBbQAuOA2oKY8s4bL0WqkBrxWcLC9JG9siu8P+eJRRw4axgohd8D20UaF5Mysu 246 | # e7ncIAkTcetqGVvP6KUwVyyJST+5z3/Jvz4iaGNTmr1pdKzFHTx/kuDDvBzYBHUw 247 | # ggUmMIIEDqADAgECAhACXbrxBhFj1/jVxh2rtd9BMA0GCSqGSIb3DQEBCwUAMHIx 248 | # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 249 | # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ 250 | # RCBDb2RlIFNpZ25pbmcgQ0EwHhcNMTUwNTA0MDAwMDAwWhcNMTYwNTExMTIwMDAw 251 | # WjBtMQswCQYDVQQGEwJVUzERMA8GA1UECBMITmV3IFlvcmsxFzAVBgNVBAcTDldl 252 | # c3QgSGVucmlldHRhMRgwFgYDVQQKEw9Kb2VsIEguIEJlbm5ldHQxGDAWBgNVBAMT 253 | # D0pvZWwgSC4gQmVubmV0dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB 254 | # AJfRKhfiDjMovUELYgagznWf+HFcDENk118Y/K6UkQDwKmVyVOvDyaVefjSmZZcV 255 | # NZqqYpm9d/Iajf2dauyC3pg3oay8KfXAADLHgbmbvYDc5zGuUNsTzMUOKlp9h13c 256 | # qsg898JwpRpI659xCQgJjZ6V83QJh+wnHvjA9ojjA4xkbwhGp4Eit6B/uGthEA11 257 | # IHcFcXeNI3fIkbwWiAw7ZoFtSLm688NFhxwm+JH3Xwj0HxuezsmU0Yc/po31CoST 258 | # nGPVN8wppHYZ0GfPwuNK4TwaI0FEXxwdwB+mEduxa5e4zB8DyUZByFW338XkGfc1 259 | # qcJJ+WTyNKFN7saevhwp02cCAwEAAaOCAbswggG3MB8GA1UdIwQYMBaAFFrEuXsq 260 | # CqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBQV0aryV1RTeVOG+wlr2Z2bOVFAbTAO 261 | # BgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwdwYDVR0fBHAwbjA1 262 | # oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJlZC1jcy1n 263 | # MS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEyLWFzc3Vy 264 | # ZWQtY3MtZzEuY3JsMEIGA1UdIAQ7MDkwNwYJYIZIAYb9bAMBMCowKAYIKwYBBQUH 265 | # AgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgYQGCCsGAQUFBwEBBHgw 266 | # djAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tME4GCCsGAQUF 267 | # BzAChkJodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEyQXNz 268 | # dXJlZElEQ29kZVNpZ25pbmdDQS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0B 269 | # AQsFAAOCAQEAIi5p+6eRu6bMOSwJt9HSBkGbaPZlqKkMd4e6AyKIqCRabyjLISwd 270 | # i32p8AT7r2oOubFy+R1LmbBMaPXORLLO9N88qxmJfwFSd+ZzfALevANdbGNp9+6A 271 | # khe3PiR0+eL8ZM5gPJv26OvpYaRebJTfU++T1sS5dYaPAztMNsDzY3krc92O27AS 272 | # WjTjWeILSryqRHXyj8KQbYyWpnG2gWRibjXi5ofL+BHyJQRET5pZbERvl2l9Bo4Z 273 | # st8CM9EQDrdG2vhELNiA6jwenxNPOa6tPkgf8cH8qpGRBVr9yuTMSHS1p9Rc+ybx 274 | # FSKiZkOw8iCR6ZQIeKkSVdwFf8V+HHPrETCCBTAwggQYoAMCAQICEAQJGBtf1btm 275 | # dVNDtW+VUAgwDQYJKoZIhvcNAQELBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoT 276 | # DERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UE 277 | # AxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoX 278 | # DTI4MTAyMjEyMDAwMFowcjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0 279 | # IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNl 280 | # cnQgU0hBMiBBc3N1cmVkIElEIENvZGUgU2lnbmluZyBDQTCCASIwDQYJKoZIhvcN 281 | # AQEBBQADggEPADCCAQoCggEBAPjTsxx/DhGvZ3cH0wsxSRnP0PtFmbE620T1f+Wo 282 | # ndsy13Hqdp0FLreP+pJDwKX5idQ3Gde2qvCchqXYJawOeSg6funRZ9PG+yknx9N7 283 | # I5TkkSOWkHeC+aGEI2YSVDNQdLEoJrskacLCUvIUZ4qJRdQtoaPpiCwgla4cSocI 284 | # 3wz14k1gGL6qxLKucDFmM3E+rHCiq85/6XzLkqHlOzEcz+ryCuRXu0q16XTmK/5s 285 | # y350OTYNkO/ktU6kqepqCquE86xnTrXE94zRICUj6whkPlKWwfIPEvTFjg/Bougs 286 | # UfdzvL2FsWKDc0GCB+Q4i2pzINAPZHM8np+mM6n9Gd8lk9ECAwEAAaOCAc0wggHJ 287 | # MBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoG 288 | # CCsGAQUFBwMDMHkGCCsGAQUFBwEBBG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29j 289 | # c3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdp 290 | # Y2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3J0MIGBBgNVHR8EejB4 291 | # MDqgOKA2hjRodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVk 292 | # SURSb290Q0EuY3JsMDqgOKA2hjRodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGln 293 | # aUNlcnRBc3N1cmVkSURSb290Q0EuY3JsME8GA1UdIARIMEYwOAYKYIZIAYb9bAAC 294 | # BDAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAoG 295 | # CGCGSAGG/WwDMB0GA1UdDgQWBBRaxLl7KgqjpepxA8Bg+S32ZXUOWDAfBgNVHSME 296 | # GDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkqhkiG9w0BAQsFAAOCAQEAPuwN 297 | # WiSz8yLRFcgsfCUpdqgdXRwtOhrE7zBh134LYP3DPQ/Er4v97yrfIFU3sOH20ZJ1 298 | # D1G0bqWOWuJeJIFOEKTuP3GOYw4TS63XX0R58zYUBor3nEZOXP+QsRsHDpEV+7qv 299 | # tVHCjSSuJMbHJyqhKSgaOnEoAjwukaPAJRHinBRHoXpoaK+bp1wgXNlxsQyPu6j4 300 | # xRJon89Ay0BEpRPw5mQMJQhCMrI2iiQC/i9yfhzXSUWW6Fkd6fp0ZGuy62ZD2rOw 301 | # jNXpDd32ASDOmTFjPQgaGLOBm0/GkxAG/AeB+ova+YJJ92JuoVP6EpQYhS6Skepo 302 | # bEQysmah5xikmmRR7zGCBDcwggQzAgEBMIGGMHIxCzAJBgNVBAYTAlVTMRUwEwYD 303 | # VQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAv 304 | # BgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EC 305 | # EAJduvEGEWPX+NXGHau130EwCQYFKw4DAhoFAKB4MBgGCisGAQQBgjcCAQwxCjAI 306 | # oAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIB 307 | # CzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFBcjxAPk1V+Y9yXHmBDz 308 | # iZeACKv4MA0GCSqGSIb3DQEBAQUABIIBABTgRWlvD0B/J9NDbKrBnp3OB71/MY1o 309 | # 9Ruc4R2X+5DuH275iKoLEB/6N9ETrGYMO1NSVWSNBDtamzFLRoaQxbamts8BOyMR 310 | # izcapd0xMfIZJpb3IQDj3iRbW4hTDAmnnr4JnqQlDLfRZ34mgbzAw9rVK92thENS 311 | # m+39bMK15LREwRlqr3iiOzZ5r3R8VPxgbehtrp83XjgeB+lhlU7pFL5RVNHsflKt 312 | # uDMv3sY2qyTHbE/HkyZTjnhtS+5xx85PzRkhw48XnxBYtyfEB/2ohexmaLwsF+Ap 313 | # C3xwz1LsAUJEme7w1jbec2h+FWcUKAdDDmCmJbtBfTjfA0LcyVhK+lihggILMIIC 314 | # BwYJKoZIhvcNAQkGMYIB+DCCAfQCAQEwcjBeMQswCQYDVQQGEwJVUzEdMBsGA1UE 315 | # ChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xMDAuBgNVBAMTJ1N5bWFudGVjIFRpbWUg 316 | # U3RhbXBpbmcgU2VydmljZXMgQ0EgLSBHMgIQDs/0OMj+vzVuBNhqmBsaUDAJBgUr 317 | # DgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUx 318 | # DxcNMTUwNTA3MjIwMDAyWjAjBgkqhkiG9w0BCQQxFgQULo3zbVGjIQ/pFhLZ6LT+ 319 | # I/vobu0wDQYJKoZIhvcNAQEBBQAEggEAlZ5GCHeigJleTlrCVIgk+EDlPUVCbvOG 320 | # 1q9++gm8IcFBt7AQ5MQ32pFqqBQS7MTIibQ7sMJINb/tvm04w7tlQxBCtyXr39xm 321 | # 26W5yVGrDTfDeOd1Rrp9UG6PtCWjd7RjjiJDWYNd0IdBPR6ZBQcgNzhdP5yj9zJS 322 | # U+jXmGUwAfkgxTFZus48hU86QzdTexkwhZgwhdxCJRvBsy5nHADNjOiTITquekqJ 323 | # ykYiWJN2OXPKJUFSA5Niv0T6tcUD12UR0Dx4kU0wc2JH0vmolT3DVCfz6XdeeFv3 324 | # pOfK+T8YlEhQEkPqBqkH1z1T2bmJK6KNoHMl3RRvM+nWxFpYBP+QXw== 325 | # SIG # End signature block 326 | -------------------------------------------------------------------------------- /CliXml.psm1: -------------------------------------------------------------------------------- 1 | #requires -version 2.0 2 | function ConvertFrom-CliXml { 3 | param( 4 | [Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)] 5 | [ValidateNotNullOrEmpty()] 6 | [String[]]$InputObject 7 | ) 8 | begin 9 | { 10 | $OFS = "`n" 11 | [String]$xmlString = "" 12 | } 13 | process 14 | { 15 | $xmlString += $InputObject 16 | } 17 | end 18 | { 19 | $type = [PSObject].Assembly.GetType('System.Management.Automation.Deserializer') 20 | $ctor = $type.GetConstructor('instance,nonpublic', $null, @([xml.xmlreader]), $null) 21 | $sr = New-Object System.IO.StringReader $xmlString 22 | $xr = New-Object System.Xml.XmlTextReader $sr 23 | $deserializer = $ctor.Invoke($xr) 24 | $done = $type.GetMethod('Done', [System.Reflection.BindingFlags]'nonpublic,instance') 25 | while (!$type.InvokeMember("Done", "InvokeMethod,NonPublic,Instance", $null, $deserializer, @())) 26 | { 27 | try { 28 | $type.InvokeMember("Deserialize", "InvokeMethod,NonPublic,Instance", $null, $deserializer, @()) 29 | } catch { 30 | Write-Warning "Could not deserialize ${string}: $_" 31 | } 32 | } 33 | $xr.Close() 34 | $sr.Dispose() 35 | } 36 | } 37 | 38 | function ConvertTo-CliXml { 39 | param( 40 | [Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)] 41 | [ValidateNotNullOrEmpty()] 42 | [PSObject[]]$InputObject 43 | ) 44 | begin { 45 | $type = [PSObject].Assembly.GetType('System.Management.Automation.Serializer') 46 | $ctor = $type.GetConstructor('instance,nonpublic', $null, @([System.Xml.XmlWriter]), $null) 47 | $sw = New-Object System.IO.StringWriter 48 | $xw = New-Object System.Xml.XmlTextWriter $sw 49 | $serializer = $ctor.Invoke($xw) 50 | #$method = $type.GetMethod('Serialize', 'nonpublic,instance', $null, [type[]]@([object]), $null) 51 | } 52 | process { 53 | try { 54 | [void]$type.InvokeMember("Serialize", "InvokeMethod,NonPublic,Instance", $null, $serializer, [object[]]@($InputObject)) 55 | } catch { 56 | Write-Warning "Could not serialize $($InputObject.GetType()): $_" 57 | } 58 | } 59 | end { 60 | [void]$type.InvokeMember("Done", "InvokeMethod,NonPublic,Instance", $null, $serializer, @()) 61 | $sw.ToString() 62 | $xw.Close() 63 | $sw.Dispose() 64 | } 65 | } 66 | 67 | 68 | $filesIn = ls | select * -first 2 69 | $xml = $filesIn | ConvertTo-CliXml 70 | $filesOut = $xml | ConvertFrom-CliXml 71 | 72 | Compare-Object $filesIn $filesOut -IncludeEqual 73 | # SIG # Begin signature block 74 | # MIIXxAYJKoZIhvcNAQcCoIIXtTCCF7ECAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB 75 | # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR 76 | # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUMg5WFiO6reJZP/DMasSS8OHt 77 | # 7KigghL3MIID7jCCA1egAwIBAgIQfpPr+3zGTlnqS5p31Ab8OzANBgkqhkiG9w0B 78 | # AQUFADCBizELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIG 79 | # A1UEBxMLRHVyYmFudmlsbGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhh 80 | # d3RlIENlcnRpZmljYXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcg 81 | # Q0EwHhcNMTIxMjIxMDAwMDAwWhcNMjAxMjMwMjM1OTU5WjBeMQswCQYDVQQGEwJV 82 | # UzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xMDAuBgNVBAMTJ1N5bWFu 83 | # dGVjIFRpbWUgU3RhbXBpbmcgU2VydmljZXMgQ0EgLSBHMjCCASIwDQYJKoZIhvcN 84 | # AQEBBQADggEPADCCAQoCggEBALGss0lUS5ccEgrYJXmRIlcqb9y4JsRDc2vCvy5Q 85 | # WvsUwnaOQwElQ7Sh4kX06Ld7w3TMIte0lAAC903tv7S3RCRrzV9FO9FEzkMScxeC 86 | # i2m0K8uZHqxyGyZNcR+xMd37UWECU6aq9UksBXhFpS+JzueZ5/6M4lc/PcaS3Er4 87 | # ezPkeQr78HWIQZz/xQNRmarXbJ+TaYdlKYOFwmAUxMjJOxTawIHwHw103pIiq8r3 88 | # +3R8J+b3Sht/p8OeLa6K6qbmqicWfWH3mHERvOJQoUvlXfrlDqcsn6plINPYlujI 89 | # fKVOSET/GeJEB5IL12iEgF1qeGRFzWBGflTBE3zFefHJwXECAwEAAaOB+jCB9zAd 90 | # BgNVHQ4EFgQUX5r1blzMzHSa1N197z/b7EyALt0wMgYIKwYBBQUHAQEEJjAkMCIG 91 | # CCsGAQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMBIGA1UdEwEB/wQIMAYB 92 | # Af8CAQAwPwYDVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NybC50aGF3dGUuY29tL1Ro 93 | # YXd0ZVRpbWVzdGFtcGluZ0NBLmNybDATBgNVHSUEDDAKBggrBgEFBQcDCDAOBgNV 94 | # HQ8BAf8EBAMCAQYwKAYDVR0RBCEwH6QdMBsxGTAXBgNVBAMTEFRpbWVTdGFtcC0y 95 | # MDQ4LTEwDQYJKoZIhvcNAQEFBQADgYEAAwmbj3nvf1kwqu9otfrjCR27T4IGXTdf 96 | # plKfFo3qHJIJRG71betYfDDo+WmNI3MLEm9Hqa45EfgqsZuwGsOO61mWAK3ODE2y 97 | # 0DGmCFwqevzieh1XTKhlGOl5QGIllm7HxzdqgyEIjkHq3dlXPx13SYcqFgZepjhq 98 | # IhKjURmDfrYwggSjMIIDi6ADAgECAhAOz/Q4yP6/NW4E2GqYGxpQMA0GCSqGSIb3 99 | # DQEBBQUAMF4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3Jh 100 | # dGlvbjEwMC4GA1UEAxMnU3ltYW50ZWMgVGltZSBTdGFtcGluZyBTZXJ2aWNlcyBD 101 | # QSAtIEcyMB4XDTEyMTAxODAwMDAwMFoXDTIwMTIyOTIzNTk1OVowYjELMAkGA1UE 102 | # BhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMTQwMgYDVQQDEytT 103 | # eW1hbnRlYyBUaW1lIFN0YW1waW5nIFNlcnZpY2VzIFNpZ25lciAtIEc0MIIBIjAN 104 | # BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAomMLOUS4uyOnREm7Dv+h8GEKU5Ow 105 | # mNutLA9KxW7/hjxTVQ8VzgQ/K/2plpbZvmF5C1vJTIZ25eBDSyKV7sIrQ8Gf2Gi0 106 | # jkBP7oU4uRHFI/JkWPAVMm9OV6GuiKQC1yoezUvh3WPVF4kyW7BemVqonShQDhfu 107 | # ltthO0VRHc8SVguSR/yrrvZmPUescHLnkudfzRC5xINklBm9JYDh6NIipdC6Anqh 108 | # d5NbZcPuF3S8QYYq3AhMjJKMkS2ed0QfaNaodHfbDlsyi1aLM73ZY8hJnTrFxeoz 109 | # C9Lxoxv0i77Zs1eLO94Ep3oisiSuLsdwxb5OgyYI+wu9qU+ZCOEQKHKqzQIDAQAB 110 | # o4IBVzCCAVMwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAO 111 | # BgNVHQ8BAf8EBAMCB4AwcwYIKwYBBQUHAQEEZzBlMCoGCCsGAQUFBzABhh5odHRw 112 | # Oi8vdHMtb2NzcC53cy5zeW1hbnRlYy5jb20wNwYIKwYBBQUHMAKGK2h0dHA6Ly90 113 | # cy1haWEud3Muc3ltYW50ZWMuY29tL3Rzcy1jYS1nMi5jZXIwPAYDVR0fBDUwMzAx 114 | # oC+gLYYraHR0cDovL3RzLWNybC53cy5zeW1hbnRlYy5jb20vdHNzLWNhLWcyLmNy 115 | # bDAoBgNVHREEITAfpB0wGzEZMBcGA1UEAxMQVGltZVN0YW1wLTIwNDgtMjAdBgNV 116 | # HQ4EFgQURsZpow5KFB7VTNpSYxc/Xja8DeYwHwYDVR0jBBgwFoAUX5r1blzMzHSa 117 | # 1N197z/b7EyALt0wDQYJKoZIhvcNAQEFBQADggEBAHg7tJEqAEzwj2IwN3ijhCcH 118 | # bxiy3iXcoNSUA6qGTiWfmkADHN3O43nLIWgG2rYytG2/9CwmYzPkSWRtDebDZw73 119 | # BaQ1bHyJFsbpst+y6d0gxnEPzZV03LZc3r03H0N45ni1zSgEIKOq8UvEiCmRDoDR 120 | # EfzdXHZuT14ORUZBbg2w6jiasTraCXEQ/Bx5tIB7rGn0/Zy2DBYr8X9bCT2bW+IW 121 | # yhOBbQAuOA2oKY8s4bL0WqkBrxWcLC9JG9siu8P+eJRRw4axgohd8D20UaF5Mysu 122 | # e7ncIAkTcetqGVvP6KUwVyyJST+5z3/Jvz4iaGNTmr1pdKzFHTx/kuDDvBzYBHUw 123 | # ggUmMIIEDqADAgECAhACXbrxBhFj1/jVxh2rtd9BMA0GCSqGSIb3DQEBCwUAMHIx 124 | # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 125 | # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ 126 | # RCBDb2RlIFNpZ25pbmcgQ0EwHhcNMTUwNTA0MDAwMDAwWhcNMTYwNTExMTIwMDAw 127 | # WjBtMQswCQYDVQQGEwJVUzERMA8GA1UECBMITmV3IFlvcmsxFzAVBgNVBAcTDldl 128 | # c3QgSGVucmlldHRhMRgwFgYDVQQKEw9Kb2VsIEguIEJlbm5ldHQxGDAWBgNVBAMT 129 | # D0pvZWwgSC4gQmVubmV0dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB 130 | # AJfRKhfiDjMovUELYgagznWf+HFcDENk118Y/K6UkQDwKmVyVOvDyaVefjSmZZcV 131 | # NZqqYpm9d/Iajf2dauyC3pg3oay8KfXAADLHgbmbvYDc5zGuUNsTzMUOKlp9h13c 132 | # qsg898JwpRpI659xCQgJjZ6V83QJh+wnHvjA9ojjA4xkbwhGp4Eit6B/uGthEA11 133 | # IHcFcXeNI3fIkbwWiAw7ZoFtSLm688NFhxwm+JH3Xwj0HxuezsmU0Yc/po31CoST 134 | # nGPVN8wppHYZ0GfPwuNK4TwaI0FEXxwdwB+mEduxa5e4zB8DyUZByFW338XkGfc1 135 | # qcJJ+WTyNKFN7saevhwp02cCAwEAAaOCAbswggG3MB8GA1UdIwQYMBaAFFrEuXsq 136 | # CqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBQV0aryV1RTeVOG+wlr2Z2bOVFAbTAO 137 | # BgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwdwYDVR0fBHAwbjA1 138 | # oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJlZC1jcy1n 139 | # MS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEyLWFzc3Vy 140 | # ZWQtY3MtZzEuY3JsMEIGA1UdIAQ7MDkwNwYJYIZIAYb9bAMBMCowKAYIKwYBBQUH 141 | # AgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgYQGCCsGAQUFBwEBBHgw 142 | # djAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tME4GCCsGAQUF 143 | # BzAChkJodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEyQXNz 144 | # dXJlZElEQ29kZVNpZ25pbmdDQS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0B 145 | # AQsFAAOCAQEAIi5p+6eRu6bMOSwJt9HSBkGbaPZlqKkMd4e6AyKIqCRabyjLISwd 146 | # i32p8AT7r2oOubFy+R1LmbBMaPXORLLO9N88qxmJfwFSd+ZzfALevANdbGNp9+6A 147 | # khe3PiR0+eL8ZM5gPJv26OvpYaRebJTfU++T1sS5dYaPAztMNsDzY3krc92O27AS 148 | # WjTjWeILSryqRHXyj8KQbYyWpnG2gWRibjXi5ofL+BHyJQRET5pZbERvl2l9Bo4Z 149 | # st8CM9EQDrdG2vhELNiA6jwenxNPOa6tPkgf8cH8qpGRBVr9yuTMSHS1p9Rc+ybx 150 | # FSKiZkOw8iCR6ZQIeKkSVdwFf8V+HHPrETCCBTAwggQYoAMCAQICEAQJGBtf1btm 151 | # dVNDtW+VUAgwDQYJKoZIhvcNAQELBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoT 152 | # DERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UE 153 | # AxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoX 154 | # DTI4MTAyMjEyMDAwMFowcjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0 155 | # IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNl 156 | # cnQgU0hBMiBBc3N1cmVkIElEIENvZGUgU2lnbmluZyBDQTCCASIwDQYJKoZIhvcN 157 | # AQEBBQADggEPADCCAQoCggEBAPjTsxx/DhGvZ3cH0wsxSRnP0PtFmbE620T1f+Wo 158 | # ndsy13Hqdp0FLreP+pJDwKX5idQ3Gde2qvCchqXYJawOeSg6funRZ9PG+yknx9N7 159 | # I5TkkSOWkHeC+aGEI2YSVDNQdLEoJrskacLCUvIUZ4qJRdQtoaPpiCwgla4cSocI 160 | # 3wz14k1gGL6qxLKucDFmM3E+rHCiq85/6XzLkqHlOzEcz+ryCuRXu0q16XTmK/5s 161 | # y350OTYNkO/ktU6kqepqCquE86xnTrXE94zRICUj6whkPlKWwfIPEvTFjg/Bougs 162 | # UfdzvL2FsWKDc0GCB+Q4i2pzINAPZHM8np+mM6n9Gd8lk9ECAwEAAaOCAc0wggHJ 163 | # MBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoG 164 | # CCsGAQUFBwMDMHkGCCsGAQUFBwEBBG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29j 165 | # c3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdp 166 | # Y2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3J0MIGBBgNVHR8EejB4 167 | # MDqgOKA2hjRodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVk 168 | # SURSb290Q0EuY3JsMDqgOKA2hjRodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGln 169 | # aUNlcnRBc3N1cmVkSURSb290Q0EuY3JsME8GA1UdIARIMEYwOAYKYIZIAYb9bAAC 170 | # BDAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAoG 171 | # CGCGSAGG/WwDMB0GA1UdDgQWBBRaxLl7KgqjpepxA8Bg+S32ZXUOWDAfBgNVHSME 172 | # GDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkqhkiG9w0BAQsFAAOCAQEAPuwN 173 | # WiSz8yLRFcgsfCUpdqgdXRwtOhrE7zBh134LYP3DPQ/Er4v97yrfIFU3sOH20ZJ1 174 | # D1G0bqWOWuJeJIFOEKTuP3GOYw4TS63XX0R58zYUBor3nEZOXP+QsRsHDpEV+7qv 175 | # tVHCjSSuJMbHJyqhKSgaOnEoAjwukaPAJRHinBRHoXpoaK+bp1wgXNlxsQyPu6j4 176 | # xRJon89Ay0BEpRPw5mQMJQhCMrI2iiQC/i9yfhzXSUWW6Fkd6fp0ZGuy62ZD2rOw 177 | # jNXpDd32ASDOmTFjPQgaGLOBm0/GkxAG/AeB+ova+YJJ92JuoVP6EpQYhS6Skepo 178 | # bEQysmah5xikmmRR7zGCBDcwggQzAgEBMIGGMHIxCzAJBgNVBAYTAlVTMRUwEwYD 179 | # VQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAv 180 | # BgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EC 181 | # EAJduvEGEWPX+NXGHau130EwCQYFKw4DAhoFAKB4MBgGCisGAQQBgjcCAQwxCjAI 182 | # oAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIB 183 | # CzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFLDeF7iCNInPgeAmgEeF 184 | # XREG+IdOMA0GCSqGSIb3DQEBAQUABIIBAE5APgDlgL83ZHJXFvxhAA/4SAVfLDEI 185 | # 9NQ07fuuMqsIWajG/HtOihyTzAXqmaIPYWSoTtADFn3jjDf8Lna09/ogA9x6B3wG 186 | # xdTWwEn7tkU9lVvsTw53jIb2xgZN+PgS2Ti3PE76KiTaKd0hvSprqpQC1SE+3vD0 187 | # 3L1dtnNCmYRVRFw27/+UiDnOoiPKnV90QQjqB2CNiodFIWRYwh2YSr4cFNhDmrtQ 188 | # RJ1Uc6/1SKt8qr8wPtBv+WOBtGYbqHUqUJwouIohRiBIOA9M9ANf0AgUt3bUy9lT 189 | # 9nW2DY4AL8P4hKa9E9p1YyqfQyXAgYyPJV3h4GDBhl/556PPq8dt3nShggILMIIC 190 | # BwYJKoZIhvcNAQkGMYIB+DCCAfQCAQEwcjBeMQswCQYDVQQGEwJVUzEdMBsGA1UE 191 | # ChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xMDAuBgNVBAMTJ1N5bWFudGVjIFRpbWUg 192 | # U3RhbXBpbmcgU2VydmljZXMgQ0EgLSBHMgIQDs/0OMj+vzVuBNhqmBsaUDAJBgUr 193 | # DgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUx 194 | # DxcNMTUwNTA1MDU1ODQ0WjAjBgkqhkiG9w0BCQQxFgQU1pnbVEEVtu+xZy9jxHyN 195 | # Y2jx70wwDQYJKoZIhvcNAQEBBQAEggEAiyrkIBhFyYk4lLyrNLC+NuvZcpcBKZya 196 | # M0opkU03Y+kYikJjHRvZfDuykRaPO3jVfRivM+K+uxRFmhXgHvuhM79ZwYs8uCYd 197 | # zbge7rUzO82+xjzmLSAdDEX7xtL6yIyfWNdudnXLA0JSBJYXrEZPkeq6brbwqj4K 198 | # Z1xhHCYgdnxfq7rKqCMwkNNUSsiLn/08pvsvATH1BhFCfLW2BjK3/cDI95Kukusd 199 | # hOvk9Gi6E9Azw1hGC6vtjWleXLStwlyf9PocJTZbiiwaAvr7iFaAW/l9202vjcFH 200 | # 6bvpur4S7U3V8w2Jq17gBVSHMU6Mhkx7/143kjBz/GgcAfUgT5auQA== 201 | # SIG # End signature block 202 | -------------------------------------------------------------------------------- /ExtensionMethods.ps1xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | System.Collections.Generic.IEnumerable[System.Int32] 4 | 5 | 6 | Sum 7 | 10 | 11 | 12 | 13 | 14 | System.Int32[] 15 | 16 | 17 | Sum 18 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /JoinObject.psm1: -------------------------------------------------------------------------------- 1 | function AddItemProperties($item, $properties, $output) 2 | { 3 | if($item -ne $null) 4 | { 5 | foreach($property in $properties) 6 | { 7 | # Support hashtables like Select-Object 8 | $propertyHash =$property -as [hashtable] 9 | if($propertyHash -ne $null) 10 | { 11 | $hashName=$propertyHash["name"] -as [string] 12 | if($hashName -eq $null) 13 | { 14 | throw "there should be a string Name" 15 | } 16 | 17 | $expression=$propertyHash["expression"] -as [scriptblock] 18 | if($expression -eq $null) 19 | { 20 | throw "there should be a ScriptBlock Expression" 21 | } 22 | 23 | $_=$item 24 | $expressionValue=& $expression 25 | 26 | $output | add-member -MemberType "NoteProperty" -Name $hashName -Value $expressionValue 27 | } 28 | else 29 | { 30 | # .psobject.Properties allows you to list the properties of any object, also known as "reflection" 31 | foreach($itemProperty in $item.psobject.Properties) 32 | { 33 | if ($itemProperty.Name -like $property) 34 | { 35 | $output | add-member -MemberType "NoteProperty" -Name $itemProperty.Name -Value $itemProperty.Value 36 | } 37 | } 38 | } 39 | } 40 | } 41 | } 42 | 43 | 44 | function WriteJoinObjectOutput($leftItem, $rightItem, $leftProperties, $rightProperties, $Type) 45 | { 46 | $output = new-object psobject 47 | 48 | if($Type -eq "AllInRight") 49 | { 50 | # This mix of rightItem with LeftProperties and vice versa is due to 51 | # the switch of Left and Right arguments for AllInRight 52 | AddItemProperties $rightItem $leftProperties $output 53 | AddItemProperties $leftItem $rightProperties $output 54 | } 55 | else 56 | { 57 | AddItemProperties $leftItem $leftProperties $output 58 | AddItemProperties $rightItem $rightProperties $output 59 | } 60 | $output 61 | } 62 | 63 | <# 64 | .Synopsis 65 | Joins two lists of objects 66 | .DESCRIPTION 67 | Joins two lists of objects 68 | .EXAMPLE 69 | Join-Object $a $b "Id" ("Name","Salary") 70 | #> 71 | function Join-Object 72 | { 73 | [CmdletBinding()] 74 | [OutputType([int])] 75 | param( 76 | # List to join with $Right 77 | [Parameter(Mandatory=$true, 78 | Position=0)] 79 | [object[]] 80 | $Left, 81 | 82 | # List to join with $Left 83 | [Parameter(Mandatory=$true, 84 | Position=1)] 85 | [object[]] 86 | $Right, 87 | 88 | # Condition in which an item in the left matches an item in the right 89 | # typically something like: {$args[0].Id -eq $args[1].Id} 90 | [Parameter(Mandatory=$true, 91 | Position=2)] 92 | [scriptblock] 93 | $Where, 94 | 95 | # Properties from $Left we want in the output. 96 | # Each property can: 97 | # - Be a plain property name like "Name" 98 | # - Contain wildcards like "*" 99 | # - Be a hashtable like @{Name="Product Name";Expression={$_.Name}}. Name is the output property name 100 | # and Expression is the property value. The same syntax is available in select-object and it is 101 | # important for join-object because joined lists could have a property with the same name 102 | [Parameter(Mandatory=$true, 103 | Position=3)] 104 | [object[]] 105 | $LeftProperties, 106 | 107 | # Properties from $Right we want in the output. 108 | # Like LeftProperties, each can be a plain name, wildcard or hashtable. See the LeftProperties comments. 109 | [Parameter(Mandatory=$true, 110 | Position=4)] 111 | [object[]] 112 | $RightProperties, 113 | 114 | # Type of join. 115 | # AllInLeft will have all elements from Left at least once in the output, and might appear more than once 116 | # if the where clause is true for more than one element in right, Left elements with matches in Right are 117 | # preceded by elements with no matches. This is equivalent to an outer left join (or simply left join) 118 | # SQL statement. 119 | # AllInRight is similar to AllInLeft. 120 | # OnlyIfInBoth will cause all elements from Left to be placed in the output, only if there is at least one 121 | # match in Right. This is equivalent to a SQL inner join (or simply join) statement. 122 | # AllInBoth will have all entries in right and left in the output. Specifically, it will have all entries 123 | # in right with at least one match in left, followed by all entries in Right with no matches in left, 124 | # followed by all entries in Left with no matches in Right.This is equivallent to a SQL full join. 125 | [Parameter(Mandatory=$false, 126 | Position=5)] 127 | [ValidateSet("AllInLeft","OnlyIfInBoth","AllInBoth", "AllInRight")] 128 | [string] 129 | $Type="OnlyIfInBoth" 130 | ) 131 | 132 | Begin 133 | { 134 | # a list of the matches in right for each object in left 135 | $leftMatchesInRight = new-object System.Collections.ArrayList 136 | 137 | # the count for all matches 138 | $rightMatchesCount = New-Object "object[]" $Right.Count 139 | 140 | for($i=0;$i -lt $Right.Count;$i++) 141 | { 142 | $rightMatchesCount[$i]=0 143 | } 144 | } 145 | 146 | Process 147 | { 148 | if($Type -eq "AllInRight") 149 | { 150 | # for AllInRight we just switch Left and Right 151 | $aux = $Left 152 | $Left = $Right 153 | $Right = $aux 154 | } 155 | 156 | # go over items in $Left and produce the list of matches 157 | foreach($leftItem in $Left) 158 | { 159 | $leftItemMatchesInRight = new-object System.Collections.ArrayList 160 | $null = $leftMatchesInRight.Add($leftItemMatchesInRight) 161 | 162 | for($i=0; $i -lt $right.Count;$i++) 163 | { 164 | $rightItem=$right[$i] 165 | 166 | if($Type -eq "AllInRight") 167 | { 168 | # For AllInRight, we want $args[0] to refer to the left and $args[1] to refer to right, 169 | # but since we switched left and right, we have to switch the where arguments 170 | $whereLeft = $rightItem 171 | $whereRight = $leftItem 172 | } 173 | else 174 | { 175 | $whereLeft = $leftItem 176 | $whereRight = $rightItem 177 | } 178 | 179 | if(Invoke-Command -ScriptBlock $where -ArgumentList $whereLeft,$whereRight) 180 | { 181 | $null = $leftItemMatchesInRight.Add($rightItem) 182 | $rightMatchesCount[$i]++ 183 | } 184 | 185 | } 186 | } 187 | 188 | # go over the list of matches and produce output 189 | for($i=0; $i -lt $left.Count;$i++) 190 | { 191 | $leftItemMatchesInRight=$leftMatchesInRight[$i] 192 | $leftItem=$left[$i] 193 | 194 | if($leftItemMatchesInRight.Count -eq 0) 195 | { 196 | if($Type -ne "OnlyIfInBoth") 197 | { 198 | WriteJoinObjectOutput $leftItem $null $LeftProperties $RightProperties $Type 199 | } 200 | 201 | continue 202 | } 203 | 204 | foreach($leftItemMatchInRight in $leftItemMatchesInRight) 205 | { 206 | WriteJoinObjectOutput $leftItem $leftItemMatchInRight $LeftProperties $RightProperties $Type 207 | } 208 | } 209 | } 210 | 211 | End 212 | { 213 | #produce final output for members of right with no matches for the AllInBoth option 214 | if($Type -eq "AllInBoth") 215 | { 216 | for($i=0; $i -lt $right.Count;$i++) 217 | { 218 | $rightMatchCount=$rightMatchesCount[$i] 219 | if($rightMatchCount -eq 0) 220 | { 221 | $rightItem=$Right[$i] 222 | WriteJoinObjectOutput $null $rightItem $LeftProperties $RightProperties $Type 223 | } 224 | } 225 | } 226 | } 227 | } 228 | # SIG # Begin signature block 229 | # MIIXxAYJKoZIhvcNAQcCoIIXtTCCF7ECAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB 230 | # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR 231 | # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU6YksIPJX1qwUwu85oNakEcWI 232 | # C2qgghL3MIID7jCCA1egAwIBAgIQfpPr+3zGTlnqS5p31Ab8OzANBgkqhkiG9w0B 233 | # AQUFADCBizELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIG 234 | # A1UEBxMLRHVyYmFudmlsbGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhh 235 | # d3RlIENlcnRpZmljYXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcg 236 | # Q0EwHhcNMTIxMjIxMDAwMDAwWhcNMjAxMjMwMjM1OTU5WjBeMQswCQYDVQQGEwJV 237 | # UzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xMDAuBgNVBAMTJ1N5bWFu 238 | # dGVjIFRpbWUgU3RhbXBpbmcgU2VydmljZXMgQ0EgLSBHMjCCASIwDQYJKoZIhvcN 239 | # AQEBBQADggEPADCCAQoCggEBALGss0lUS5ccEgrYJXmRIlcqb9y4JsRDc2vCvy5Q 240 | # WvsUwnaOQwElQ7Sh4kX06Ld7w3TMIte0lAAC903tv7S3RCRrzV9FO9FEzkMScxeC 241 | # i2m0K8uZHqxyGyZNcR+xMd37UWECU6aq9UksBXhFpS+JzueZ5/6M4lc/PcaS3Er4 242 | # ezPkeQr78HWIQZz/xQNRmarXbJ+TaYdlKYOFwmAUxMjJOxTawIHwHw103pIiq8r3 243 | # +3R8J+b3Sht/p8OeLa6K6qbmqicWfWH3mHERvOJQoUvlXfrlDqcsn6plINPYlujI 244 | # fKVOSET/GeJEB5IL12iEgF1qeGRFzWBGflTBE3zFefHJwXECAwEAAaOB+jCB9zAd 245 | # BgNVHQ4EFgQUX5r1blzMzHSa1N197z/b7EyALt0wMgYIKwYBBQUHAQEEJjAkMCIG 246 | # CCsGAQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMBIGA1UdEwEB/wQIMAYB 247 | # Af8CAQAwPwYDVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NybC50aGF3dGUuY29tL1Ro 248 | # YXd0ZVRpbWVzdGFtcGluZ0NBLmNybDATBgNVHSUEDDAKBggrBgEFBQcDCDAOBgNV 249 | # HQ8BAf8EBAMCAQYwKAYDVR0RBCEwH6QdMBsxGTAXBgNVBAMTEFRpbWVTdGFtcC0y 250 | # MDQ4LTEwDQYJKoZIhvcNAQEFBQADgYEAAwmbj3nvf1kwqu9otfrjCR27T4IGXTdf 251 | # plKfFo3qHJIJRG71betYfDDo+WmNI3MLEm9Hqa45EfgqsZuwGsOO61mWAK3ODE2y 252 | # 0DGmCFwqevzieh1XTKhlGOl5QGIllm7HxzdqgyEIjkHq3dlXPx13SYcqFgZepjhq 253 | # IhKjURmDfrYwggSjMIIDi6ADAgECAhAOz/Q4yP6/NW4E2GqYGxpQMA0GCSqGSIb3 254 | # DQEBBQUAMF4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3Jh 255 | # dGlvbjEwMC4GA1UEAxMnU3ltYW50ZWMgVGltZSBTdGFtcGluZyBTZXJ2aWNlcyBD 256 | # QSAtIEcyMB4XDTEyMTAxODAwMDAwMFoXDTIwMTIyOTIzNTk1OVowYjELMAkGA1UE 257 | # BhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMTQwMgYDVQQDEytT 258 | # eW1hbnRlYyBUaW1lIFN0YW1waW5nIFNlcnZpY2VzIFNpZ25lciAtIEc0MIIBIjAN 259 | # BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAomMLOUS4uyOnREm7Dv+h8GEKU5Ow 260 | # mNutLA9KxW7/hjxTVQ8VzgQ/K/2plpbZvmF5C1vJTIZ25eBDSyKV7sIrQ8Gf2Gi0 261 | # jkBP7oU4uRHFI/JkWPAVMm9OV6GuiKQC1yoezUvh3WPVF4kyW7BemVqonShQDhfu 262 | # ltthO0VRHc8SVguSR/yrrvZmPUescHLnkudfzRC5xINklBm9JYDh6NIipdC6Anqh 263 | # d5NbZcPuF3S8QYYq3AhMjJKMkS2ed0QfaNaodHfbDlsyi1aLM73ZY8hJnTrFxeoz 264 | # C9Lxoxv0i77Zs1eLO94Ep3oisiSuLsdwxb5OgyYI+wu9qU+ZCOEQKHKqzQIDAQAB 265 | # o4IBVzCCAVMwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAO 266 | # BgNVHQ8BAf8EBAMCB4AwcwYIKwYBBQUHAQEEZzBlMCoGCCsGAQUFBzABhh5odHRw 267 | # Oi8vdHMtb2NzcC53cy5zeW1hbnRlYy5jb20wNwYIKwYBBQUHMAKGK2h0dHA6Ly90 268 | # cy1haWEud3Muc3ltYW50ZWMuY29tL3Rzcy1jYS1nMi5jZXIwPAYDVR0fBDUwMzAx 269 | # oC+gLYYraHR0cDovL3RzLWNybC53cy5zeW1hbnRlYy5jb20vdHNzLWNhLWcyLmNy 270 | # bDAoBgNVHREEITAfpB0wGzEZMBcGA1UEAxMQVGltZVN0YW1wLTIwNDgtMjAdBgNV 271 | # HQ4EFgQURsZpow5KFB7VTNpSYxc/Xja8DeYwHwYDVR0jBBgwFoAUX5r1blzMzHSa 272 | # 1N197z/b7EyALt0wDQYJKoZIhvcNAQEFBQADggEBAHg7tJEqAEzwj2IwN3ijhCcH 273 | # bxiy3iXcoNSUA6qGTiWfmkADHN3O43nLIWgG2rYytG2/9CwmYzPkSWRtDebDZw73 274 | # BaQ1bHyJFsbpst+y6d0gxnEPzZV03LZc3r03H0N45ni1zSgEIKOq8UvEiCmRDoDR 275 | # EfzdXHZuT14ORUZBbg2w6jiasTraCXEQ/Bx5tIB7rGn0/Zy2DBYr8X9bCT2bW+IW 276 | # yhOBbQAuOA2oKY8s4bL0WqkBrxWcLC9JG9siu8P+eJRRw4axgohd8D20UaF5Mysu 277 | # e7ncIAkTcetqGVvP6KUwVyyJST+5z3/Jvz4iaGNTmr1pdKzFHTx/kuDDvBzYBHUw 278 | # ggUmMIIEDqADAgECAhACXbrxBhFj1/jVxh2rtd9BMA0GCSqGSIb3DQEBCwUAMHIx 279 | # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 280 | # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ 281 | # RCBDb2RlIFNpZ25pbmcgQ0EwHhcNMTUwNTA0MDAwMDAwWhcNMTYwNTExMTIwMDAw 282 | # WjBtMQswCQYDVQQGEwJVUzERMA8GA1UECBMITmV3IFlvcmsxFzAVBgNVBAcTDldl 283 | # c3QgSGVucmlldHRhMRgwFgYDVQQKEw9Kb2VsIEguIEJlbm5ldHQxGDAWBgNVBAMT 284 | # D0pvZWwgSC4gQmVubmV0dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB 285 | # AJfRKhfiDjMovUELYgagznWf+HFcDENk118Y/K6UkQDwKmVyVOvDyaVefjSmZZcV 286 | # NZqqYpm9d/Iajf2dauyC3pg3oay8KfXAADLHgbmbvYDc5zGuUNsTzMUOKlp9h13c 287 | # qsg898JwpRpI659xCQgJjZ6V83QJh+wnHvjA9ojjA4xkbwhGp4Eit6B/uGthEA11 288 | # IHcFcXeNI3fIkbwWiAw7ZoFtSLm688NFhxwm+JH3Xwj0HxuezsmU0Yc/po31CoST 289 | # nGPVN8wppHYZ0GfPwuNK4TwaI0FEXxwdwB+mEduxa5e4zB8DyUZByFW338XkGfc1 290 | # qcJJ+WTyNKFN7saevhwp02cCAwEAAaOCAbswggG3MB8GA1UdIwQYMBaAFFrEuXsq 291 | # CqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBQV0aryV1RTeVOG+wlr2Z2bOVFAbTAO 292 | # BgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwdwYDVR0fBHAwbjA1 293 | # oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJlZC1jcy1n 294 | # MS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEyLWFzc3Vy 295 | # ZWQtY3MtZzEuY3JsMEIGA1UdIAQ7MDkwNwYJYIZIAYb9bAMBMCowKAYIKwYBBQUH 296 | # AgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgYQGCCsGAQUFBwEBBHgw 297 | # djAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tME4GCCsGAQUF 298 | # BzAChkJodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEyQXNz 299 | # dXJlZElEQ29kZVNpZ25pbmdDQS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0B 300 | # AQsFAAOCAQEAIi5p+6eRu6bMOSwJt9HSBkGbaPZlqKkMd4e6AyKIqCRabyjLISwd 301 | # i32p8AT7r2oOubFy+R1LmbBMaPXORLLO9N88qxmJfwFSd+ZzfALevANdbGNp9+6A 302 | # khe3PiR0+eL8ZM5gPJv26OvpYaRebJTfU++T1sS5dYaPAztMNsDzY3krc92O27AS 303 | # WjTjWeILSryqRHXyj8KQbYyWpnG2gWRibjXi5ofL+BHyJQRET5pZbERvl2l9Bo4Z 304 | # st8CM9EQDrdG2vhELNiA6jwenxNPOa6tPkgf8cH8qpGRBVr9yuTMSHS1p9Rc+ybx 305 | # FSKiZkOw8iCR6ZQIeKkSVdwFf8V+HHPrETCCBTAwggQYoAMCAQICEAQJGBtf1btm 306 | # dVNDtW+VUAgwDQYJKoZIhvcNAQELBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoT 307 | # DERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UE 308 | # AxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoX 309 | # DTI4MTAyMjEyMDAwMFowcjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0 310 | # IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNl 311 | # cnQgU0hBMiBBc3N1cmVkIElEIENvZGUgU2lnbmluZyBDQTCCASIwDQYJKoZIhvcN 312 | # AQEBBQADggEPADCCAQoCggEBAPjTsxx/DhGvZ3cH0wsxSRnP0PtFmbE620T1f+Wo 313 | # ndsy13Hqdp0FLreP+pJDwKX5idQ3Gde2qvCchqXYJawOeSg6funRZ9PG+yknx9N7 314 | # I5TkkSOWkHeC+aGEI2YSVDNQdLEoJrskacLCUvIUZ4qJRdQtoaPpiCwgla4cSocI 315 | # 3wz14k1gGL6qxLKucDFmM3E+rHCiq85/6XzLkqHlOzEcz+ryCuRXu0q16XTmK/5s 316 | # y350OTYNkO/ktU6kqepqCquE86xnTrXE94zRICUj6whkPlKWwfIPEvTFjg/Bougs 317 | # UfdzvL2FsWKDc0GCB+Q4i2pzINAPZHM8np+mM6n9Gd8lk9ECAwEAAaOCAc0wggHJ 318 | # MBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoG 319 | # CCsGAQUFBwMDMHkGCCsGAQUFBwEBBG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29j 320 | # c3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdp 321 | # Y2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3J0MIGBBgNVHR8EejB4 322 | # MDqgOKA2hjRodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVk 323 | # SURSb290Q0EuY3JsMDqgOKA2hjRodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGln 324 | # aUNlcnRBc3N1cmVkSURSb290Q0EuY3JsME8GA1UdIARIMEYwOAYKYIZIAYb9bAAC 325 | # BDAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAoG 326 | # CGCGSAGG/WwDMB0GA1UdDgQWBBRaxLl7KgqjpepxA8Bg+S32ZXUOWDAfBgNVHSME 327 | # GDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkqhkiG9w0BAQsFAAOCAQEAPuwN 328 | # WiSz8yLRFcgsfCUpdqgdXRwtOhrE7zBh134LYP3DPQ/Er4v97yrfIFU3sOH20ZJ1 329 | # D1G0bqWOWuJeJIFOEKTuP3GOYw4TS63XX0R58zYUBor3nEZOXP+QsRsHDpEV+7qv 330 | # tVHCjSSuJMbHJyqhKSgaOnEoAjwukaPAJRHinBRHoXpoaK+bp1wgXNlxsQyPu6j4 331 | # xRJon89Ay0BEpRPw5mQMJQhCMrI2iiQC/i9yfhzXSUWW6Fkd6fp0ZGuy62ZD2rOw 332 | # jNXpDd32ASDOmTFjPQgaGLOBm0/GkxAG/AeB+ova+YJJ92JuoVP6EpQYhS6Skepo 333 | # bEQysmah5xikmmRR7zGCBDcwggQzAgEBMIGGMHIxCzAJBgNVBAYTAlVTMRUwEwYD 334 | # VQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAv 335 | # BgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EC 336 | # EAJduvEGEWPX+NXGHau130EwCQYFKw4DAhoFAKB4MBgGCisGAQQBgjcCAQwxCjAI 337 | # oAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIB 338 | # CzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFBdUF6f3sOjIHr0YwaSD 339 | # zhLoV7gEMA0GCSqGSIb3DQEBAQUABIIBAASC1b7uOzXLpB04O1Sv7E9TPiA1jZ4n 340 | # odpZXDQ4fzkySgNarW76VjAJ1CsMbcTxD5ViGHn56DhFTTd357AZsTNXjUn5xGSg 341 | # mND1pIxJkJRhzjaM6Lylpy86eaZcjmGZzADXfZib4kuXM/CbTEvwzelSzl5I+WnJ 342 | # hXC810c4EGZAptzg8+gFVR8Lh8EsFGEbhn9MPSUqbNh4wyUaQNjT5siT7Qca8MBD 343 | # GEIygu/KVXC+cgTk0lSlyxoX14mHlwF8x8Ojw4P4xJciePEQu0yl7a5XExPbpvo0 344 | # cPqt4UdhLiG95wqtnKPleuz3CMk/gLzUN0CzXccHJXT6BcBh742ou7GhggILMIIC 345 | # BwYJKoZIhvcNAQkGMYIB+DCCAfQCAQEwcjBeMQswCQYDVQQGEwJVUzEdMBsGA1UE 346 | # ChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xMDAuBgNVBAMTJ1N5bWFudGVjIFRpbWUg 347 | # U3RhbXBpbmcgU2VydmljZXMgQ0EgLSBHMgIQDs/0OMj+vzVuBNhqmBsaUDAJBgUr 348 | # DgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUx 349 | # DxcNMTUwNTA1MDU1ODQ0WjAjBgkqhkiG9w0BCQQxFgQUiGBOWVGGwK0jQVUdOW5X 350 | # QqKMcigwDQYJKoZIhvcNAQEBBQAEggEAm3rWRDpPdzN6dQfmVL8UIirDJScl6pWP 351 | # J8CWKktCskSCeeg/qJJw2DY5c6CulNggKYP4aNGbYOpMsNKDoefqPHTOB8fG66UY 352 | # 1y8aCaTgTcnTh1ZWXYldUXoDcaekOgMQDqbPxOcPQ+ZtRWO49pZPxVhxLzDLmS4i 353 | # 1nUdhCpw1NVOo2uQvmtmFU3oZdcAD1RKG6OsBRj5lk3RPWFhan/oPQk7v4PwJe5q 354 | # p45Ar5mhWUEQOfRGM2bU6/T25aR5XoaFFCo6BS/Bzsc7LyejpMLLng64zDsTxBHQ 355 | # xppEbBL0sTiTxIZodzw7r06kYb33+o6y5FsUl2915+BbTxdtH+xYCQ== 356 | # SIG # End signature block 357 | -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | # Reflection 2 | 3 | ## A .Net Framework Interaction Module for PowerShell 4 | 5 | This module has functions for inspecting .Net Assemblies and Classes, as well as for adding and removing accelerators, working with CliXml and the AST. 6 | 7 | -------------------------------------------------------------------------------- /Reflection.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | 3 | # Script module or binary module file associated with this manifest. 4 | RootModule = '.\Reflection.psm1' 5 | 6 | # Version number of this module. 7 | ModuleVersion = '4.8' 8 | 9 | # ID used to uniquely identify this module 10 | GUID = '64b5f609-970f-4e65-b02f-93ccf3e60cbb' 11 | 12 | # Author of this module 13 | Author = 'Joel Bennett' 14 | 15 | # Company or vendor of this module 16 | CompanyName = 'http://HuddledMasses.org' 17 | 18 | # Copyright statement for this module 19 | Copyright = 'Copyright (c) 2008-2014 by Joel Bennett, released under the Ms-PL' 20 | 21 | # Description of the functionality provided by this module 22 | Description = 'A .Net Framework Interaction Module for PowerShell' 23 | 24 | # Minimum version of the Windows PowerShell engine required by this module 25 | PowerShellVersion = '2.0' 26 | 27 | # Name of the Windows PowerShell host required by this module 28 | # PowerShellHostName = '' 29 | 30 | # Minimum version of the Windows PowerShell host required by this module 31 | # PowerShellHostVersion = '' 32 | 33 | # Minimum version of Microsoft .NET Framework required by this module 34 | # DotNetFrameworkVersion = '' 35 | 36 | # Minimum version of the common language runtime (CLR) required by this module 37 | CLRVersion = '2.0' 38 | 39 | # Processor architecture (None, X86, Amd64) required by this module 40 | ProcessorArchitecture = 'None' 41 | 42 | # Modules that must be imported into the global environment prior to importing this module 43 | RequiredModules = @(@{ModuleName = 'Autoload'; GUID = '4001ca5f-8b94-41a1-9229-4db6afa6c6ea'; ModuleVersion = '4.0'; }) 44 | 45 | # Assemblies that must be loaded prior to importing this module 46 | # RequiredAssemblies = @() 47 | 48 | # Script files (.ps1) that are run in the caller's environment prior to importing this module. 49 | # ScriptsToProcess = @() 50 | 51 | # Type files (.ps1xml) to be loaded when importing this module 52 | # TypesToProcess = @() 53 | 54 | # Format files (.ps1xml) to be loaded when importing this module 55 | # FormatsToProcess = @() 56 | 57 | # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess 58 | # NestedModules = @() 59 | 60 | # Functions to export from this module 61 | FunctionsToExport = 'Add-Accelerator', 'Add-Assembly', 'Add-ConstructorFunction', 62 | 'Add-Struct', 'Add-Enum', 'Get-Accelerator', 'Get-Argument', 63 | 'Get-Assembly', 'Get-Constructor', 'Get-ExtensionMethod', 64 | 'Get-MemberSignature', 'Get-Method', 'Get-ReflectionModule', 'Get-Type', 65 | 'Import-ConstructorFunctions', 'Import-Namespace', 'Invoke-Generic', 66 | 'Invoke-Member', 'New-ModuleManifestFromSnapin', 'Read-Choice', 67 | 'Remove-Accelerator', 'Set-DependencyProperty', 68 | 'Set-ObjectProperties', 'Set-Property', 'Test-AssignableToGeneric', 69 | 'Update-PSBoundParameters', 'Test-RestrictedLanguage', 70 | 'Get-ParseResults', 'Find-Token' 71 | 72 | # Cmdlets to export from this module 73 | CmdletsToExport = '*' 74 | 75 | # Variables to export from this module 76 | VariablesToExport = '*' 77 | 78 | # Aliases to export from this module 79 | AliasesToExport = '*' 80 | 81 | # DSC resources to export from this module 82 | # DscResourcesToExport = @() 83 | 84 | # List of all modules packaged with this module 85 | # ModuleList = @() 86 | 87 | # List of all files packaged with this module 88 | FileList = 'Reflection.psm1', 'Reflection.psd1', 'license.txt' 89 | 90 | # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. 91 | PrivateData = @{ 92 | 93 | PSData = @{ 94 | 95 | # Tags applied to this module. These help with module discovery in online galleries. 96 | Tags = @("Reflection", "CodeGen", "Accelerator", "CliXml") 97 | 98 | # A URL to the license for this module. 99 | LicenseUri = 'https://github.com/Jaykul/Reflection/blob/master/license.txt' 100 | 101 | # A URL to the main website for this project. 102 | ProjectUri = 'https://github.com/Jaykul/Reflection' 103 | # ReleaseNotes of this module 104 | ReleaseNotes = 'https://github.com/Jaykul/Reflection/blob/master/ReleaseNotes.md' 105 | 106 | } # End of PSData hashtable 107 | 108 | } # End of PrivateData hashtable 109 | 110 | # HelpInfo URI of this module 111 | # HelpInfoURI = '' 112 | 113 | # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. 114 | # DefaultCommandPrefix = '' 115 | 116 | } 117 | -------------------------------------------------------------------------------- /Reflection.psm1: -------------------------------------------------------------------------------- 1 | #requires -version 2.0 2 | # ALSO REQUIRES Autoload for some functionality (Latest version: http://poshcode.org/3173) 3 | # You should create a Reflection.psd1 with the contents: 4 | # @{ ModuleToProcess="Reflection.psm1"; RequiredModules = @("Autoload"); GUID="64b5f609-970f-4e65-b02f-93ccf3e60cbb"; ModuleVersion="4.5.0.0" } 5 | # 6 | Add-Type -TypeDefinition @" 7 | using System; 8 | using System.ComponentModel; 9 | using System.Management.Automation; 10 | using System.Collections.ObjectModel; 11 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] 12 | public class TransformAttribute : ArgumentTransformationAttribute { 13 | private ScriptBlock _scriptblock; 14 | private string _noOutputMessage = "Transform Script had no output."; 15 | public override string ToString() { 16 | return string.Format("[Transform(Script='{{{0}}}')]", Script); 17 | } 18 | public override Object Transform( EngineIntrinsics engine, Object inputData) { 19 | try { 20 | Collection output = 21 | engine.InvokeCommand.InvokeScript( engine.SessionState, Script, inputData ); 22 | if(output.Count > 1) { 23 | Object[] transformed = new Object[output.Count]; 24 | for(int i =0; i < output.Count;i++) { 25 | transformed[i] = output[i].BaseObject; 26 | } 27 | return transformed; 28 | } else if(output.Count == 1) { 29 | return output[0].BaseObject; 30 | } else { 31 | throw new ArgumentTransformationMetadataException(NoOutputMessage); 32 | } 33 | } catch (ArgumentTransformationMetadataException) { 34 | throw; 35 | } catch (Exception e) { 36 | throw new ArgumentTransformationMetadataException(string.Format("Transform Script threw an exception ('{0}'). See `$Error[0].Exception.InnerException.InnerException for more details.",e.Message), e); 37 | } 38 | } 39 | public TransformAttribute() { 40 | this.Script = ScriptBlock.Create("{`$args}"); 41 | } 42 | public TransformAttribute( ScriptBlock Script ) { 43 | this.Script = Script; 44 | } 45 | public ScriptBlock Script { 46 | get { return _scriptblock; } 47 | set { _scriptblock = value; } 48 | } 49 | public string NoOutputMessage { 50 | get { return _noOutputMessage; } 51 | set { _noOutputMessage = value; } 52 | } 53 | } 54 | "@ 55 | 56 | $ReflectionRoot = Get-Variable PSScriptRoot* -ErrorAction SilentlyContinue | 57 | Where-Object { $_.Name -eq "PSScriptRoot" } | 58 | ForEach-Object { $_.Value } 59 | if(!$ReflectionRoot) { 60 | $ReflectionRoot = Split-Path $MyInvocation.MyCommand.Path -Parent 61 | } 62 | 63 | Import-Module "${ReflectionRoot}\Accelerator.psm1" 64 | Import-Module "${ReflectionRoot}\AST.psm1" 65 | Import-Module "${ReflectionRoot}\CliXml.psm1" 66 | 67 | 68 | function Get-Type { 69 | <# 70 | .Synopsis 71 | Gets the types that are currenty loaded in .NET, or gets information about a specific type 72 | .Description 73 | Gets information about one or more loaded types, or gets the possible values for an enumerated type or value. 74 | .Example 75 | Get-Type 76 | 77 | Gets all loaded types (takes a VERY long time to print out) 78 | .Example 79 | Get-Type -Assembly ([PSObject].Assembly) 80 | 81 | Gets types from System.Management.Automation 82 | .Example 83 | [Threading.Thread]::CurrentThread.ApartmentState | Get-Type 84 | 85 | Gets all of the possible values for the ApartmentState property 86 | .Example 87 | [Threading.ApartmentState] | Get-Type 88 | 89 | Gets all of the possible values for an apartmentstate 90 | #> 91 | [CmdletBinding(DefaultParameterSetName="Assembly")] 92 | param( 93 | # The Assemblies to search for types. 94 | # Can be an actual Assembly object or a regex to pass to Get-Assembly. 95 | [Parameter(ValueFromPipeline=$true)] 96 | [PsObject[]]$Assembly, 97 | 98 | # The type name(s) to search for (wildcard patterns allowed). 99 | [Parameter(Mandatory=$false,Position=0)] 100 | [SupportsWildCards()] 101 | [String[]]$TypeName, 102 | 103 | # A namespace to restrict where we selsect types from (wildcard patterns allowed). 104 | [Parameter(Mandatory=$false)] 105 | [SupportsWildCards()] 106 | [String[]]$Namespace, 107 | 108 | # A Base type they should derive from (wildcard patterns allowed). 109 | [Parameter(Mandatory=$false)] 110 | [SupportsWildCards()] 111 | [String[]]$BaseType, 112 | 113 | # An interface they should implement (wildcard patterns allowed). 114 | [Parameter(Mandatory=$false)] 115 | [SupportsWildCards()] 116 | [String[]]$Interface, 117 | 118 | # An Custom Attribute which should decorate the class 119 | [Parameter(Mandatory=$false)] 120 | [SupportsWildCards()] 121 | [String[]]$Attribute, 122 | 123 | 124 | # The enumerated value to get all of the possible values of 125 | [Parameter(ParameterSetName="Enum")] 126 | [PSObject]$Enum, 127 | 128 | # Causes Private types to be included 129 | [Parameter()][Alias("Private","ShowPrivate")] 130 | [Switch]$Force 131 | ) 132 | 133 | process { 134 | if($psCmdlet.ParameterSetName -eq 'Enum') { 135 | if($Enum -is [Enum]) { 136 | [Enum]::GetValues($enum.GetType()) 137 | } elseif($Enum -is [Type] -and $Enum.IsEnum) { 138 | [Enum]::GetValues($enum) 139 | } else { 140 | throw "Specified Enum is neither an enum value nor an enumerable type" 141 | } 142 | } 143 | else { 144 | if($Assembly -as [Reflection.Assembly[]]) { 145 | ## This is what we expected, move along 146 | } elseif($Assembly -as [String[]]) { 147 | $Assembly = Get-Assembly $Assembly 148 | } elseif(!$Assembly) { 149 | $Assembly = [AppDomain]::CurrentDomain.GetAssemblies() 150 | } 151 | 152 | :asm foreach ($asm in $assembly) { 153 | Write-Verbose "Testing Types from Assembly: $($asm.Location)" 154 | if ($asm) { 155 | trap { 156 | if( $_.Exception.LoaderExceptions -and $_.Exception.LoaderExceptions[0] -is [System.IO.FileNotFoundException] ) { 157 | $PSCmdlet.WriteWarning( "Unable to load some types from $($asm.Location), required assemblies were not found. Use -Debug to see more detail") 158 | continue asm 159 | } 160 | Write-Error "Unable to load some types from $($asm.Location). Try with -Debug to see more detail" 161 | Write-Debug $( $_.Exception.LoaderExceptions | Out-String ) 162 | continue asm 163 | } 164 | $asm.GetTypes() | Where { 165 | ( $Force -or $_.IsPublic ) -AND 166 | ( !$Namespace -or $( foreach($n in $Namespace) { $_.Namespace -like $n } ) ) -AND 167 | ( !$TypeName -or $( foreach($n in $TypeName) { $_.Name -like $n -or $_.FullName -like $n } ) -contains $True ) -AND 168 | ( !$Attribute -or $( foreach($n in $Attribute) { $_.CustomAttributes | ForEach { $_.AttributeType.Name -like $n -or $_.AttributeType.FullName -like $n } } ) -contains $True ) -AND 169 | ( !$BaseType -or $( foreach($n in $BaseType) { $_.BaseType -like $n } ) -contains $True ) -AND 170 | ( !$Interface -or @( foreach($n in $Interface) { $_.GetInterfaces() -like $n } ).Count -gt 0 ) 171 | } 172 | } 173 | } 174 | } 175 | } 176 | } 177 | 178 | function Add-Assembly { 179 | #.Synopsis 180 | # Load assemblies 181 | #.Description 182 | # Load assemblies from a folder 183 | #.Parameter Path 184 | # Specifies a path to one or more locations. Wildcards are permitted. The default location is the current directory (.). 185 | #.Parameter Passthru 186 | # Returns System.Runtime objects that represent the types that were added. By default, this cmdlet does not generate any output. 187 | # Aliased to -Types 188 | #.Parameter Recurse 189 | # Gets the items in the specified locations and in all child items of the locations. 190 | # 191 | # Recurse works only when the path points to a container that has child items, such as C:\Windows or C:\Windows\*, and not when it points to items that do not have child items, such as C:\Windows\*.dll 192 | [CmdletBinding()] 193 | param( 194 | [Parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true, Position=0)] 195 | [Alias("PSPath")] 196 | [string[]]$Path = ".", 197 | 198 | [Alias("Types")] 199 | [Switch]$Passthru, 200 | 201 | [Switch]$Recurse 202 | ) 203 | process { 204 | foreach($file in Get-ChildItem $Path -Filter *.dll -Recurse:$Recurse) { 205 | Add-Type -Path $file.FullName -Passthru:$Passthru | Where { $_.IsPublic } 206 | } 207 | } 208 | } 209 | 210 | function Get-Assembly { 211 | <# 212 | .Synopsis 213 | Get a list of assemblies available in the runspace 214 | .Description 215 | Returns AssemblyInfo for all the assemblies available in the current AppDomain, optionally filtered by partial name match 216 | .Parameter Name 217 | A regex to filter the returned assemblies. This is matched against the .FullName or Location (path) of the assembly. 218 | #> 219 | [CmdletBinding()] 220 | param( 221 | [Parameter(ValueFromPipeline=$true, Position=0)] 222 | [string[]]$Name = '' 223 | ) 224 | process { 225 | [appdomain]::CurrentDomain.GetAssemblies() | Where { 226 | $Assembly = $_ 227 | if($Name){ 228 | $( 229 | foreach($n in $Name){ 230 | if(Resolve-Path $n -ErrorAction 0) { 231 | $n = [Regex]::Escape( (Resolve-Path $n).Path ) 232 | } 233 | $Assembly.FullName -match $n -or $Assembly.Location -match $n -or ($Assembly.Location -and (Split-Path $Assembly.Location) -match $n) 234 | } 235 | ) -contains $True 236 | } else { $true } 237 | } 238 | } 239 | } 240 | 241 | function Update-PSBoundParameters { 242 | #.Synopsis 243 | # Ensure a parameter value is set 244 | #.Description 245 | # Update-PSBoundParameters takes the name of a parameter, a default value, and optionally a min and max value, and ensures that PSBoundParameters has a value for it. 246 | #.Parameter Name 247 | # The name (key) of the parameter you want to set in PSBoundParameters 248 | #.Parameter Default 249 | # A Default value for the parameter, in case it's not already set 250 | #.Parameter Min 251 | # The Minimum allowed value for the parameter 252 | #.Parameter Max 253 | # The Maximum allowed value for the parameter 254 | #.Parameter PSBoundParameters 255 | # The PSBoundParameters you want to affect (this picks the local PSBoundParameters object, so you shouldn't have to set it) 256 | Param( 257 | [Parameter(Mandatory=$true, Position=0)] 258 | [String]$Name, 259 | 260 | [Parameter(Mandatory=$false, Position=1)] 261 | $Default, 262 | 263 | [Parameter()] 264 | $Min, 265 | 266 | [Parameter()] 267 | $Max, 268 | 269 | [Parameter(Mandatory=$true, Position=99)] 270 | $PSBoundParameters=$PSBoundParameters 271 | ) 272 | end { 273 | $outBuffer = $null 274 | ## If it's not set, and you passed a default, we set it to the default 275 | if($Default) { 276 | if (!$PSBoundParameters.TryGetValue($Name, [ref]$outBuffer)) 277 | { 278 | $PSBoundParameters[$Name] = $Default 279 | } 280 | } 281 | ## If you passed a $max, and it's set greater than $max, we set it to $max 282 | if($Max) { 283 | if ($PSBoundParameters.TryGetValue($Name, [ref]$outBuffer) -and $outBuffer -gt $Max) 284 | { 285 | $PSBoundParameters[$Name] = $Max 286 | } 287 | } 288 | ## If you passed a $min, and it's set less than $min, we set it to $min 289 | if($Min) { 290 | if ($PSBoundParameters.TryGetValue($Name, [ref]$outBuffer) -and $outBuffer -lt $Min) 291 | { 292 | $PSBoundParameters[$Name] = $Min 293 | } 294 | } 295 | $PSBoundParameters 296 | } 297 | } 298 | 299 | function Get-Constructor { 300 | <# 301 | .Synopsis 302 | Returns RuntimeConstructorInfo for the (public) constructor methods of the specified Type. 303 | .Description 304 | Get the RuntimeConstructorInfo for a type and add members "Syntax," "SimpleSyntax," and "Definition" to each one containing the syntax information that can use to call that constructor. 305 | .Parameter Type 306 | The type to get the constructor for 307 | .Parameter Force 308 | Force inclusion of Private and Static constructors which are hidden by default. 309 | .Parameter NoWarn 310 | Serves as the replacement for the broken -WarningAction. If specified, no warnings will be written for types without public constructors. 311 | .Example 312 | Get-Constructor System.IO.FileInfo 313 | 314 | Description 315 | ----------- 316 | Gets all the information about the single constructor for a FileInfo object. 317 | .Example 318 | Get-Type System.IO.*info mscorlib | Get-Constructor -NoWarn | Select Syntax 319 | 320 | Description 321 | ----------- 322 | Displays the constructor syntax for all of the *Info objects in the System.IO namespace. 323 | Using -NoWarn supresses the warning about System.IO.FileSystemInfo not having constructors. 324 | 325 | .Example 326 | $path = $pwd 327 | $driveName = $pwd.Drive 328 | $fileName = "$Profile" 329 | Get-Type System.IO.*info mscorlib | Get-Constructor -NoWarn | ForEach-Object { Invoke-Expression $_.Syntax } 330 | 331 | Description 332 | ----------- 333 | Finds and invokes the constructors for DirectoryInfo, DriveInfo, and FileInfo. 334 | Note that we pre-set the parameters for the constructors, otherwise they would fail with null arguments, so this example isn't really very practical. 335 | 336 | 337 | #> 338 | [CmdletBinding()] 339 | param( 340 | [Parameter(Mandatory=$true, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$true, Position=0)] 341 | [Alias("ParameterType")] 342 | [Type]$Type, 343 | [Switch]$Force, 344 | [Switch]$NoWarn 345 | ) 346 | process { 347 | $type.GetConstructors() | Where-Object { $Force -or $_.IsPublic -and -not $_.IsStatic } -OutVariable ctor 348 | if(!$ctor -and !$NoWarn) { Write-Warning "There are no public constructors for $($type.FullName)" } 349 | } 350 | } 351 | 352 | function Get-ExtensionMethod { 353 | <# 354 | .Synopsis 355 | Finds Extension Methods which target the specified type 356 | .Example 357 | Get-ExtensionMethod String 358 | 359 | Finds all extension methods which target strings 360 | #> 361 | [CmdletBinding()] 362 | param( 363 | # The type name to find Extension Methods for 364 | [Parameter(Mandatory=$false,Position=0)] 365 | [SupportsWildCards()] 366 | [String[]]$TargetTypeName, 367 | 368 | # A filter for the Extension Method name 369 | [Parameter(Mandatory=$false)] 370 | [SupportsWildCards()] 371 | [String[]]$Name = "*", 372 | 373 | # The type to search for Extension Methods (defaults to search all types) 374 | [Parameter(Mandatory=$false,Position=99)] 375 | [SupportsWildCards()] 376 | [String[]]$TypeName = "*" 377 | ) 378 | process { 379 | Get-Type -TypeName $TypeName -Attribute ExtensionAttribute | 380 | Get-Method -Name $Name -BindingFlags "Static,Public,NonPublic" -Attribute ExtensionAttribute | 381 | ForEach-Object { 382 | $Method = $_ 383 | $ParameterType = $_.GetParameters()[0].ParameterType 384 | 385 | ForEach($T in $TargetTypeName) { 386 | Write-Verbose "Is '$T' a '$ParameterType'?" 387 | if($ParameterType.Name -like $T -or $ParameterType.FullName -like $T) { 388 | Write-Verbose "The name '$T' matches '$ParameterType'" 389 | Add-Member -Input $Method -Type NoteProperty -Name ParamBlock -Value (Get-MemberSignature $Method -ParamBlock) -Force 390 | Write-Output $Method 391 | continue 392 | } 393 | 394 | if($ParameterType.IsGenericType) { 395 | $interface = $null 396 | if(Test-AssignableToGeneric $T $ParameterType -interface ([ref]$interface)) { 397 | # if([GenericHelper]::IsAssignableToGenericType( $T, $ParameterType )) { 398 | Write-Verbose "'$T' is a generic that's assignable to '$ParameterType'" 399 | Add-Member -Input $Method -Type NoteProperty -Name Extends -Value $interface.Value -Force 400 | Add-Member -Input $Method -Type NoteProperty -Name ParamBlock -Value (Get-MemberSignature $Method -GenericArguments $interface.GetGenericArguments() -ParamBlock) -Force 401 | Write-Output $Method 402 | continue 403 | } 404 | } else { 405 | if($ParameterType.IsAssignableFrom($T)) { 406 | Write-Verbose "'$ParameterType' is assignable from '$T'" 407 | Add-Member -Input $Method -Type NoteProperty -Name ParamBlock -Value (Get-MemberSignature $Method -ParamBlock) -Force 408 | Write-Output $Method 409 | continue 410 | } 411 | } 412 | } 413 | } 414 | } 415 | } 416 | 417 | function Test-AssignableToGeneric { 418 | <# 419 | .Synopsis 420 | Determine if a specific type can be cast to the given generic type 421 | #> 422 | param( 423 | # The concrete type you want to test generics against 424 | [Parameter(Position=0, Mandatory = $true)] 425 | [Type]$type, 426 | 427 | # A Generic Type to test 428 | [Parameter(ValueFromPipeline=$true, Position=1, Mandatory = $true)] 429 | [Type]$genericType, 430 | 431 | # Check the GenericTypeDefinition of the GenericType (in case it's typed) 432 | [Switch]$force, 433 | 434 | # If the type is assignable because of an interface, return that interface here 435 | [Parameter(Position=2)] 436 | [ref]$interface = [ref]$null 437 | ) 438 | 439 | process { 440 | $interfaces = $type.GetInterfaces() 441 | if($type.IsGenericType -and ($type.GetGenericTypeDefinition().equals($genericType))) { 442 | return $true 443 | } 444 | 445 | foreach($i in $interfaces) 446 | { 447 | if($i.IsGenericType -and $i.GetGenericTypeDefinition().Equals($genericType)) { 448 | $interface.Value = $i 449 | return $true 450 | } 451 | if($i.IsGenericType -and $i.GetGenericTypeDefinition().Equals($genericType.GetGenericTypeDefinition())) { 452 | $genericTypeArgs = @($genericType.GetGenericArguments())[0] 453 | if(($genericTypeArgs.IsGenericParameter -and 454 | $genericTypeArgs.BaseType.IsAssignableFrom( @($i.GetGenericArguments())[0] ) ) -or 455 | $genericTypeArgs.IsAssignableFrom( @($i.GetGenericArguments())[0] )) { 456 | 457 | $interface.Value = $i 458 | return $true 459 | } 460 | } 461 | } 462 | if($force -and $genericType -ne $genericType.GetGenericTypeDefinition()) { 463 | if(Test-AssignableToGeneric $type $genericType.GetGenericTypeDefinition()) { 464 | return $true 465 | } 466 | } 467 | 468 | $base = $type.BaseType 469 | if(!$base) { return $false } 470 | 471 | Test-AssignableToGeneric $base $genericType 472 | } 473 | } 474 | 475 | function Get-Method { 476 | <# 477 | .Synopsis 478 | Returns MethodInfo for the (public) methods of the specified Type. 479 | .Description 480 | Get the MethodInfo for a type and add members "Syntax," "SimpleSyntax," and "Definition" to each one containing the syntax information that can use to call that method. 481 | .Parameter Type 482 | .Parameter Name 483 | 484 | .Parameter Force 485 | #> 486 | [CmdletBinding(DefaultParameterSetName="Type")] 487 | param( 488 | # The type to get methods from 489 | [Parameter(ParameterSetName="Type", Mandatory=$true, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$true, Position=0)] 490 | [Type]$Type, 491 | # The name(s) of the method(s) you want to retrieve (Accepts Wildcard Patterns) 492 | [Parameter(Mandatory=$false, Position=1)] 493 | [SupportsWildCards()] 494 | [PSDefaultValue(Help='*')] 495 | [String[]]$Name ="*", 496 | # Force inclusion of Private methods and property accessors which are hidden by default. 497 | [Switch]$Force, 498 | # The Binding Flags filter the output. defaults to returning all methods, static or instance 499 | [PSDefaultValue(Help='Instance,Static,Public')] 500 | [System.Reflection.BindingFlags]$BindingFlags = $(if($Force){"Instance,Static,Public,NonPublic"} else {"Instance,Static,Public"}), 501 | 502 | # An Custom Attribute which should decorate the class 503 | [Parameter(Mandatory=$false)] 504 | [SupportsWildCards()] 505 | [String[]]$Attribute 506 | 507 | ) 508 | process { 509 | Write-Verbose "[$($type.FullName)].GetMethods(`"$BindingFlags`")" 510 | Write-Verbose "[$($type.FullName)].GetConstructors(`"$BindingFlags`")" 511 | Write-Verbose "Filter by Name -like '$Name'" 512 | 513 | 514 | $Type.GetMethods($BindingFlags) + $type.GetConstructors($BindingFlags) | Where-Object { 515 | # Hide the Property accessor methods 516 | ($Force -or !$_.IsSpecialName -or $_.Name -notmatch "^get_|^set_") -AND 517 | # And Filter by Name, if necessary 518 | ($Name -eq "*" -or ($( foreach($n in $Name) { $_.Name -like $n } ) -contains $True)) -AND 519 | (!$Attribute -or $( foreach($n in $Attribute) { $_.CustomAttributes | ForEach { $_.AttributeType.Name -like $n -or $_.AttributeType.FullName -like $n } } ) -contains $True ) 520 | } 521 | } 522 | } 523 | 524 | # if(!($RMI = Get-TypeData System.Reflection.RuntimeMethodInfo) -or !$RMI.Members.ContainsKey("TypeName")) { 525 | # Update-TypeData -TypeName System.Reflection.RuntimeMethodInfo -MemberName "TypeName" -MemberType ScriptProperty -Value { $this.ReflectedType.FullName } 526 | # Update-TypeData -TypeName System.Reflection.RuntimeMethodInfo -MemberName "Definition" -MemberType ScriptProperty -Value { Get-MemberSignature $this -Simple } 527 | # Update-TypeData -TypeName System.Reflection.RuntimeMethodInfo -MemberName "Syntax" -MemberType AliasProperty -Value "Definition" 528 | # Update-TypeData -TypeName System.Reflection.RuntimeMethodInfo -MemberName "SafeSyntax" -MemberType ScriptProperty -Value { Get-MemberSignature $this } 529 | # } 530 | 531 | function Get-MemberSignature { 532 | <# 533 | .Synopsis 534 | Get the powershell signature for calling a member. 535 | #> 536 | [CmdletBinding(DefaultParameterSetName="CallSignature")] 537 | param( 538 | # The Method we're getting the signature for 539 | [Parameter(ValueFromPipeline=$true,Mandatory=$true,Position=0)] 540 | [System.Reflection.MethodBase]$MethodBase, 541 | 542 | [Parameter(Mandatory=$false, Position=1)] 543 | [Type[]]$GenericArguments, 544 | 545 | # Return the simplified markup 546 | [Parameter(ParameterSetName="CallSignature")] 547 | [Switch]$Simple, 548 | 549 | # Return a param block 550 | [Parameter(ParameterSetName="ParamBlock")] 551 | [Switch]$ParamBlock 552 | ) 553 | process { 554 | if($PSCmdlet.ParameterSetName -eq "ParamBlock") { $Simple = $true } 555 | 556 | $parameters = $( 557 | foreach($param in $MethodBase.GetParameters()) { 558 | # Write-Host $param.ParameterType.FullName.TrimEnd('&'), $param.Name -fore cyan 559 | # Write-Verbose "$($param.ParameterType.UnderlyingSystemType.FullName) - $($param.ParameterType)" 560 | $paramType = $param.ParameterType 561 | 562 | Write-Verbose "$(if($paramType.IsGenericType){'Generic: '})$($GenericArguments)" 563 | if($paramType.IsGenericType -and $GenericArguments) { 564 | try { 565 | $paramType = $paramType.GetGenericTypeDefinition().MakeGenericType( $GenericArguments ) 566 | } catch { continue } 567 | } 568 | 569 | if($paramType.Name.EndsWith('&')) { $ref = '[ref]' } else { $ref = '' } 570 | if($paramType.IsArray) { $array = ',' } else { $array = '' } 571 | if($ParamBlock) { 572 | '[Parameter(Mandatory=$true)]{0}[{1}]${2}' -f $ref, $paramType.ToString().TrimEnd('&'), $param.Name 573 | } elseif($Simple) { 574 | '[{0}] {2}' -f $paramType.ToString().TrimEnd('&'), $param.Name 575 | } else { 576 | '{0}({1}[{2}]${3})' -f $ref, $array, $paramType.ToString().TrimEnd('&'), $param.Name 577 | } 578 | } 579 | ) 580 | if($PSCmdlet.ParameterSetName -eq "ParamBlock") { 581 | $parameters -join ', ' 582 | } elseif($MethodBase.IsConstructor) { 583 | "New-Object $($MethodBase.ReflectedType.FullName) $($parameters -join ', ')" 584 | } elseif($Simple) { 585 | "$($MethodBase.ReturnType.FullName) $($MethodBase.Name)($($parameters -join ', '))" 586 | } elseif($MethodBase.IsStatic) { 587 | "[$($MethodBase.ReturnType.FullName)] [$($MethodBase.ReflectedType.FullName)]::$($MethodBase.Name)($($parameters -join ', '))" 588 | } else { 589 | "[$($MethodBase.ReturnType.FullName)] `$$($MethodBase.ReflectedType.Name)Object.$($MethodBase.Name)($($parameters -join ', '))" 590 | } 591 | } 592 | } 593 | 594 | function Read-Choice { 595 | <# 596 | .Synopsis 597 | Prompt the user for a choice, and return the (0-based) index of the selected item 598 | .Example 599 | Read-Choice -Prompt "WEBPAGE BUILDER MENU" "&Create Webpage","&View HTML code","&Publish Webpage","&Remove Webpage","E&xit" 600 | .Example 601 | [bool](Read-Choice "Do you really want to do this?" "&No","&Yes" -Default 1) 602 | 603 | This example takes advantage of the 0-based index to convert No (0) to False, and Yes (1) to True. It also specifies YES as the default, since that's the norm in PowerShell. 604 | .Example 605 | Read-Choice "Do you really want to delete them all?" @{label="&Yes"; Help="Confirm that you want to delete all of the files"},@{Label="&No"; Help="Do not delete all files. You will be prompted to delete each file individually."} 606 | 607 | Specifies the labels and help text explicitly using hashtables. 608 | .Example 609 | $Env:PSModulePath -Split ';' | Read-Choice -Passthru | Get-Item 610 | 611 | Pipes paths into Read-Choice to use as selections, and passes through the selected path to Get-Item 612 | .Example 613 | Get-Process | Where { $_.VM -gt 500MB } | Read-Choice -Multi -Label ProcessName -Value Id -Help { if($_.Path) { $_.Path } else { $_.ProcessName + " (" + $_.ID + ")" } } 614 | 615 | An advanced example dealing with pipeline input. In this example we're taking processes and rendering the name as the labels, and showing the path (or process name and ID) as help, and RETURNING the process Id of the selected processes 616 | #> 617 | [CmdletBinding(DefaultParameterSetName="InputObject")] 618 | param( 619 | # An array of choices (or menu items), with optional ampersands (&) in them to mark (unique) characters which can be used to select each item. 620 | # Can be an array of strings which are used as labels, or objects (or hashtables) with properties for Name (Name or Label or Key) and Help (Help or Expression or Value) 621 | [Parameter(Mandatory=$False, ParameterSetName="InputObject", ValueFromPipeline = $true)] 622 | [Object]$InputObject, 623 | 624 | # This is the prompt that will be presented to the user. Basically, the question you're asking. 625 | [Parameter(Mandatory=$False, Position=0)] 626 | [string]$Prompt = "Choose one of the following options:", 627 | 628 | # An array of choices (or menu items), with optional ampersands (&) in them to mark (unique) characters which can be used to select each item. 629 | # Can be an array of strings which are used as labels, or objects (or hashtables) with properties for Name (Name or Label or Key) and Help (Help or Expression or Value) 630 | [Parameter(Mandatory=$true, Position=1, ParameterSetName="Choices")] 631 | [Array]$Choices, 632 | 633 | # The name of a property of the InputObject to be used as the Label text. 634 | # NOTE: this parameter is ValueFromPipelineByPropertyName and you can use a scriptblock to calculate something based on the InputObject 635 | [Parameter(Mandatory=$false, ParameterSetName="InputObject", ValueFromPipelineByPropertyName = $true)] 636 | [Alias("Name")] 637 | [String]$Label, 638 | 639 | # The name of a property of the InputObject to be used as the Help text. 640 | # NOTE: this parameter is ValueFromPipelineByPropertyName and you can use a scriptblock to calculate something based on the InputObject 641 | [Parameter(Mandatory=$false, ParameterSetName="InputObject", ValueFromPipelineByPropertyName = $true)] 642 | [String]$Help, 643 | 644 | # The name of a property of the InputObject to be used as the Value for output. 645 | # If -Value is set, it forces -Passthru (since there's no other reason to use Value) 646 | # NOTE: this parameter is ValueFromPipelineByPropertyName and you can use a scriptblock to calculate something based on the InputObject 647 | [Parameter(Mandatory=$false, ParameterSetName="InputObject", ValueFromPipelineByPropertyName = $true)] 648 | [String]$Value, 649 | 650 | # An additional caption that can be displayed (usually above the Prompt) as part of the prompt. Defaults to "Please choose!" 651 | [Parameter(Mandatory=$False)] 652 | [string]$Title = "Please choose!", 653 | 654 | # The (0-based) index of the menu item to select by default (defaults to zero). 655 | [Parameter(Mandatory=$False)] 656 | [int[]]$Default = 0, 657 | 658 | # Prompt the user to select more than one option. This changes the prompt display for the default PowerShell.exe host to show the options in a column and allows them to choose multiple times. 659 | # Note: when you specify MultipleChoice you may also specify multiple options as the default! 660 | [Switch]$MultipleChoice, 661 | 662 | # Assume options aren't currently sorted or labelled, and sort them by the key letter we choose 663 | # Setting -Sorted forces -Passthru (since otherwise there's no way to tell what they selected) 664 | [Switch]$Sorted, 665 | 666 | # Causes the Choices objects to be output instead of just the indexes 667 | [Switch]$Passthru 668 | ) 669 | begin { 670 | $ChoiceDescriptions = @() 671 | $Output = @() 672 | if($PSCmdlet.ParameterSetName -eq "Choices") { 673 | $ChoiceDescriptions = $( 674 | foreach($choice in $Choices) { 675 | if($Choice -is [System.Collections.IDictionary]) { 676 | foreach($Key in $Choice.Keys) { 677 | if("Label" -like "${Key}*" -or "Name" -like "${Key}*") { 678 | $Name = $Choice.$Key 679 | } elseif ("Help" -like "${Key}*" -or "Value" -like "${Key}*" -or "Expression" -like "${Key}*") { 680 | $Value = $Choice.$Key 681 | } else { 682 | Write-Error "The key $Key is not valid. Expected `"Label`" and `"Help`"" 683 | } 684 | } 685 | if($Name -and $Value) { 686 | New-Object System.Management.Automation.Host.ChoiceDescription $Name, $Value 687 | } else { 688 | Write-Error "The parameter $Choice is not valid. Expected `"Label`" and `"Help`" keys." 689 | } 690 | } else { 691 | New-Object System.Management.Automation.Host.ChoiceDescription "$Choice", "$Choice" 692 | } 693 | $Output += $Choice 694 | } 695 | ) 696 | } 697 | 698 | # Set calculated* variables true if the parameter is a scriptblock to calculate 699 | $CalculatedLabel = $PSBoundParameters.ContainsKey('Label') -and !$Label 700 | $CalculatedHelp = $PSBoundParameters.ContainsKey('Help') -and !$Help 701 | $CalculatedValue = $PSBoundParameters.ContainsKey('Value') -and !$Value 702 | 703 | if($PSBoundParameters.ContainsKey('Value')) { 704 | $Passthru = $True 705 | } 706 | } 707 | process { 708 | if($PSCmdlet.ParameterSetName -eq 'InputObject') { 709 | $Output += if($CalculatedValue) { $Value } elseif($Value -and $InputObject.$Value) { $InputObject.$Value } elseif($Value) { $Value } else { $InputObject } 710 | $LabelText = if($CalculatedLabel) { $Label } elseif($Label -and $InputObject.$Label) { $InputObject.$Label } elseif($Label) { $Label } else { "$InputObject" } 711 | $HelpText = if($CalculatedHelp) { $Help } elseif($Help -and $InputObject.$Help) { $InputObject.$Help } elseif($Help) { $Help } else { $LabelText } 712 | 713 | if($LabelText -and $HelpText) { 714 | $ChoiceDescriptions += New-Object System.Management.Automation.Host.ChoiceDescription $LabelText, $HelpText 715 | } 716 | } 717 | } 718 | end { 719 | if(@($ChoiceDescriptions).Count -eq 0) { 720 | Write-Error "There were no choices generated, no input" 721 | return 722 | } elseif (@($ChoiceDescriptions).Count -eq 1) { 723 | return $Output 724 | } 725 | 726 | 727 | [string[]]$Labels = $ChoiceDescriptions | % { $_.Label } 728 | # Try making unique keys for the labels: 729 | $Keys = @() 730 | # If they already have a key 731 | for($l =0; $l -lt $Labels.Count; $l++) { 732 | if($Labels[$l].IndexOf('&') -ge 0) { 733 | $Keys += $Labels[$l][($Labels[$l].IndexOf('&')+1)] 734 | } 735 | } 736 | # Otherwise pick the first letter that's not a key 737 | for($l =0; $l -lt $Labels.Count; $l++) { 738 | if($Labels[$l].IndexOf('&') -lt 0) { 739 | for($i = 0; $i -lt $Labels[$l].Length; $i++) { 740 | if($Keys -notcontains $Labels[$l][$i]) { 741 | $Keys += $Labels[$l][$i] 742 | $Labels[$l] = $Labels[$l].Insert($i,'&') 743 | $ChoiceDescriptions[$l] = New-Object System.Management.Automation.Host.ChoiceDescription $Labels[$l], $ChoiceDescriptions[$l].HelpMessage 744 | break 745 | } 746 | } 747 | } 748 | } 749 | # Otherwise, add a number or a letter 750 | for($l =0; $l -lt $Labels.Count; $l++) { 751 | if($Labels[$l].IndexOf('&') -lt 0) { 752 | foreach($i in 49..57+66..90) { 753 | if($Keys -notcontains [string][char]$i) { 754 | $Keys += [string][char]$i 755 | $Labels[$l] = '{0}(&{1})' -f $Labels[$l], ([string][char]$i) 756 | $ChoiceDescriptions[$l] = New-Object System.Management.Automation.Host.ChoiceDescription $Labels[$l], $ChoiceDescriptions[$l].HelpMessage 757 | break 758 | } 759 | } 760 | } 761 | } 762 | if($ChoiceDescriptions.Length -gt 34 -and $Labels -notmatch '&') { 763 | Write-Warning "There are too many choices, some may be unpickable!" 764 | } 765 | 766 | if($Sorted) { 767 | $Passthru = $True 768 | $Max = 1000 769 | $Indexes = $Labels | %{ if(($amp = $_.IndexOf('&')) -lt 0) { ($Max++) } else { [int][byte][char]"$($_[($amp+1)])".ToUpperInvariant() } } 770 | [Array]::Sort($Indexes.Clone(), $Output) 771 | [Array]::Sort($Indexes, $ChoiceDescriptions) 772 | } 773 | 774 | # Passing an array as the $Default triggers multiple choice prompting. 775 | if(!$MultipleChoice) { [int]$Default = $Default[0] } 776 | 777 | [int[]]$Answer = $Host.UI.PromptForChoice($Title,$Prompt,$ChoiceDescriptions,$Default) 778 | 779 | if($Passthru) { 780 | Write-Verbose "$Answer" 781 | Write-Output $Output[$Answer] 782 | } else { 783 | Write-Output $Answer 784 | } 785 | } 786 | } 787 | 788 | function Get-Argument { 789 | param( 790 | [Type]$Target, 791 | [ref]$Method, 792 | [Array]$Arguments 793 | ) 794 | end { 795 | trap { 796 | write-error $_ 797 | break 798 | } 799 | 800 | $flags = [System.Reflection.BindingFlags]"public,ignorecase,invokemethod,instance" 801 | 802 | [Type[]]$Types = @( 803 | foreach($arg in $Arguments) { 804 | if($arg -is [type]) { 805 | $arg 806 | } 807 | else { 808 | $arg.GetType() 809 | } 810 | } 811 | ) 812 | try { 813 | Write-Verbose "[$($Target.FullName)].GetMethod('$($Method.Value)', [$($Flags.GetType())]'$flags', `$null, ([Type[]]($(@($Types|%{$_.Name}) -join ','))), `$null)" 814 | $MethodBase = $Target.GetMethod($($Method.Value), $flags, $null, $types, $null) 815 | $Arguments 816 | if($MethodBase) { 817 | $Method.Value = $MethodBase.Name 818 | } 819 | } catch { } 820 | 821 | if(!$MethodBase) { 822 | Write-Verbose "Try again to get $($Method.Value) Method on $($Target.FullName):" 823 | $MethodBase = Get-Method $target $($Method.Value) 824 | if(@($MethodBase).Count -gt 1) { 825 | $i = 0 826 | $i = Read-Choice -Choices $(foreach($mb in $MethodBase) { @{ "$($mb.SafeSyntax) &$($i = $i+1;$i)`b`n" = $mb.SafeSyntax } }) -Default ($MethodBase.Count-1) -Caption "Choose a Method." -Message "Please choose which method overload to invoke:" 827 | [System.Reflection.MethodBase]$MethodBase = $MethodBase[$i] 828 | } 829 | 830 | 831 | ForEach($parameter in $MethodBase.GetParameters()) { 832 | $found = $false 833 | For($a =0;$a -lt $Arguments.Count;$a++) { 834 | if($argument[$a] -as $parameter.ParameterType) { 835 | Write-Output $argument[$a] 836 | if($a -gt 0 -and $a -lt $Arguments.Count) { 837 | $Arguments = $Arguments | Select -First ($a-1) -Last ($Arguments.Count -$a) 838 | } elseif($a -eq 0) { 839 | $Arguments = $Arguments | Select -Last ($Arguments.Count - 1) 840 | } else { # a -eq count 841 | $Arguments = $Arguments | Select -First ($Arguments.Count - 1) 842 | } 843 | $found = $true 844 | break 845 | } 846 | } 847 | if(!$Found) { 848 | $userInput = Read-Host "Please enter a [$($parameter.ParameterType.FullName)] value for $($parameter.Name)" 849 | if($userInput -match '^{.*}$' -and !($userInput -as $parameter.ParameterType)) { 850 | Write-Output ((Invoke-Expression $userInput) -as $parameter.ParameterType) 851 | } else { 852 | Write-Output ($userInput -as $parameter.ParameterType) 853 | } 854 | } 855 | } 856 | } 857 | } 858 | } 859 | 860 | function Invoke-Member { 861 | [CmdletBinding()] 862 | param( 863 | [parameter(position=10, valuefrompipeline=$true, mandatory=$true)] 864 | [allowemptystring()] 865 | $InputObject, 866 | 867 | [parameter(position=0, mandatory=$true)] 868 | [validatenotnullorempty()] 869 | $Member, 870 | 871 | [parameter(position=1, valuefromremainingarguments=$true)] 872 | [allowemptycollection()] 873 | $Arguments, 874 | 875 | [parameter()] 876 | [switch]$Static 877 | ) 878 | # begin { 879 | # if(!(get-member SafeSyntax -input $Member -type Property)){ 880 | # if(get-member Name -inpup $Member -Type Property) { 881 | # $Member = Get-Method $InputObject $Member.Name 882 | # } else { 883 | # $Member = Get-Method $InputObject $Member 884 | # } 885 | # } 886 | # $SafeSyntax = [ScriptBlock]::Create( $Member.SafeSyntax ) 887 | # } 888 | process { 889 | # if ($InputObject) 890 | # { 891 | # if ($InputObject | Get-Member $Member -static:$static) 892 | # { 893 | 894 | if ($InputObject -is [type]) { 895 | $target = $InputObject 896 | } else { 897 | $target = $InputObject.GetType() 898 | } 899 | 900 | if(Get-Member $Member -InputObject $InputObject -Type Properties) { 901 | $_.$Member 902 | } 903 | elseif($Member -match "ctor|constructor") { 904 | $Member = ".ctor" 905 | [System.Reflection.BindingFlags]$flags = "CreateInstance" 906 | $InputObject = $Null 907 | } 908 | else { 909 | [System.Reflection.BindingFlags]$flags = "IgnoreCase,Public,InvokeMethod" 910 | if($Static) { $flags = "$Flags,Static" } else { $flags = "$Flags,Instance" } 911 | } 912 | [ref]$Member = $Member 913 | [Object[]]$Parameters = Get-Argument $Target $Member $Arguments 914 | [string]$Member = $Member.Value 915 | 916 | Write-Verbose $(($Parameters | %{ '[' + $_.GetType().FullName + ']' + $_ }) -Join ", ") 917 | 918 | try { 919 | Write-Verbose "Invoking $Member on [$target]$InputObject with [$($Flags.GetType())]'$flags' and [$($Parameters.GetType())]($($Parameters -join ','))" 920 | Write-Verbose "[$($target.FullName)].InvokeMember('$Member', [System.Reflection.BindingFlags]'$flags', `$null, '$InputObject', ([object[]]($(($Parameters | %{ '[' + $_.GetType().FullName + ']''' + $_ + ''''}) -join', '))))" 921 | $target.InvokeMember($Member, [System.Reflection.BindingFlags]"$flags", $null, $InputObject, $Parameters) 922 | } catch { 923 | Write-Warning $_.Exception 924 | if ($_.Exception.Innerexception -is [MissingMethodException]) { 925 | write-warning "Method argument count (or type) mismatch." 926 | } 927 | } 928 | # } else { 929 | # write-warning "Method $Member not found." 930 | # } 931 | # } 932 | } 933 | } 934 | 935 | function Invoke-Generic { 936 | #.Synopsis 937 | # Invoke Generic method definitions via reflection: 938 | [CmdletBinding()] 939 | param( 940 | [Parameter(Position=0,Mandatory=$true,ValueFromPipelineByPropertyName=$true)] 941 | [Alias('On')] 942 | $InputObject, 943 | 944 | [Parameter(Position=1,ValueFromPipelineByPropertyName=$true)] 945 | [Alias('Named')] 946 | [string]$MethodName, 947 | 948 | [Parameter(Position=2)] 949 | [Alias("Types")] 950 | [Type[]]$ParameterTypes, 951 | 952 | [Parameter(Position=4, ValueFromRemainingArguments=$true, ValueFromPipelineByPropertyName=$true)] 953 | [Object[]]$WithArgs, 954 | 955 | [Switch]$Static 956 | ) 957 | begin { 958 | if($Static) { 959 | $BindingFlags = [System.Reflection.BindingFlags]"IgnoreCase,Public,Static" 960 | } else { 961 | $BindingFlags = [System.Reflection.BindingFlags]"IgnoreCase,Public,Instance" 962 | } 963 | } 964 | process { 965 | $Type = $InputObject -as [Type] 966 | if(!$Type) { $Type = $InputObject.GetType() } 967 | 968 | if($WithArgs -and -not $ParameterTypes) { 969 | $ParameterTypes = $withArgs | % { $_.GetType() } 970 | } elseif(!$ParameterTypes) { 971 | $ParameterTypes = [Type]::EmptyTypes 972 | } 973 | 974 | 975 | trap { continue } 976 | $MemberInfo = $Type.GetMethod($MethodName, $BindingFlags) 977 | if(!$MemberInfo) { 978 | $MemberInfo = $Type.GetMethod($MethodName, $BindingFlags, $null, $NonGenericArgumentTypes, $null) 979 | } 980 | if(!$MemberInfo) { 981 | $MemberInfo = $Type.GetMethods($BindingFlags) | Where-Object { 982 | $MI = $_ 983 | [bool]$Accept = $MI.Name -eq $MethodName 984 | if($Accept){ 985 | Write-Verbose "$Accept = $($MI.Name) -eq $($MethodName)" 986 | [Array]$GenericTypes = @($MI.GetGenericArguments() | Select -Expand Name) 987 | [Array]$Parameters = @($MI.GetParameters() | Add-Member ScriptProperty -Name IsGeneric -Value { 988 | $GenericTypes -Contains $this.ParameterType 989 | } -Passthru) 990 | 991 | $Accept = $ParameterTypes.Count -eq $Parameters.Count 992 | Write-Verbose " $Accept = $($Parameters.Count) Arguments" 993 | if($Accept) { 994 | for($i=0;$i -lt $Parameters.Count;$i++) { 995 | $Accept = $Accept -and ( $Parameters[$i].IsGeneric -or ($ParameterTypes[$i] -eq $Parameters[$i].ParameterType)) 996 | Write-Verbose " $Accept =$(if($Parameters[$i].IsGeneric){' GENERIC or'}) $($ParameterTypes[$i]) -eq $($Parameters[$i].ParameterType)" 997 | } 998 | } 999 | } 1000 | return $Accept 1001 | } | Sort { @($_.GetGenericArguments()).Count } | Select -First 1 1002 | } 1003 | Write-Verbose "Time to make generic methods." 1004 | Write-Verbose $MemberInfo 1005 | [Type[]]$GenericParameters = @() 1006 | [Array]$ConcreteTypes = @($MemberInfo.GetParameters() | Select -Expand ParameterType) 1007 | for($i=0;$i -lt $ParameterTypes.Count;$i++){ 1008 | Write-Verbose "$($ParameterTypes[$i]) ? $($ConcreteTypes[$i] -eq $ParameterTypes[$i])" 1009 | if($ConcreteTypes[$i] -ne $ParameterTypes[$i]) { 1010 | $GenericParameters += $ParameterTypes[$i] 1011 | } 1012 | $ParameterTypes[$i] = Add-Member -in $ParameterTypes[$i] -Type NoteProperty -Name IsGeneric -Value $($ConcreteTypes[$i] -ne $ParameterTypes[$i]) -Passthru 1013 | } 1014 | 1015 | $ParameterTypes | Where-Object { $_.IsGeneric } 1016 | Write-Verbose "$($GenericParameters -join ', ') generic parameters" 1017 | 1018 | $MemberInfo = $MemberInfo.MakeGenericMethod( $GenericParameters ) 1019 | Write-Verbose $MemberInfo 1020 | 1021 | if($WithArgs) { 1022 | [Object[]]$Arguments = $withArgs | %{ $_.PSObject.BaseObject } 1023 | Write-Verbose "Arguments: $(($Arguments | %{ $_.GetType().Name }) -Join ', ')" 1024 | $MemberInfo.Invoke( $InputObject, $Arguments ) 1025 | } else { 1026 | $MemberInfo.Invoke( $InputObject ) 1027 | } 1028 | } 1029 | } 1030 | 1031 | ############################################################################### 1032 | ##### Imported from PowerBoots 1033 | 1034 | $Script:CodeGenContentProperties = 'Content','Child','Children','Frames','Items','Pages','Blocks','Inlines','GradientStops','Source','DataPoints', 'Series', 'VisualTree' 1035 | $DependencyProperties = @{} 1036 | if(Test-Path $PSScriptRoot\DependencyPropertyCache.xml) { 1037 | #$DependencyProperties = [System.Windows.Markup.XamlReader]::Parse( (gc $PSScriptRoot\DependencyPropertyCache.xml) ) 1038 | $DependencyProperties = Import-CliXml $PSScriptRoot\DependencyPropertyCache.xml 1039 | } 1040 | 1041 | function Get-ReflectionModule { $executioncontext.sessionstate.module } 1042 | 1043 | function Set-ObjectProperties { 1044 | [CmdletBinding()] 1045 | param( $Parameters, [ref]$DObject ) 1046 | 1047 | if($DObject.Value -is [System.ComponentModel.ISupportInitialize]) { $DObject.Value.BeginInit() } 1048 | 1049 | if($DebugPreference -ne "SilentlyContinue") { Write-Host; Write-Host ">>>> $($Dobject.Value.GetType().FullName)" -fore Black -back White } 1050 | foreach ($param in $Parameters) { 1051 | if($DebugPreference -ne "SilentlyContinue") { Write-Host "Processing Param: $($param|Out-String )" } 1052 | ## INGORE DEPENDENCY PROPERTIES FOR NOW :) 1053 | if($param.Key -eq "DependencyProps") { 1054 | ## HANDLE EVENTS .... 1055 | } 1056 | elseif ($param.Key.StartsWith("On_")) { 1057 | $EventName = $param.Key.SubString(3) 1058 | if($DebugPreference -ne "SilentlyContinue") { Write-Host "Event handler $($param.Key) Type: $(@($param.Value)[0].GetType().FullName)" } 1059 | $sb = $param.Value -as [ScriptBlock] 1060 | if(!$sb) { 1061 | $sb = (Get-Command $param.Value -CommandType Function,ExternalScript).ScriptBlock 1062 | } 1063 | $Dobject.Value."Add_$EventName".Invoke( $sb ); 1064 | # $Dobject.Value."Add_$EventName".Invoke( ($sb.GetNewClosure()) ); 1065 | 1066 | # $Dobject.Value."Add_$EventName".Invoke( $PSCmdlet.MyInvocation.MyCommand.Module.NewBoundScriptBlock( $sb.GetNewClosure() ) ); 1067 | 1068 | 1069 | } ## HANDLE PROPERTIES .... 1070 | else { 1071 | try { 1072 | ## TODO: File a BUG because Write-DEBUG and Write-VERBOSE die here. 1073 | if($DebugPreference -ne "SilentlyContinue") { 1074 | Write-Host "Setting $($param.Key) of $($Dobject.Value.GetType().Name) to $($param.Value.GetType().FullName): $($param.Value)" -fore Gray 1075 | } 1076 | if(@(foreach($sb in $param.Value) { $sb -is [ScriptBlock] }) -contains $true) { 1077 | $Values = @() 1078 | foreach($sb in $param.Value) { 1079 | $Values += & (Get-ReflectionModule) $sb 1080 | } 1081 | } else { 1082 | $Values = $param.Value 1083 | } 1084 | 1085 | if($DebugPreference -ne "SilentlyContinue") { Write-Host ([System.Windows.Markup.XamlWriter]::Save( $Dobject.Value )) -foreground green } 1086 | if($DebugPreference -ne "SilentlyContinue") { Write-Host ([System.Windows.Markup.XamlWriter]::Save( @($Values)[0] )) -foreground green } 1087 | 1088 | Set-Property $Dobject $Param.Key $Values 1089 | 1090 | if($DebugPreference -ne "SilentlyContinue") { Write-Host ([System.Windows.Markup.XamlWriter]::Save( $Dobject.Value )) -foreground magenta } 1091 | 1092 | if($DebugPreference -ne "SilentlyContinue") { 1093 | if( $Dobject.Value.$($param.Key) -ne $null ) { 1094 | Write-Host $Dobject.Value.$($param.Key).GetType().FullName -fore Green 1095 | } 1096 | } 1097 | } 1098 | catch [Exception] 1099 | { 1100 | Write-Host "COUGHT AN EXCEPTION" -fore Red 1101 | Write-Host $_ -fore Red 1102 | Write-Host $this -fore DarkRed 1103 | } 1104 | } 1105 | 1106 | while($DependencyProps) { 1107 | $name, $value, $DependencyProps = $DependencyProps 1108 | $name = ([string]@($name)[0]).Trim("-") 1109 | if($name -and $value) { 1110 | Set-DependencyProperty -Element $Dobject.Value -Property $name -Value $Value 1111 | } 1112 | } 1113 | } 1114 | if($DebugPreference -ne "SilentlyContinue") { Write-Host "<<<< $($Dobject.Value.GetType().FullName)" -fore Black -back White; Write-Host } 1115 | 1116 | if($DObject.Value -is [System.ComponentModel.ISupportInitialize]) { $DObject.Value.EndInit() } 1117 | 1118 | } 1119 | 1120 | function Set-Property { 1121 | PARAM([ref]$TheObject, $Name, $Values) 1122 | $DObject = $TheObject.Value 1123 | 1124 | if($DebugPreference -ne "SilentlyContinue") { Write-Host ([System.Windows.Markup.XamlWriter]::Save( $DObject )) -foreground DarkMagenta } 1125 | if($DebugPreference -ne "SilentlyContinue") { Write-Host ([System.Windows.Markup.XamlWriter]::Save( @($Values)[0] )) -foreground DarkMagenta } 1126 | 1127 | $PropertyType = $DObject.GetType().GetProperty($Name).PropertyType 1128 | if('System.Windows.FrameworkElementFactory' -as [Type] -and $PropertyType -eq [System.Windows.FrameworkElementFactory] -and $DObject -is [System.Windows.FrameworkTemplate]) { 1129 | if($DebugPreference -ne "SilentlyContinue") { Write-Host "Loading a FrameworkElementFactory" -foreground Green} 1130 | 1131 | # [Xml]$Template = [PoshWpf.XamlHelper]::ConvertToXaml( $DObject ) 1132 | # [Xml]$Content = [PoshWpf.XamlHelper]::ConvertToXaml( (@($Values)[0]) ) 1133 | # In .Net 3.5 the recommended way to programmatically create a template is to load XAML from a string or a memory stream using the Load method of the XamlReader class. 1134 | [Xml]$Template = [System.Windows.Markup.XamlWriter]::Save( $DObject ) 1135 | [Xml]$Content = [System.Windows.Markup.XamlWriter]::Save( (@($Values)[0]) ) 1136 | 1137 | $Template.DocumentElement.PrependChild( $Template.ImportNode($Content.DocumentElement, $true) ) | Out-Null 1138 | 1139 | $TheObject.Value = [System.Windows.Markup.XamlReader]::Parse( $Template.get_OuterXml() ) 1140 | } 1141 | elseif('System.Windows.Data.Binding' -as [Type] -and @($Values)[0] -is [System.Windows.Data.Binding] -and !$PropertyType.IsAssignableFrom([System.Windows.Data.BindingBase])) { 1142 | $Binding = @($Values)[0]; 1143 | if($DebugPreference -ne "SilentlyContinue") { Write-Host "$($DObject.GetType())::$Name is $PropertyType and the value is a Binding: $Binding" -fore Cyan} 1144 | 1145 | if(!$Binding.Source -and !$Binding.ElementName) { 1146 | $Binding.Source = $DObject.DataContext 1147 | } 1148 | if($DependencyProperties.ContainsKey($Name)) { 1149 | $field = @($DependencyProperties.$Name.Keys | Where { $DObject -is $_ -and $PropertyType -eq ([type]$DependencyProperties.$Name.$_.PropertyType)})[0] # -or -like "*$Class" -and ($Param1.Value -as ([type]$_.PropertyType) 1150 | if($field) { 1151 | if($DebugPreference -ne "SilentlyContinue") { Write-Host "$($field)" -fore Blue } 1152 | if($DebugPreference -ne "SilentlyContinue") { Write-Host "Binding: ($field)::`"$($DependencyProperties.$Name.$field.Name)`" to $Binding" -fore Blue} 1153 | 1154 | $DObject.SetBinding( ([type]$field)::"$($DependencyProperties.$Name.$field.Name)", $Binding ) | Out-Null 1155 | } else { 1156 | throw "Couldn't figure out $( @($DependencyProperties.$Name.Keys) -join ', ' )" 1157 | } 1158 | } else { 1159 | if($DebugPreference -ne "SilentlyContinue") { 1160 | Write-Host "But $($DObject.GetType())::${Name}Property is not a Dependency Property, so it probably can't be bound?" -fore Cyan 1161 | } 1162 | try { 1163 | 1164 | $DObject.SetBinding( ($DObject.GetType()::"${Name}Property"), $Binding ) | Out-Null 1165 | 1166 | if($DebugPreference -ne "SilentlyContinue") { 1167 | Write-Host ([System.Windows.Markup.XamlWriter]::Save( $Dobject )) -foreground yellow 1168 | } 1169 | } catch { 1170 | Write-Host "Nope, was not able to set it." -fore Red 1171 | Write-Host $_ -fore Red 1172 | Write-Host $this -fore DarkRed 1173 | } 1174 | } 1175 | } 1176 | elseif($PropertyType -ne [Object] -and $PropertyType.IsAssignableFrom( [System.Collections.IEnumerable] ) -and ($DObject.$($Name) -eq $null)) { 1177 | if($Values -is [System.Collections.IEnumerable]) { 1178 | if($DebugPreference -ne "SilentlyContinue") { Write-Host "$Name is $PropertyType which is IEnumerable, and the value is too!" -fore Cyan } 1179 | $DObject.$($Name) = $Values 1180 | } else { 1181 | if($DebugPreference -ne "SilentlyContinue") { Write-Host "$Name is $PropertyType which is IEnumerable, but the value is not." -fore Cyan } 1182 | $DObject.$($Name) = new-object "System.Collections.ObjectModel.ObservableCollection[$(@($Values)[0].GetType().FullName)]" 1183 | $DObject.$($Name).Add($Values) 1184 | } 1185 | } 1186 | elseif($DObject.$($Name) -is [System.Collections.IList]) { 1187 | foreach ($value in @($Values)) { 1188 | try { 1189 | $null = $DObject.$($Name).Add($value) 1190 | } 1191 | catch 1192 | { 1193 | # Write-Host "CAUGHT array problem" -fore Red 1194 | if($_.Exception.Message -match "Invalid cast from 'System.String' to 'System.Windows.UIElement'.") { 1195 | $null = $DObject.$($Name).Add( (New-System.Windows.Controls.TextBlock $value) ) 1196 | } else { 1197 | Write-Error $_.Exception 1198 | throw 1199 | } 1200 | } 1201 | } 1202 | } 1203 | else { 1204 | ## If they pass an array of 1 when we only want one, we just use the first value 1205 | if($Values -is [System.Collections.IList] -and $Values.Count -eq 1) { 1206 | if($DebugPreference -ne "SilentlyContinue") { Write-Host "Value is an IList ($($Values.GetType().FullName))" -fore Cyan} 1207 | if($DebugPreference -ne "SilentlyContinue") { Write-Host "But we'll just use the first ($($Values[0].GetType().FullName))" -fore Cyan} 1208 | 1209 | if($DebugPreference -ne "SilentlyContinue") { Write-Host ([System.Windows.Markup.XamlWriter]::Save( $Values[0] )) -foreground White} 1210 | try { 1211 | $DObject.$($Name) = $Values[0] 1212 | } 1213 | catch [Exception] 1214 | { 1215 | # Write-Host "CAUGHT collection value problem" -fore Red 1216 | if($_.Exception.Message -match "Invalid cast from 'System.String' to 'System.Windows.UIElement'.") { 1217 | $null = $DObject.$($Name).Add( (TextBlock $Values[0]) ) 1218 | }else { 1219 | throw 1220 | } 1221 | } 1222 | } 1223 | else ## If they pass an array when we only want one, we try to use it, and failing that, cast it to strings 1224 | { 1225 | if($DebugPreference -ne "SilentlyContinue") { Write-Host "Value is just $Values" -fore Cyan} 1226 | try { 1227 | $DObject.$($Name) = $Values 1228 | } catch [Exception] 1229 | { 1230 | # Write-Host "CAUGHT value problem" -fore Red 1231 | if($_.Exception.Message -match "Invalid cast from 'System.String' to 'System.Windows.UIElement'.") { 1232 | $null = $DObject.$($Name).Add( (TextBlock $values) ) 1233 | }else { 1234 | throw 1235 | } 1236 | } 1237 | } 1238 | } 1239 | } 1240 | 1241 | function Set-DependencyProperty { 1242 | [CmdletBinding()] 1243 | param( 1244 | [Parameter(Position=0,Mandatory=$true)] 1245 | $Property, 1246 | 1247 | [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 1248 | $Element, 1249 | 1250 | [Parameter()] 1251 | [Switch]$Passthru 1252 | ) 1253 | 1254 | dynamicParam { 1255 | $paramDictionary = new-object System.Management.Automation.RuntimeDefinedParameterDictionary 1256 | $Param1 = new-object System.Management.Automation.RuntimeDefinedParameter 1257 | $Param1.Name = "Value" 1258 | # $Param1.Attributes.Add( (New-ParameterAttribute -Position 1) ) 1259 | $Param1.Attributes.Add( (New-Object System.Management.Automation.ParameterAttribute -Property @{ Position = 1 }) ) 1260 | 1261 | if( $Property ) { 1262 | if($Property.GetType() -eq ([System.Windows.DependencyProperty]) -or 1263 | $Property.GetType().IsSubclassOf(([System.Windows.DependencyProperty]))) 1264 | { 1265 | $Param1.ParameterType = $Property.PropertyType 1266 | } 1267 | elseif($Property -is [string] -and $Property.Contains(".")) { 1268 | $Class,$Property = $Property.Split(".") 1269 | if($DependencyProperties.ContainsKey($Property)){ 1270 | $type = $DependencyProperties.$Property.Keys -like "*$Class" 1271 | if($type) { 1272 | $Param1.ParameterType = [type]@($DependencyProperties.$Property.$type)[0].PropertyType 1273 | } 1274 | } 1275 | 1276 | } elseif($DependencyProperties.ContainsKey($Property)){ 1277 | if($Element) { 1278 | if($DependencyProperties.$Property.ContainsKey( $element.GetType().FullName )) { 1279 | $Param1.ParameterType = [type]$DependencyProperties.$Property.($element.GetType().FullName).PropertyType 1280 | } 1281 | } else { 1282 | $Param1.ParameterType = [type]$DependencyProperties.$Property.Values[0].PropertyType 1283 | } 1284 | } 1285 | else 1286 | { 1287 | $Param1.ParameterType = [PSObject] 1288 | } 1289 | } 1290 | else 1291 | { 1292 | $Param1.ParameterType = [PSObject] 1293 | } 1294 | $paramDictionary.Add("Value", $Param1) 1295 | return $paramDictionary 1296 | } 1297 | process { 1298 | trap { 1299 | Write-Host "ERROR Setting Dependency Property" -Fore Red 1300 | Write-Host "Trying to set $Property to $($Param1.Value)" -Fore Red 1301 | continue 1302 | } 1303 | if($Property.GetType() -eq ([System.Windows.DependencyProperty]) -or 1304 | $Property.GetType().IsSubclassOf(([System.Windows.DependencyProperty])) 1305 | ){ 1306 | trap { 1307 | Write-Host "ERROR Setting Dependency Property" -Fore Red 1308 | Write-Host "Trying to set $($Property.FullName) to $($Param1.Value)" -Fore Red 1309 | continue 1310 | } 1311 | $Element.SetValue($Property, ($Param1.Value -as $Property.PropertyType)) 1312 | } else { 1313 | if("$Property".Contains(".")) { 1314 | $Class,$Property = "$Property".Split(".") 1315 | } 1316 | 1317 | if( $DependencyProperties.ContainsKey("$Property" ) ) { 1318 | $fields = @( $DependencyProperties.$Property.Keys -like "*$Class" | ? { $Param1.Value -as ([type]$DependencyProperties.$Property.$_.PropertyType) } ) 1319 | if($fields.Count -eq 0 ) { 1320 | $fields = @($DependencyProperties.$Property.Keys -like "*$Class" ) 1321 | } 1322 | if($fields.Count) { 1323 | $success = $false 1324 | foreach($field in $fields) { 1325 | trap { 1326 | Write-Host "ERROR Setting Dependency Property" -Fore Red 1327 | Write-Host "Trying to set $($field)::$($DependencyProperties.$Property.$field.Name) to $($Param1.Value) -as $($DependencyProperties.$Property.$field.PropertyType)" -Fore Red 1328 | continue 1329 | } 1330 | $Element.SetValue( ([type]$field)::"$($DependencyProperties.$Property.$field.Name)", ($Param1.Value -as ([type]$DependencyProperties.$Property.$field.PropertyType))) 1331 | if($?) { $success = $true; break } 1332 | } 1333 | 1334 | if(!$success) { 1335 | throw "food" 1336 | } 1337 | } else { 1338 | Write-Host "Couldn't find the right property: $Class.$Property on $( $Element.GetType().Name ) of type $( $Param1.Value.GetType().FullName )" -Fore Red 1339 | } 1340 | } 1341 | else { 1342 | Write-Host "Unknown Dependency Property Key: $Property on $($Element.GetType().Name)" -Fore Red 1343 | } 1344 | } 1345 | 1346 | if( $Passthru ) { $Element } 1347 | } 1348 | } 1349 | 1350 | function Add-Struct { 1351 | <# 1352 | .Synopsis 1353 | Creates Struct types from a list of types and properties 1354 | .Description 1355 | Add-Struct is a wrapper for Add-Type to create struct types. 1356 | .Example 1357 | New-Struct Song { 1358 | [string]$Artist 1359 | [string]$Album 1360 | [string]$Name 1361 | [TimeSpan]$Length 1362 | } -CreateConstructorFunction 1363 | 1364 | Description 1365 | ----------- 1366 | Creates a "Song" type with strongly typed Artist, Album, Name, and Length properties, with a simple constructor and a constructor function 1367 | .Example 1368 | New-Struct @{ 1369 | >> Product = { [string]$Name; [double]$Price; } 1370 | >> Order = { [Guid]$Id; [Product]$Product; [int]$Quantity } 1371 | >> Customer = { 1372 | >> [string]$FirstName 1373 | >> [string]$LastName 1374 | >> [int]$Age 1375 | >> [Order[]]$OrderHistory 1376 | >> } 1377 | >> } 1378 | >> 1379 | 1380 | Description 1381 | ----------- 1382 | To create a series of related struct types (where one type is a property of another type), you need to use the -Types hashtable parameter set. That way, all of the types will compiled together at once, so the compiler will be able to find them all. 1383 | #> 1384 | [CmdletBinding(DefaultParameterSetName="Multiple")] 1385 | param( 1386 | # The name of the TYPE you are creating. Must be unique per PowerShell session. 1387 | [ValidateScript({ 1388 | if($_ -notmatch '^[a-z][a-z1-9_]*$') { 1389 | throw "'$_' is invalid. A valid name identifier must start with a letter, and contain only alpha-numeric or the underscore (_)." 1390 | } 1391 | return $true 1392 | })] 1393 | [Parameter(Position=0, Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName = "Single")] 1394 | [string]$Name, 1395 | 1396 | # A Scriptblock full of "[Type]$Name" definitions to show what properties you want on your Struct type 1397 | [Parameter(Position=1, Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName = "Single")] 1398 | [ScriptBlock]$Property, 1399 | 1400 | # A Hashtable in the form @{Name={Properties}} with multiple Names and Property Scriptblocks to define related structs (see example 2). 1401 | [Parameter(Position=0, Mandatory=$true, ParameterSetName = "Multiple")] 1402 | [HashTable]$Types, 1403 | 1404 | # Generate a New-StructName shortcut function for each New-Object StructName 1405 | [Alias("CTorFunction","ConstructorFunction")] 1406 | [Switch]$CreateConstructorFunction, 1407 | 1408 | # Output the defined type(s) 1409 | [Switch]$PassThru 1410 | ) 1411 | begin { 1412 | if($PSCmdlet.ParameterSetName -eq "Multiple") { 1413 | $Structs = foreach($key in $Types.Keys) { 1414 | New-Object PSObject -Property @{Name=$key;Property=$Types.$key} 1415 | } 1416 | Write-Verbose ($Structs | Out-String) 1417 | $Structs | New-Struct -Passthru:$Passthru -CreateConstructorFunction:$CreateConstructorFunction 1418 | } else { 1419 | $code = "using System;`nusing System.Collections;`nusing System.Management.Automation;`n" 1420 | $function = "" 1421 | } 1422 | } 1423 | process { 1424 | if($PSCmdlet.ParameterSetName -ne "Multiple") { 1425 | $parserrors = $null 1426 | $tokens = [PSParser]::Tokenize( $Property, [ref]$parserrors ) | Where-Object { "Newline","StatementSeparator" -notcontains $_.Type } 1427 | 1428 | # CODE GENERATION MAGIKS! 1429 | $Name = $Name.ToUpper()[0] + $Name.SubString(1) 1430 | $ctor = @() 1431 | $setr = @() 1432 | $prop = @() 1433 | $parm = @() 1434 | $cast = @() 1435 | $hash = @() 1436 | $2Str = @() 1437 | 1438 | $(while($typeToken,$varToken,$tokens = $tokens) { 1439 | if($typeToken.Type -ne "Type") { 1440 | throw "Error on line $($typeToken.StartLine) Column $($typeToken.Start). The Struct Properties block must contain only statements of the form: [Type]`$Name, see Get-Help New-Struct -Parameter Properties" 1441 | } elseif($varToken.Type -ne "Variable") { 1442 | throw "Error on line $($varToken.StartLine) Column $($varToken.Start). The Struct Properties block must contain only statements of the form: [Type]`$Name, see Get-Help New-Struct -Parameter Properties" 1443 | } 1444 | 1445 | $varName = $varToken.Content.ToUpper()[0] + $varToken.Content.SubString(1) 1446 | $varNameLower = $varName.ToLower()[0] + $varName.SubString(1) 1447 | try { 1448 | $typeName = Invoke-Expression "[$($typeToken.Content)].FullName" 1449 | } catch { 1450 | $typeName = $typeToken.Content 1451 | } 1452 | 1453 | $prop += ' public {0} {1};' -f $typeName,$varName 1454 | $setr += ' {0} = {1};' -f $varName,$varNameLower 1455 | $ctor += '{0} {1}' -f $typeName,$varNameLower 1456 | $cast += ' if(input.Properties["{0}"] != null){{ output.{0} = ({1})input.Properties["{0}"].Value; }}' -f $varName,$typeName 1457 | $hash += ' if(hash.ContainsKey("{0}")){{ output.{0} = ({1})hash["{0}"]; }}' -f $varName,$typeName 1458 | $2Str += '"{0} = [{1}]\"" + {0}.ToString() + "\""' -f $varName, $typeName 1459 | if($CreateConstructorFunction) { 1460 | $parm += '[{0}]${1}' -f $typeName,$varName 1461 | } 1462 | }) 1463 | 1464 | $code += @" 1465 | public struct $Name { 1466 | $($prop -join "`n") 1467 | public $Name ($( $ctor -join ",")) 1468 | { 1469 | $($setr -join "`n") 1470 | } 1471 | public static implicit operator $Name(Hashtable hash) 1472 | { 1473 | $Name output = new $Name(); 1474 | $($hash -join "`n") 1475 | return output; 1476 | } 1477 | public static implicit operator $Name(PSObject input) 1478 | { 1479 | $Name output = new $Name(); 1480 | $($cast -join "`n") 1481 | return output; 1482 | } 1483 | 1484 | public override string ToString() 1485 | { 1486 | return "@{" + $($2Str -join ' + "; " + ') + "}"; 1487 | } 1488 | } 1489 | 1490 | "@ 1491 | 1492 | if($CreateConstructorFunction) { 1493 | $function += @" 1494 | Function global:New-$Name { 1495 | [CmdletBinding()] 1496 | param( 1497 | $( $parm -join ",`n" ) 1498 | ) 1499 | New-Object $Name -Property `$PSBoundParameters 1500 | } 1501 | 1502 | "@ 1503 | } 1504 | 1505 | } 1506 | } 1507 | end { 1508 | if($PSCmdlet.ParameterSetName -ne "Multiple") { 1509 | Write-Verbose "C# Code:`n$code" 1510 | Write-Verbose "PowerShell Code:`n$function" 1511 | 1512 | Add-Type -TypeDefinition $code -PassThru:$Passthru -ErrorAction Stop 1513 | if($CreateConstructorFunction) { 1514 | Invoke-Expression $function 1515 | } 1516 | } 1517 | } 1518 | } 1519 | 1520 | function Add-Enum { 1521 | #.Synopsis 1522 | # Generates an enumerable type 1523 | #.Description 1524 | # Add-Enum is a wrapper for Add-Type to create Enums that can be used as parameters for functions. It includes the ability to create Flag enums, and automatically generates integer values (optionally adding a "None" (zero) value with the name you specify). 1525 | #.Example 1526 | # Add-Enum SpecialFolders Desktop Programs Personal MyDocuments 1527 | #.Example 1528 | # get-content FolderPerLine.txt | New-Enum "SpecialFolders" 1529 | [CmdletBinding(DefaultParameterSetName="Simple")] 1530 | param ( 1531 | # The name of the enum type. 1532 | # Note: To avoid collisions, this type will reside in the "PowerEnums" namespace, but we'll generate an alias for it so you can use just the name. 1533 | [Parameter(Position=0,Mandatory=$true)] 1534 | [String]$Name, 1535 | 1536 | # The values in the enum 1537 | [Parameter(Position=1,Mandatory=$true,ValueFromPipeline=$true,ValueFromRemainingArguments=$true)] 1538 | [String[]]$Members, 1539 | 1540 | # Controls whether the enum is generated as a [Flags] enum (meaning that combinations of the enumerations are valid) 1541 | [Parameter(ParameterSetName="Flags",Mandatory=$true)] 1542 | [Switch]$Flags, 1543 | 1544 | # Sets the name for the "None" (zero) value in a flags enum 1545 | [Parameter(ParameterSetName="Flags")] 1546 | [String]$ZeroValue, 1547 | 1548 | # If set, the type will be output 1549 | [Switch]$Passthru 1550 | ) 1551 | begin { 1552 | $AllMembers = New-Object System.Collections.Generic.List[String] 1553 | } 1554 | process { 1555 | $AllMembers += $Members 1556 | } 1557 | end { 1558 | $Members = foreach($m in $AllMembers -Split " ") { $m.Trim() -replace "^.", $m.Trim()[0].ToString().ToUpper() } 1559 | $Members = $Members | Select -Unique 1560 | if($Flags) { 1561 | $Value = 1 1562 | $Members = foreach($m in $Members) { 1563 | "$m = $Value" 1564 | $Value += $Value 1565 | } 1566 | if($ZeroValue) { 1567 | $Members = @("$ZeroValue = 0,`n") + $Members 1568 | } 1569 | } 1570 | 1571 | $Type = Add-Type -TypeDefinition @" 1572 | namespace PowerEnums { 1573 | $(if($Flags){"[System.Flags]"}) 1574 | public enum $Name { 1575 | $($Members -Join ",`n") 1576 | } 1577 | } 1578 | "@ -Passthru 1579 | 1580 | if($Type) { 1581 | Add-Accelerator $Name $Type 1582 | 1583 | if($Passthru) { 1584 | $Type 1585 | } 1586 | } 1587 | } 1588 | } 1589 | 1590 | Add-Type -Assembly WindowsBase 1591 | function Add-ConstructorFunction { 1592 | <# 1593 | .Synopsis 1594 | Add support for a new class by creating the dynamic constructor function(s). 1595 | .Description 1596 | Creates a New-Namespace.Type function for each type passed in, as well as a short form "Type" alias. 1597 | 1598 | Exposes all of the properties and events of the type as perameters to the function. 1599 | 1600 | NOTE: The Type MUST have a default parameterless constructor. 1601 | .Parameter Assembly 1602 | The Assembly you want to generate constructors for. All public types within it will be generated if possible. 1603 | .Parameter Type 1604 | The type you want to create a constructor function for. It must have a default parameterless constructor. 1605 | .Example 1606 | Add-ConstructorFunction System.Windows.Controls.Button 1607 | 1608 | Creates a new function for the Button control. 1609 | 1610 | .Example 1611 | [Reflection.Assembly]::LoadWithPartialName( "PresentationFramework" ).GetTypes() | Add-ConstructorFunction 1612 | 1613 | Will create constructor functions for all the WPF components in the PresentationFramework assembly. Note that you could also load that assembly using GetAssembly( "System.Windows.Controls.Button" ) or Load( "PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" ) 1614 | 1615 | .Example 1616 | Add-ConstructorFunction -Assembly PresentationFramework 1617 | 1618 | Will create constructor functions for all the WPF components in the PresentationFramework assembly. 1619 | 1620 | .Links 1621 | http://HuddledMasses.org/powerboots 1622 | .ReturnValue 1623 | The name(s) of the function(s) created -- so you can export them, if necessary. 1624 | .Notes 1625 | AUTHOR: Joel Bennett http://HuddledMasses.org 1626 | LASTEDIT: 2009-01-13 16:35:23 1627 | #> 1628 | [CmdletBinding(DefaultParameterSetName="FromType")] 1629 | param( 1630 | [Parameter(Position=0,ValueFromPipeline=$true,ParameterSetName="FromType",Mandatory=$true)] 1631 | [type[]]$type, 1632 | 1633 | [Alias("FullName")] 1634 | [Parameter(Position=0,ValueFromPipelineByPropertyName=$true,ParameterSetName="FromAssembly",Mandatory=$true)] 1635 | [string[]]$Assembly, 1636 | 1637 | [Parameter()] 1638 | [string]$Path = "$PSScriptRoot\Types_Generated", 1639 | 1640 | [switch]$Force, 1641 | 1642 | [switch]$ShortAliases, 1643 | 1644 | [Switch]$Quiet 1645 | ) 1646 | begin { 1647 | [Type[]]$Empty=@() 1648 | if(!(Test-Path $Path)) { 1649 | MkDir $Path 1650 | } 1651 | $ErrorList = @() 1652 | } 1653 | end { 1654 | #Set-Content -Literal $PSScriptRoot\DependencyPropertyCache.xml -Value ([System.Windows.Markup.XamlWriter]::Save( $DependencyProperties )) 1655 | Export-CliXml -Path $PSScriptRoot\DependencyPropertyCache.xml -InputObject $DependencyProperties 1656 | 1657 | if($ErrorList.Count) { Write-Warning "Some New-* functions not aliased." } 1658 | $ErrorList | Write-Error 1659 | } 1660 | process { 1661 | if($PSCmdlet.ParameterSetName -eq "FromAssembly") { 1662 | [type[]]$type = @() 1663 | foreach($lib in $Assembly) { 1664 | $asm = $null 1665 | trap { continue } 1666 | if(Test-Path $lib) { 1667 | $asm = [Reflection.Assembly]::LoadFrom( (Convert-Path (Resolve-Path $lib -EA "SilentlyContinue") -EA "SilentlyContinue") ) 1668 | } 1669 | if(!$asm) { 1670 | ## BUGBUG: LoadWithPartialName is "Obsolete" -- but it still works in 2.0/3.5 1671 | $asm = [Reflection.Assembly]::LoadWithPartialName( $lib ) 1672 | } 1673 | if($asm) { 1674 | $type += $asm.GetTypes() | ?{ $_.IsPublic -and !$_.IsEnum -and 1675 | !$_.IsAbstract -and !$_.IsInterface -and 1676 | $_.GetConstructor( "Instance,Public", $Null, $Empty, @() )} 1677 | } else { 1678 | Write-Error "Can't find the assembly $lib, please check your spelling and try again" 1679 | } 1680 | } 1681 | } 1682 | 1683 | foreach($T in $type) { 1684 | $TypeName = $T.FullName 1685 | $ScriptPath = Join-Path $Path "New-$TypeName.ps1" 1686 | Write-Verbose $TypeName 1687 | 1688 | ## Collect all dependency properties .... 1689 | $T.GetFields() | 1690 | Where-Object { $_.FieldType -eq [System.Windows.DependencyProperty] } | 1691 | ForEach-Object { 1692 | [string]$Field = $_.DeclaringType::"$($_.Name)".Name 1693 | [string]$TypeName = $_.DeclaringType.FullName 1694 | 1695 | if(!$DependencyProperties.ContainsKey( $Field )) { 1696 | $DependencyProperties.$Field = @{} 1697 | } 1698 | 1699 | $DependencyProperties.$Field.$TypeName = @{ 1700 | Name = [string]$_.Name 1701 | PropertyType = [string]$_.DeclaringType::"$($_.Name)".PropertyType.FullName 1702 | } 1703 | } 1704 | 1705 | if(!( Test-Path $ScriptPath ) -OR $Force) { 1706 | $Pipelineable = @(); 1707 | ## Get (or generate) a set of parameters based on the the Type Name 1708 | $PropertyNames = New-Object System.Text.StringBuilder "@(" 1709 | 1710 | $Parameters = New-Object System.Text.StringBuilder "[CmdletBinding(DefaultParameterSetName='Default')]`nPARAM(`n" 1711 | 1712 | ## Add all properties 1713 | $Properties = $T.GetProperties("Public,Instance,FlattenHierarchy") | 1714 | Where-Object { $_.CanWrite -Or $_.PropertyType.GetInterface([System.Collections.IList]) } 1715 | 1716 | $Properties = ($T.GetEvents("Public,Instance,FlattenHierarchy") + $Properties) | Sort-Object Name -Unique 1717 | 1718 | foreach ($p in $Properties) { 1719 | $null = $PropertyNames.AppendFormat(",'{0}'",$p.Name) 1720 | switch( $p.MemberType ) { 1721 | Event { 1722 | $null = $PropertyNames.AppendFormat(",'{0}__'",$p.Name) 1723 | $null = $Parameters.AppendFormat(@' 1724 | [Parameter()] 1725 | [PSObject]${{On_{0}}}, 1726 | 1727 | '@, $p.Name) 1728 | } 1729 | Property { 1730 | if($p.Name -match "^$($CodeGenContentProperties -Join '$|^')`$") { 1731 | $null = $Parameters.AppendFormat(@' 1732 | [Parameter(Position=1,ValueFromPipeline=$true)] 1733 | [Object[]]${{{0}}}, 1734 | 1735 | '@, $p.Name) 1736 | $Pipelineable += @(Add-Member -in $p.Name -Type NoteProperty -Name "IsCollection" -Value $($p.PropertyType.GetInterface([System.Collections.IList]) -ne $null) -Passthru) 1737 | } 1738 | elseif($p.PropertyType -eq [System.Boolean]) 1739 | { 1740 | $null = $Parameters.AppendFormat(@' 1741 | [Parameter()] 1742 | [Switch]${{{0}}}, 1743 | 1744 | '@, $p.Name) 1745 | } 1746 | else 1747 | { 1748 | $null = $Parameters.AppendFormat(@' 1749 | [Parameter()] 1750 | [Object[]]${{{0}}}, 1751 | 1752 | '@, $p.Name) 1753 | } 1754 | } 1755 | } 1756 | } 1757 | $null = $Parameters.Append(' [Parameter(ValueFromRemainingArguments=$true)] 1758 | [string[]]$DependencyProps 1759 | )') 1760 | $null = $PropertyNames.Remove(2,1).Append(')') 1761 | 1762 | $collectable = [bool]$(@(foreach($p in @($Pipelineable)){$p.IsCollection}) -contains $true) 1763 | $ofs = "`n"; 1764 | 1765 | $function = $( 1766 | " 1767 | if(!( '$TypeName' -as [Type] )) { 1768 | $( 1769 | if( $T.Assembly.GlobalAssemblyCache ) { 1770 | " `$null = [Reflection.Assembly]::Load( '$($T.Assembly.FullName)' ) " 1771 | } else { 1772 | " `$null = [Reflection.Assembly]::LoadFrom( '$($T.Assembly.Location)' ) " 1773 | } 1774 | ) 1775 | } 1776 | ## if(`$ExecutionContext.SessionState.Module.Guid -ne (Get-ReflectionModule).Guid) { 1777 | ## Write-Warning `"$($T.Name) not invoked in ReflectionModule context. Attempting to reinvoke.`" 1778 | ## # `$scriptParam = `$PSBoundParameters 1779 | ## # return iex `"& (Get-ReflectionModule) '`$(`$MyInvocation.MyCommand.Path)' ```@PSBoundParameters`" 1780 | ## } 1781 | Write-Verbose ""$($T.Name) in module `$(`$executioncontext.sessionstate.module) context!"" 1782 | 1783 | function New-$TypeName { 1784 | <# 1785 | .Synopsis 1786 | Create a new $($T.Name) object 1787 | .Description 1788 | Generates a new $TypeName object, and allows setting all of it's properties. 1789 | (From the $($T.Assembly.GetName().Name) assembly v$($T.Assembly.GetName().Version)) 1790 | .Notes 1791 | GENERATOR : $((Get-ReflectionModule).Name) v$((Get-ReflectionModule).Version) by Joel Bennett http://HuddledMasses.org 1792 | GENERATED : $(Get-Date) 1793 | ASSEMBLY : $($T.Assembly.FullName) 1794 | FULLPATH : $($T.Assembly.Location) 1795 | #> 1796 | 1797 | $Parameters 1798 | BEGIN { 1799 | `$DObject = New-Object $TypeName 1800 | `$All = $PropertyNames 1801 | } 1802 | PROCESS { 1803 | " 1804 | if(!$collectable) { 1805 | " 1806 | # The content of $TypeName is not a collection 1807 | # So if we're in a pipeline, make a new $($T.Name) each time 1808 | if(`$_) { 1809 | `$DObject = New-Object $TypeName 1810 | } 1811 | " 1812 | } 1813 | @' 1814 | foreach($key in @($PSBoundParameters.Keys) | where { $PSBoundParameters[$_] -is [ScriptBlock] }) { 1815 | $PSBoundParameters[$key] = $PSBoundParameters[$key].GetNewClosure() 1816 | } 1817 | Set-ObjectProperties @($PSBoundParameters.GetEnumerator() | Where { [Array]::BinarySearch($All,($_.Key -replace "^On_(.*)",'$1__')) -ge 0 } ) ([ref]$DObject) 1818 | '@ 1819 | 1820 | if(!$collectable) { 1821 | @' 1822 | Microsoft.PowerShell.Utility\Write-Output $DObject 1823 | } #Process 1824 | '@ 1825 | } else { 1826 | @' 1827 | } #Process 1828 | END { 1829 | Microsoft.PowerShell.Utility\Write-Output $DObject 1830 | } 1831 | '@ 1832 | } 1833 | @" 1834 | } 1835 | ## New-$TypeName `@PSBoundParameters 1836 | "@ 1837 | ) 1838 | 1839 | Set-Content -Path $ScriptPath -Value $Function 1840 | } 1841 | 1842 | # Note: set the aliases global for now, because it's too late to export them 1843 | # E.g.: New-Button = New-System.Windows.Controls.Button 1844 | Set-Alias -Name "New-$($T.Name)" "New-$TypeName" -ErrorAction SilentlyContinue -ErrorVariable +ErrorList -Scope Global -Passthru:(!$Quiet) 1845 | if($ShortAliases) { 1846 | # E.g.: Button = New-System.Windows.Controls.Button 1847 | Set-Alias -Name $T.Name "New-$TypeName" -ErrorAction SilentlyContinue -ErrorVariable +ErrorList -Scope Global -Passthru:(!$Quiet) 1848 | } 1849 | 1850 | New-AutoLoad -Name $ScriptPath -Alias "New-$TypeName" 1851 | } 1852 | }#PROCESS 1853 | } 1854 | 1855 | function Import-ConstructorFunctions { 1856 | #.Synopsis 1857 | # Autoload pre-generated constructor functions and generate aliases for them. 1858 | #.Description 1859 | # Parses the New-* scripts in the specified path, and uses the Autoload module to pre-load them as commands and set up aliases for them, without parsing them into memory. 1860 | #.Parameter Path 1861 | # The path to a folder with functions to preload 1862 | param( 1863 | [Parameter()] 1864 | [Alias("PSPath")] 1865 | [string[]]$Path = "$PSScriptRoot\Types_Generated" 1866 | ) 1867 | end { 1868 | $Paths = $(foreach($p in $Path) { Join-Path $p "New-*.ps1" }) 1869 | Write-Verbose "Importing Constructors from: `n`t$($Paths -join "`n`t")" 1870 | 1871 | foreach($script in Get-ChildItem $Paths -ErrorAction 0) { 1872 | $TypeName = $script.Name -replace 'New-(.*).ps1','$1' 1873 | $ShortName = ($TypeName -split '\.')[-1] 1874 | Write-Verbose "Importing constructor for type: $TypeName ($ShortName)" 1875 | 1876 | # Note: set the aliases global for now, because it's too late to export them 1877 | # E.g.: New-Button = New-System.Windows.Controls.Button 1878 | Set-Alias -Name "New-$ShortName" "New-$TypeName" -ErrorAction SilentlyContinue -ErrorVariable +ErrorList -Scope Global -Passthru:(!$Quiet) 1879 | if($ShortAliases) { 1880 | # E.g.: Button = New-System.Windows.Controls.Button 1881 | Set-Alias -Name $ShortName "New-$TypeName" -ErrorAction SilentlyContinue -ErrorVariable +ErrorList -Scope Global -Passthru:(!$Quiet) 1882 | } 1883 | 1884 | New-Autoload -Name $Script.FullName -Alias "New-$TypeName" 1885 | # Write-Host -fore yellow $(Get-Command "New-$TypeName" | Out-String) 1886 | Get-Command "New-$TypeName" 1887 | } 1888 | } 1889 | } 1890 | 1891 | function New-ModuleManifestFromSnapin { 1892 | #.Parameter Snapin 1893 | # The full path to where the snapin .dll is 1894 | #.Parameter OutputPath 1895 | # Force the module manifest(s) to output in a different location than where the snapin .dll is 1896 | #.Parameter ModuleName 1897 | # Override the snapin name(s) for the module manifest 1898 | #.Parameter Author 1899 | # Overrides the Company Name from the manifest when generating the module's "Author" comment 1900 | #.Parameter Passthru 1901 | # Returns the ModuleManifest (same as -Passthru on New-ModuleManifest) 1902 | #.Example 1903 | # New-ModuleManifestFromSnapin ".\Quest Software\Management Shell for AD" -ModuleName QAD 1904 | # 1905 | # Description 1906 | # ----------- 1907 | # Generates a new module manifest file: QAD.psd1 in the folder next to the Quest.ActiveRoles.ArsPowerShellSnapIn.dll 1908 | #.Example 1909 | # New-ModuleManifestFromSnapin "C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\" -Output $pwd 1910 | # 1911 | # Description 1912 | # ----------- 1913 | # Generates module manifest files for the SqlServer PSSnapins and stores them in the current folder 1914 | param( 1915 | [Parameter(Mandatory=$true, Position="0", ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] 1916 | [Alias("FullName")] 1917 | [String[]]$Snapin, 1918 | 1919 | [Parameter()] 1920 | $OutputPath, 1921 | 1922 | [Parameter()] 1923 | $ModuleName, 1924 | 1925 | [Parameter()] 1926 | [String]$Author, 1927 | 1928 | [Switch]$Passthru 1929 | ) 1930 | 1931 | # $SnapinPath = $(Get-ChildItem $SnapinPath -Filter *.dll) 1932 | $EAP = $ErrorActionPreference 1933 | $ErrorActionPreference = "SilentlyContinue" 1934 | Add-Assembly $Snapin 1935 | $ErrorActionPreference = $EAP 1936 | 1937 | $SnapinTypes = Get-Assembly $Snapin | Get-Type -BaseType System.Management.Automation.PSSnapIn, System.Management.Automation.CustomPSSnapIn -WarningAction SilentlyContinue 1938 | 1939 | 1940 | foreach($SnapinType in $SnapinTypes) { 1941 | $Installer = New-Object $SnapinType 1942 | 1943 | if(!$PSBoundParameters.ContainsKey("OutputPath")) { 1944 | $OutputPath = (Split-Path $SnapinType.Assembly.Location) 1945 | } 1946 | 1947 | if(!$PSBoundParameters.ContainsKey("ModuleName")) { 1948 | $ModuleName = $Installer.Vendor 1949 | } 1950 | if(!$PSBoundParameters.ContainsKey("Author")) { 1951 | $Author = $Installer.Name 1952 | } 1953 | $ManifestPath = (Join-Path $OutputPath "$ModuleName.psd1") 1954 | 1955 | Write-Verbose "Creating Module Manifest: $ManifestPath" 1956 | 1957 | $RequiredAssemblies = @( $SnapinType.Assembly.GetReferencedAssemblies() | Get-Assembly | Where-Object { (Split-Path $_.Location) -eq (Split-Path $SnapinType.Assembly.Location) } | Select-Object -Expand Location | Resolve-Path -ErrorAction Continue) 1958 | 1959 | # New-ModuleManifest has a bad bug -- it makes paths relative to the current location (and it does it wrong). 1960 | Push-Location $OutputPath 1961 | 1962 | if($Installer -is [System.Management.Automation.CustomPSSnapIn]) { 1963 | $Cmdlets = $Installer.Cmdlets | Select-Object -Expand Name 1964 | $Types = $Installer.Types | Select-Object -Expand FileName | %{ $path = Resolve-Path $_ -ErrorAction Continue; if(!$path){ $_ } else { $path } } 1965 | $Formats = $Installer.Formats | Select-Object -Expand FileName | %{ $path = Resolve-Path $_ -ErrorAction Continue; if(!$path){ $_ } else { $path } } 1966 | } else { 1967 | $Types = $Installer.Types | %{ $path = Resolve-Path $_ -ErrorAction Continue; if(!$path){ $_ } else { $path } } 1968 | $Formats = $Installer.Formats | %{ $path = Resolve-Path $_ -ErrorAction Continue; if(!$path){ $_ } else { $path } } 1969 | } 1970 | if(!$Cmdlets) { $Cmdlets = "*" } 1971 | if(!$Types) { $Types = @() } 1972 | if(!$Formats) { $Formats = @() } 1973 | 1974 | New-ModuleManifest -Path $ManifestPath -Author $Author -Company $Installer.Vendor -Description $Installer.Description ` 1975 | -ModuleToProcess $SnapinType.Assembly.Location -Types $Types -Formats $Formats -Cmdlets $Cmdlets ` 1976 | -RequiredAssemblies $RequiredAssemblies -Passthru:$Passthru ` 1977 | -NestedModules @() -Copyright $Installer.Vendor -FileList @() 1978 | Pop-Location 1979 | } 1980 | } 1981 | 1982 | Set-Alias aasm Add-Assembly 1983 | Set-Alias gt Get-Type 1984 | Set-Alias gasm Get-Assembly 1985 | Set-Alias gctor Get-Constructor 1986 | 1987 | Update-TypeData -MemberType ScriptProperty -MemberName TokenType -Value { $this.GetType().FullName } -TypeName System.Management.Automation.Language.Ast -ErrorAction SilentlyContinue 1988 | # SIG # Begin signature block 1989 | # MIIXxAYJKoZIhvcNAQcCoIIXtTCCF7ECAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB 1990 | # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR 1991 | # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUmu3qJ4SrrX7WRYIiQZLH8y1P 1992 | # JA+gghL3MIID7jCCA1egAwIBAgIQfpPr+3zGTlnqS5p31Ab8OzANBgkqhkiG9w0B 1993 | # AQUFADCBizELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIG 1994 | # A1UEBxMLRHVyYmFudmlsbGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhh 1995 | # d3RlIENlcnRpZmljYXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcg 1996 | # Q0EwHhcNMTIxMjIxMDAwMDAwWhcNMjAxMjMwMjM1OTU5WjBeMQswCQYDVQQGEwJV 1997 | # UzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xMDAuBgNVBAMTJ1N5bWFu 1998 | # dGVjIFRpbWUgU3RhbXBpbmcgU2VydmljZXMgQ0EgLSBHMjCCASIwDQYJKoZIhvcN 1999 | # AQEBBQADggEPADCCAQoCggEBALGss0lUS5ccEgrYJXmRIlcqb9y4JsRDc2vCvy5Q 2000 | # WvsUwnaOQwElQ7Sh4kX06Ld7w3TMIte0lAAC903tv7S3RCRrzV9FO9FEzkMScxeC 2001 | # i2m0K8uZHqxyGyZNcR+xMd37UWECU6aq9UksBXhFpS+JzueZ5/6M4lc/PcaS3Er4 2002 | # ezPkeQr78HWIQZz/xQNRmarXbJ+TaYdlKYOFwmAUxMjJOxTawIHwHw103pIiq8r3 2003 | # +3R8J+b3Sht/p8OeLa6K6qbmqicWfWH3mHERvOJQoUvlXfrlDqcsn6plINPYlujI 2004 | # fKVOSET/GeJEB5IL12iEgF1qeGRFzWBGflTBE3zFefHJwXECAwEAAaOB+jCB9zAd 2005 | # BgNVHQ4EFgQUX5r1blzMzHSa1N197z/b7EyALt0wMgYIKwYBBQUHAQEEJjAkMCIG 2006 | # CCsGAQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMBIGA1UdEwEB/wQIMAYB 2007 | # Af8CAQAwPwYDVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NybC50aGF3dGUuY29tL1Ro 2008 | # YXd0ZVRpbWVzdGFtcGluZ0NBLmNybDATBgNVHSUEDDAKBggrBgEFBQcDCDAOBgNV 2009 | # HQ8BAf8EBAMCAQYwKAYDVR0RBCEwH6QdMBsxGTAXBgNVBAMTEFRpbWVTdGFtcC0y 2010 | # MDQ4LTEwDQYJKoZIhvcNAQEFBQADgYEAAwmbj3nvf1kwqu9otfrjCR27T4IGXTdf 2011 | # plKfFo3qHJIJRG71betYfDDo+WmNI3MLEm9Hqa45EfgqsZuwGsOO61mWAK3ODE2y 2012 | # 0DGmCFwqevzieh1XTKhlGOl5QGIllm7HxzdqgyEIjkHq3dlXPx13SYcqFgZepjhq 2013 | # IhKjURmDfrYwggSjMIIDi6ADAgECAhAOz/Q4yP6/NW4E2GqYGxpQMA0GCSqGSIb3 2014 | # DQEBBQUAMF4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3Jh 2015 | # dGlvbjEwMC4GA1UEAxMnU3ltYW50ZWMgVGltZSBTdGFtcGluZyBTZXJ2aWNlcyBD 2016 | # QSAtIEcyMB4XDTEyMTAxODAwMDAwMFoXDTIwMTIyOTIzNTk1OVowYjELMAkGA1UE 2017 | # BhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMTQwMgYDVQQDEytT 2018 | # eW1hbnRlYyBUaW1lIFN0YW1waW5nIFNlcnZpY2VzIFNpZ25lciAtIEc0MIIBIjAN 2019 | # BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAomMLOUS4uyOnREm7Dv+h8GEKU5Ow 2020 | # mNutLA9KxW7/hjxTVQ8VzgQ/K/2plpbZvmF5C1vJTIZ25eBDSyKV7sIrQ8Gf2Gi0 2021 | # jkBP7oU4uRHFI/JkWPAVMm9OV6GuiKQC1yoezUvh3WPVF4kyW7BemVqonShQDhfu 2022 | # ltthO0VRHc8SVguSR/yrrvZmPUescHLnkudfzRC5xINklBm9JYDh6NIipdC6Anqh 2023 | # d5NbZcPuF3S8QYYq3AhMjJKMkS2ed0QfaNaodHfbDlsyi1aLM73ZY8hJnTrFxeoz 2024 | # C9Lxoxv0i77Zs1eLO94Ep3oisiSuLsdwxb5OgyYI+wu9qU+ZCOEQKHKqzQIDAQAB 2025 | # o4IBVzCCAVMwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAO 2026 | # BgNVHQ8BAf8EBAMCB4AwcwYIKwYBBQUHAQEEZzBlMCoGCCsGAQUFBzABhh5odHRw 2027 | # Oi8vdHMtb2NzcC53cy5zeW1hbnRlYy5jb20wNwYIKwYBBQUHMAKGK2h0dHA6Ly90 2028 | # cy1haWEud3Muc3ltYW50ZWMuY29tL3Rzcy1jYS1nMi5jZXIwPAYDVR0fBDUwMzAx 2029 | # oC+gLYYraHR0cDovL3RzLWNybC53cy5zeW1hbnRlYy5jb20vdHNzLWNhLWcyLmNy 2030 | # bDAoBgNVHREEITAfpB0wGzEZMBcGA1UEAxMQVGltZVN0YW1wLTIwNDgtMjAdBgNV 2031 | # HQ4EFgQURsZpow5KFB7VTNpSYxc/Xja8DeYwHwYDVR0jBBgwFoAUX5r1blzMzHSa 2032 | # 1N197z/b7EyALt0wDQYJKoZIhvcNAQEFBQADggEBAHg7tJEqAEzwj2IwN3ijhCcH 2033 | # bxiy3iXcoNSUA6qGTiWfmkADHN3O43nLIWgG2rYytG2/9CwmYzPkSWRtDebDZw73 2034 | # BaQ1bHyJFsbpst+y6d0gxnEPzZV03LZc3r03H0N45ni1zSgEIKOq8UvEiCmRDoDR 2035 | # EfzdXHZuT14ORUZBbg2w6jiasTraCXEQ/Bx5tIB7rGn0/Zy2DBYr8X9bCT2bW+IW 2036 | # yhOBbQAuOA2oKY8s4bL0WqkBrxWcLC9JG9siu8P+eJRRw4axgohd8D20UaF5Mysu 2037 | # e7ncIAkTcetqGVvP6KUwVyyJST+5z3/Jvz4iaGNTmr1pdKzFHTx/kuDDvBzYBHUw 2038 | # ggUmMIIEDqADAgECAhACXbrxBhFj1/jVxh2rtd9BMA0GCSqGSIb3DQEBCwUAMHIx 2039 | # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 2040 | # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ 2041 | # RCBDb2RlIFNpZ25pbmcgQ0EwHhcNMTUwNTA0MDAwMDAwWhcNMTYwNTExMTIwMDAw 2042 | # WjBtMQswCQYDVQQGEwJVUzERMA8GA1UECBMITmV3IFlvcmsxFzAVBgNVBAcTDldl 2043 | # c3QgSGVucmlldHRhMRgwFgYDVQQKEw9Kb2VsIEguIEJlbm5ldHQxGDAWBgNVBAMT 2044 | # D0pvZWwgSC4gQmVubmV0dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB 2045 | # AJfRKhfiDjMovUELYgagznWf+HFcDENk118Y/K6UkQDwKmVyVOvDyaVefjSmZZcV 2046 | # NZqqYpm9d/Iajf2dauyC3pg3oay8KfXAADLHgbmbvYDc5zGuUNsTzMUOKlp9h13c 2047 | # qsg898JwpRpI659xCQgJjZ6V83QJh+wnHvjA9ojjA4xkbwhGp4Eit6B/uGthEA11 2048 | # IHcFcXeNI3fIkbwWiAw7ZoFtSLm688NFhxwm+JH3Xwj0HxuezsmU0Yc/po31CoST 2049 | # nGPVN8wppHYZ0GfPwuNK4TwaI0FEXxwdwB+mEduxa5e4zB8DyUZByFW338XkGfc1 2050 | # qcJJ+WTyNKFN7saevhwp02cCAwEAAaOCAbswggG3MB8GA1UdIwQYMBaAFFrEuXsq 2051 | # CqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBQV0aryV1RTeVOG+wlr2Z2bOVFAbTAO 2052 | # BgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwdwYDVR0fBHAwbjA1 2053 | # oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJlZC1jcy1n 2054 | # MS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEyLWFzc3Vy 2055 | # ZWQtY3MtZzEuY3JsMEIGA1UdIAQ7MDkwNwYJYIZIAYb9bAMBMCowKAYIKwYBBQUH 2056 | # AgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgYQGCCsGAQUFBwEBBHgw 2057 | # djAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tME4GCCsGAQUF 2058 | # BzAChkJodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEyQXNz 2059 | # dXJlZElEQ29kZVNpZ25pbmdDQS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0B 2060 | # AQsFAAOCAQEAIi5p+6eRu6bMOSwJt9HSBkGbaPZlqKkMd4e6AyKIqCRabyjLISwd 2061 | # i32p8AT7r2oOubFy+R1LmbBMaPXORLLO9N88qxmJfwFSd+ZzfALevANdbGNp9+6A 2062 | # khe3PiR0+eL8ZM5gPJv26OvpYaRebJTfU++T1sS5dYaPAztMNsDzY3krc92O27AS 2063 | # WjTjWeILSryqRHXyj8KQbYyWpnG2gWRibjXi5ofL+BHyJQRET5pZbERvl2l9Bo4Z 2064 | # st8CM9EQDrdG2vhELNiA6jwenxNPOa6tPkgf8cH8qpGRBVr9yuTMSHS1p9Rc+ybx 2065 | # FSKiZkOw8iCR6ZQIeKkSVdwFf8V+HHPrETCCBTAwggQYoAMCAQICEAQJGBtf1btm 2066 | # dVNDtW+VUAgwDQYJKoZIhvcNAQELBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoT 2067 | # DERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UE 2068 | # AxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoX 2069 | # DTI4MTAyMjEyMDAwMFowcjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0 2070 | # IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNl 2071 | # cnQgU0hBMiBBc3N1cmVkIElEIENvZGUgU2lnbmluZyBDQTCCASIwDQYJKoZIhvcN 2072 | # AQEBBQADggEPADCCAQoCggEBAPjTsxx/DhGvZ3cH0wsxSRnP0PtFmbE620T1f+Wo 2073 | # ndsy13Hqdp0FLreP+pJDwKX5idQ3Gde2qvCchqXYJawOeSg6funRZ9PG+yknx9N7 2074 | # I5TkkSOWkHeC+aGEI2YSVDNQdLEoJrskacLCUvIUZ4qJRdQtoaPpiCwgla4cSocI 2075 | # 3wz14k1gGL6qxLKucDFmM3E+rHCiq85/6XzLkqHlOzEcz+ryCuRXu0q16XTmK/5s 2076 | # y350OTYNkO/ktU6kqepqCquE86xnTrXE94zRICUj6whkPlKWwfIPEvTFjg/Bougs 2077 | # UfdzvL2FsWKDc0GCB+Q4i2pzINAPZHM8np+mM6n9Gd8lk9ECAwEAAaOCAc0wggHJ 2078 | # MBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoG 2079 | # CCsGAQUFBwMDMHkGCCsGAQUFBwEBBG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29j 2080 | # c3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdp 2081 | # Y2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3J0MIGBBgNVHR8EejB4 2082 | # MDqgOKA2hjRodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVk 2083 | # SURSb290Q0EuY3JsMDqgOKA2hjRodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGln 2084 | # aUNlcnRBc3N1cmVkSURSb290Q0EuY3JsME8GA1UdIARIMEYwOAYKYIZIAYb9bAAC 2085 | # BDAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAoG 2086 | # CGCGSAGG/WwDMB0GA1UdDgQWBBRaxLl7KgqjpepxA8Bg+S32ZXUOWDAfBgNVHSME 2087 | # GDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkqhkiG9w0BAQsFAAOCAQEAPuwN 2088 | # WiSz8yLRFcgsfCUpdqgdXRwtOhrE7zBh134LYP3DPQ/Er4v97yrfIFU3sOH20ZJ1 2089 | # D1G0bqWOWuJeJIFOEKTuP3GOYw4TS63XX0R58zYUBor3nEZOXP+QsRsHDpEV+7qv 2090 | # tVHCjSSuJMbHJyqhKSgaOnEoAjwukaPAJRHinBRHoXpoaK+bp1wgXNlxsQyPu6j4 2091 | # xRJon89Ay0BEpRPw5mQMJQhCMrI2iiQC/i9yfhzXSUWW6Fkd6fp0ZGuy62ZD2rOw 2092 | # jNXpDd32ASDOmTFjPQgaGLOBm0/GkxAG/AeB+ova+YJJ92JuoVP6EpQYhS6Skepo 2093 | # bEQysmah5xikmmRR7zGCBDcwggQzAgEBMIGGMHIxCzAJBgNVBAYTAlVTMRUwEwYD 2094 | # VQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAv 2095 | # BgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EC 2096 | # EAJduvEGEWPX+NXGHau130EwCQYFKw4DAhoFAKB4MBgGCisGAQQBgjcCAQwxCjAI 2097 | # oAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIB 2098 | # CzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFMvvD7Gblea5voZ1g846 2099 | # bz3CIS+0MA0GCSqGSIb3DQEBAQUABIIBAAymsrpFiNkt3wB8QHtOvMyDfAbf9kls 2100 | # m8p6GqtiXpNPS996KhQfnHQbyl/uAzdZ2cSrQhDhndw9Yu372DOPNPCWLRGxSD8l 2101 | # wbRa2jxU991+ETgGRb/HeIX2unrko/2sNAAsVodaccvjS0ficPnnsc20xaFaD8Wi 2102 | # KZ0Sd4yGHWv2fuPMTu2SyKspF0dZmcfwtKCuzQb3J21mNZtES2TpQD93T1hAlrPD 2103 | # pYcCho8NAEFXjQ9Aby7rXoo7pMtIQkqxcca7NAY61XgkwpgikUqnAhmoTzXRCWFG 2104 | # N8qfHf9HFwJYikAqA0aGmex8irLUubzmcrcM5ylgE5/haXpyEQRBGc6hggILMIIC 2105 | # BwYJKoZIhvcNAQkGMYIB+DCCAfQCAQEwcjBeMQswCQYDVQQGEwJVUzEdMBsGA1UE 2106 | # ChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xMDAuBgNVBAMTJ1N5bWFudGVjIFRpbWUg 2107 | # U3RhbXBpbmcgU2VydmljZXMgQ0EgLSBHMgIQDs/0OMj+vzVuBNhqmBsaUDAJBgUr 2108 | # DgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUx 2109 | # DxcNMTUwNTA3MjIwMDAzWjAjBgkqhkiG9w0BCQQxFgQUTMK4qc2eubVgP3StzIV8 2110 | # vNAQ7dswDQYJKoZIhvcNAQEBBQAEggEAQzYcp1wNIkO0sQwxnOfKrVn5ZXZrR0n8 2111 | # Kp4LjR3VYKERTUsDNHCwNZwi8OTOnYejin4A/trSCyoNh5z/l+spYvJuZblU8qt0 2112 | # p0R4DUcxS2ek/bVWmOmzdZhu76eUM3kD28nOcgOpcvVIT2syNtnwb6J2M5qKdIVi 2113 | # /0aHAuMe/39yRwytg6rQuPdLwhAB8uPe1tlXiqjNh27ume6CH9uGC1YCP6Iy4Egy 2114 | # Gy7EDp/uAN6qyGR8ssVkRoD91WCTtpRn36A4rXDqxlDmCpZ/VIfb4Wlsek6Za1OW 2115 | # 0s5RjzqbqUnT5u+pHSLeMwRGAUlXxy1qVLnlJMVXfW7cQKl1h7GEGg== 2116 | # SIG # End signature block 2117 | -------------------------------------------------------------------------------- /ReleaseNotes.md: -------------------------------------------------------------------------------- 1 | ## Release Notes 2 | 3 | #### 4.8 _May 5, 2015_ 4 | Trying to work around the PowerShellGallery limitations 5 | Refactored some functions into nested modules 6 | 7 | #### 4.7 _May 8, 2014_ 8 | Added Test-RestrictedLanguage and Get-ParseResults 9 | 10 | #### 4.6 _April 28, 2014_ 11 | Updated Read-Choice again with better choicing ;) 12 | 13 | #### 4.5 _March 2, 2013_ 14 | Added Test-AssignableToGeneric and Get-ExtensionMethod 15 | Updated Read-Choice from the standalone script I use. 16 | 17 | #### 4.2 18 | Added Add-Enum and Add-Struct 19 | 20 | #### 4.1 _Oct 27, 2011_ 21 | Fix PowerShell 3 changes so they don't break PowerShell 2 (huy!) 22 | 23 | #### 4.0 _Sept 27, 2011_ 24 | Fix conflicts with PowerShell 3 25 | 26 | #### 3.9 _May 25, 2011_ 27 | Added "Interface" parameter to Get-Type 28 | 29 | #### 3.8 _May 4, 2011_ 30 | Huge rewrite of Invoke-Generic (also published separately: http://poshcode.org/2649) 31 | 32 | #### 3.7 _February 1, 2001_ 33 | Added [TransformAttribute] type 34 | 35 | #### 3.6 _January 28, 2011_ 36 | Added *basic* support for CustomPSSnapin to New-ModuleManifestFromSnapin 37 | 38 | #### 3.5 _January 28, 2011_ 39 | Fixed several bugs in Add-Assembly, Get-Assembly, Get-MemberSignature 40 | Fixed alias exporting so aliases will show up now 41 | Added New-ModuleManifestFromSnapin to create module manifests from snapin assemblies 42 | 43 | #### 3.0 _September 3, 2010_ 44 | Included the New-ConstructorFunction feature (ripped from PowerBoots to serve a more generic and powerful purpose!) 45 | New-ConstructorFunction and Import-ConstructorFunctions depend on the Autoload Module: http://poshcode.org/2312 46 | 47 | #### 2.0 48 | Included the Accelerator function inline 49 | Added a few default aliases 50 | 51 | #### 1.0 _March 19, 2010_ 52 | First public releasema 53 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. 2 | 3 | 1. Definitions 4 | The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. 5 | A "contribution" is the original software, or any additions or changes to the software. 6 | A "contributor" is any person that distributes its contribution under this license. 7 | "Licensed patents" are a contributor's patent claims that read directly on its contribution. 8 | 9 | 2. Grant of Rights 10 | (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. 11 | (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 12 | 13 | 3. Conditions and Limitations 14 | (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. 15 | (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. 16 | (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. 17 | (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. 18 | (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. 19 | --------------------------------------------------------------------------------