diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 83b30ed587f..441c1ed6229 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -4,7 +4,7 @@ # First Lets start with areas with no filters or paths # Area: Performance -# @lzybkr @adityapatwardhan +# @adityapatwardhan # Area: Portability # @BrucePay @JamesWTruher @@ -13,7 +13,7 @@ # @TravisEz13 @PaulHigin # Area: Documentation -# @joeyaiello @TravisEz13 +.github/ @joeyaiello @TravisEz13 # Area: Test # @JamesWTruher @TravisEz13 @adityapatwardhan @@ -32,7 +32,7 @@ src/Microsoft.PowerShell.Commands.Management/ @daxian-dbw @adityapatwardhan src/Microsoft.PowerShell.Commands.Utility/ @JamesWTruher @dantraMSFT @PaulHigin # Area: Console -src/Microsoft.PowerShell.ConsoleHost/ @daxian-dbw @lzybkr @anmenaga +src/Microsoft.PowerShell.ConsoleHost/ @daxian-dbw @anmenaga # Area: Demo demos/ @joeyaiello @SteveL-MSFT @HemantMahawar @@ -41,7 +41,7 @@ demos/ @joeyaiello @SteveL-MSFT @Hem src/System.Management.Automation/DscSupport @TravisEz13 @dantraMSFT # Area: engine -src/System.Management.Automation/engine @daxian-dbw @vors @lzybkr @BrucePay +src/System.Management.Automation/engine @daxian-dbw @BrucePay # Area: Debugging # Must be below engine to override @@ -51,16 +51,16 @@ src/System.Management.Automation/engine/debugger/ @BrucePay @dantraMSFT @PaulHi src/System.Management.Automation/help @Francisco-Gamino @adityapatwardhan # Area: Intellisense -# @daxian-dbw @lzybkr @charub +# @daxian-dbw @charub # Area: Language -# @daxian-dbw @vors @lzybkr @BrucePay +src/System.Management.Automation/engine/parser @daxian-dbw @vors @BrucePay # Area: Providers src/System.Management.Automation/namespaces @BrucePay @anmenaga # Area: PSReadLine -src/Microsoft.PowerShell.PSReadLine @lzybkr @charub +src/Microsoft.PowerShell.PSReadLine @charub # Area: Remoting src/System.Management.Automation/engine/remoting @dantraMSFT @mirichmo @PaulHigin @@ -77,3 +77,7 @@ src/System.Management.Automation/engine/remoting @dantraMSFT @mirichmo @PaulHi build.* @daxian-dbw @TravisEz13 @adityapatwardhan tools/ @daxian-dbw @TravisEz13 @adityapatwardhan docker/ @daxian-dbw @TravisEz13 @adityapatwardhan + +# Area: Compliance +tools/terms @TravisEz13 +tools/credScan @TravisEz13 diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index a7491ea8bd9..498fe0f26cd 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -98,6 +98,8 @@ Additional references: #### Before submitting +* If your change would fix a security vulnerability, + first follow the [vulnerability issue reporting policy][vuln-reporting], before submitting a PR. * To avoid merge conflicts, make sure your branch is rebased on the `master` branch of this repository. * Many code changes will require new tests, so make sure you've added a new test if existing tests do not effectively test the code changed. @@ -109,7 +111,7 @@ Additional references: **Always create a pull request to the `master` branch of this repository**. -![Github-PR-dev.png](Images/Github-PR-dev.png) +![GitHub-PR.png](Images/GitHub-PR.png) * It's recommended to avoid a PR with too many changes. A large PR not only stretches the review time, but also makes it much harder to spot issues. @@ -129,19 +131,6 @@ Additional references: If the changes are related to an existing GitHub issue, please reference the issue in PR description (e.g. ```Fix #11```). See [this][closing-via-message] for more details. -* If the change warrants a note in the [changelog](../CHANGELOG.MD) - either update the changelog in your pull request or - add a comment in the PR description saying that the change may warrant a note in the changelog. - New changes always go into the **Unreleased** section. - Keeping the changelog up-to-date simplifies the release process for Maintainers. - An example (with an associated PR #): - - ```markdown - Unreleased - ---------- - - * `Update-Item` now supports `-FriendlyName` (#1234). - ``` * Please use the present tense and imperative mood when describing your changes: * Instead of "Adding support for Windows Server 2012 R2", write "Add support for Windows Server 2012 R2". @@ -160,6 +149,29 @@ Additional references: While not required, we appreciate any contributors who add this label and create the issue themselves. Even better, all contributors are free to contribute the documentation themselves. (See [Contributing to documentation related to PowerShell](#contributing-to-documentation-related-to-powershell) for more info.) +* If your change adds a new source file, ensure the appropriate copyright and license headers is on top. + It is standard practice to have both a copyright and license notice for each source file. + * For `.h`, `.cpp`, and `.cs` files use: + + // Copyright (c) Microsoft Corporation. All rights reserved. + // Licensed under the MIT License. + + * For `.ps1` and `.psm1` files use: + + # Copyright (c) Microsoft Corporation. All rights reserved. + # Licensed under the MIT License. + +* If your change adds a new module manifest (.psd1 file), ensure that: + + ```powershell + Author = "PowerShell" + Company = "Microsoft Corporation" + Copyright = "Copyright (c) Microsoft Corporation. All rights reserved." + ``` + +### Pull Request - Work in Progress + +* If your pull request is not ready to merge, please add the prefix `WIP:` to the beginning of the title and remove the prefix when the PR is ready. #### Pull Request - Automatic Checks @@ -308,6 +320,7 @@ Once you sign a CLA, all your existing and future pull requests will be labeled [testing-guidelines]: ../docs/testing-guidelines/testing-guidelines.md [running-tests-outside-of-ci]: ../docs/testing-guidelines/testing-guidelines.md#running-tests-outside-of-ci [issue-management]: ../docs/maintainers/issue-management.md +[vuln-reporting]: ../docs/maintainers/issue-management.md#Security-Vulnerabilities [governance]: ../docs/community/governance.md [using-prs]: https://help.github.com/articles/using-pull-requests/ [fork-a-repo]: https://help.github.com/articles/fork-a-repo/ diff --git a/.github/Images/Github-PR-dev.png b/.github/Images/GitHub-PR.png similarity index 100% rename from .github/Images/Github-PR-dev.png rename to .github/Images/GitHub-PR.png diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 684606536ec..cab42706164 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,8 +1,23 @@ - -For more information about the roles of Reviewer and Assignee, refer to [CONTRIBUTING.md](https://github.com/PowerShell/PowerShell/blob/master/.github/CONTRIBUTING.md). +## PR Checklist ---> +- [ ] [PR has a meaningful title](https://github.com/PowerShell/PowerShell/blob/master/.github/CONTRIBUTING.md#pull-request---submission) + - Use the present tense and imperative mood when describing your changes +- [ ] [Summarized changes](https://github.com/PowerShell/PowerShell/blob/master/.github/CONTRIBUTING.md#pull-request---submission) +- [ ] [Change is not breaking](https://github.com/PowerShell/PowerShell/blob/master/.github/CONTRIBUTING.md#making-breaking-changes) +- [ ] [Make sure all `.h`, `.cpp`, `.cs`, `.ps1` and `.psm1` files have the correct copyright header](https://github.com/PowerShell/PowerShell/blob/master/.github/CONTRIBUTING.md#pull-request---submission) +- [ ] This PR is ready to merge and is not [Work in Progress](https://github.com/PowerShell/PowerShell/blob/master/.github/CONTRIBUTING.md#pull-request---work-in-progress). + - If the PR is work in progress, please add the prefix `WIP:` to the beginning of the title and remove the prefix when the PR is ready. +- **User-facing changes** + - [ ] Not Applicable + - **OR** + - [ ] User-facing [Documentation needed](https://github.com/PowerShell/PowerShell/blob/master/.github/CONTRIBUTING.md#pull-request---submission) + - [ ] Issue filed - Issue link: +- **Testing - New and feature** + - [ ] Not Applicable or can only be tested interactively + - **OR** + - [ ] [Make sure you've added a new test if existing tests do not effectively test the code changed](https://github.com/PowerShell/PowerShell/blob/master/.github/CONTRIBUTING.md#before-submitting) + - [ ] [Add `[feature]` if the change is significant or affects feature tests](https://github.com/PowerShell/PowerShell/blob/master/docs/testing-guidelines/testing-guidelines.md#requesting-additional-tests-for-a-pr) diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 00000000000..61dfae5d273 --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,62 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 30 + +# Number of days of inactivity before a stale Issue or Pull Request is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 10 + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - Issue-Meta + - Issue-Discussion + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: true + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Label to use when marking as stale +staleLabel: Review - Abandoned + +# Comment to post when marking as stale. Set to `false` to disable +markComment: > + This PR has been automatically marked as stale because it has not had activity in the last 30 days. + It will be closed if no further activity occurs within 10 days. + + Thank you for your contributions. + + Community members are welcome to grab these works. + +# Comment to post when removing the stale label. +# unmarkComment: > +# Your comment here. + +# Comment to post when closing a stale Issue or Pull Request. +closeComment: > + This PR has be automatically close because it is stale. + If you wish to continue working on the PR, please first update the PR, then reopen it. + + Thanks again for your contribution. + + Community members are welcome to grab these works. + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +# Limit to only `issues` or `pulls` +only: pulls + +# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls': +# pulls: +# daysUntilStale: 30 +# markComment: > +# This pull request has been automatically marked as stale because it has not had +# recent activity. It will be closed if no further activity occurs. Thank you +# for your contributions. + +# issues: +# exemptLabels: +# - confirmed diff --git a/.gitignore b/.gitignore index 089babc3522..4d4e69760b4 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,7 @@ dotnet-uninstall-debian-packages.sh # Ignore binaries and symbols *.pdb *.dll +*.wixpdb # Ignore packages *.deb @@ -43,25 +44,17 @@ dotnet-uninstall-debian-packages.sh *.rpm *.pkg *.nupkg - -# ignore the telemetry semaphore file -DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY +*.AppImage # default location for produced nuget packages /nuget-artifacts -# generated man files -/assets/powershell.1* - # resgen output gen # Per repo profile .profile.ps1 -#VS Code files -.vscode - # macOS .DS_Store @@ -70,4 +63,4 @@ TestsResults*.xml # Resharper settings PowerShell.sln.DotSettings.user - +*.msp diff --git a/.gitmodules b/.gitmodules index 17765f6837c..c677d18caff 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,8 +1,3 @@ -[submodule "src/Modules/Pester"] - path = src/Modules/Shared/Pester - url = https://github.com/PowerShell/psl-pester.git - branch = develop - ignore = dirty [submodule "src/libpsl-native/test/googletest"] path = src/libpsl-native/test/googletest url = https://github.com/google/googletest.git diff --git a/.spelling b/.spelling index 3b415b9aef5..457e028a121 100644 --- a/.spelling +++ b/.spelling @@ -21,10 +21,12 @@ AppImage AppVeyor argumentlist arm32 +arm64 artifact artifacts ASP.NET AssemblyLoadContext +authenticode authenticodesignature behavior behaviors @@ -101,6 +103,7 @@ linux-x64 lockfile macOS md +microsoft Microsoft.PowerShell.Archive microsoft.powershell.commands.diagnostics microsoft.powershell.commands.management @@ -135,6 +138,7 @@ parameterized patwardhan powershell PowerShell +PowerShell.Core.Instrumentation powershell.exe PowerShellGet program.cs @@ -146,7 +150,9 @@ PSObject psobjects psproxyjobs PSReadline +psrp.windows PSSessionConfiguration +pwsh redistributables Register-EngineEvent Register-PSSessionConfiguration @@ -181,6 +187,7 @@ TeamCity thenewstellw throttlelimit toolset +toolchain TraceSource Unregister-Event Unregister-PSSessionConfiguration @@ -199,6 +206,7 @@ writingpestertests.md WSMan wsmansessionoption.cs xUnit +0-powershell-crossplatform #endregion #region ./tools/install-powershell.readme.md Overrides @@ -217,6 +225,8 @@ _Jobs -Include -Title 0xfeeddeadbeef +about_ +about_Jobs acceptance alpha.10 alpha.11 @@ -227,6 +237,7 @@ alpha.16 alpha.17 alpha.18 args +Bhaal22 behavioral bergmeister beta.1 @@ -236,6 +247,7 @@ beta.4 beta.5 beta.6 beta.8 +beta.9 binding bool CDXML @@ -244,6 +256,7 @@ CI cleanup CodeMethod CodeOwner +codepage CommandNotFoundException ContentType ConvertTo-Html @@ -251,11 +264,14 @@ CoreConsoleHost crossgen'ing DarwinJS dchristian3188 +DdWr deserialization deserialize +dlwyatt +dotnet enums -ExecutionPolicy EXE's +ExecutionPolicy FileCatalog FilterHashtable foreach @@ -263,8 +279,10 @@ GetParentProcess GitCommitId globbing HelpersCommon.psm1 +Himura2la honors hostname +IISResetMe IncludeUserName InformationRecord IoT @@ -278,10 +296,13 @@ KeyFileParameter KeyHandler KirkMunro kittholland +kvprasoon kwiknick +kylesferrazza LDSpits Lee303 libpsl-native +libunwind8 LoadFrom markekraus meta @@ -294,10 +315,13 @@ nanoserver-insider non-22 non-CIM non-R2 +OAuth +offthewoll oising oneget.org PetSerAl powercode +PowershellNinja PowerShellProperties preview1-24530-04 ProductVersion @@ -309,9 +333,12 @@ PSScriptAnalyzer PSVersion PVS-Studio Pwrshplughin.dll +raghav710 +Raspbian +rc +rc.2 rc2-24027 rc3-24011 -Raspbian README.md RelationLink richardszalay @@ -329,14 +356,17 @@ system.manage Tadas TestCase TheFlyingCorpse +thezim TimCurwick timestamp TimeZone TPA Travis +travisty TTY's UserAgent UserData +UserVoice Utf8 UTF8NoBOM v0.1.0 @@ -346,19 +376,50 @@ v0.4.0 v0.5.0 v0.6.0 v6.0.0 +v6.0.1 ValidateNotNullOrEmpty WebListener WebRequest win7-x86 +Windos WindowsVersion WSManCredSSP XPath Youtube +stuntguy3000 +SwarfegaGit +v6.0.2 +diddledan +v6.1.0 +preview.1 +tandasat +kwkam +stknohg +CloudyDino +KevinMarquette +tomconte +DarqueWarrior +Pawamoy +strawgate +CallmeJoeBob +maertendMSFT +seemethere +zackJKnight +brianbunke +timothywlewis +rpalo +kanjibates +kasper3 +ppadmavilasom +Stanzilla +mababio +v4 #endregion #region CODE_OF_CONDUCT.md Overrides - CODE_OF_CONDUCT.md microsoft.com +o opencode #endregion @@ -390,11 +451,8 @@ u #region demos/DSC/readme.md Overrides - demos/DSC/readme.md -#endregion - -#region demos/install/README.md Overrides - - demos/install/README.md -download.sh +www.github.com +omi #endregion #region demos/python/README.md Overrides @@ -403,52 +461,11 @@ _script.ps1 _script.ps1. #endregion -#region demos/Raspberry-Pi/README.md Overrides - - demos/Raspberry-Pi/README.md -2.0.x -2.1.x -Raspbian -toolchain -#endregion - #region demos/rest/README.md Overrides - demos/rest/README.md rest.ps1 #endregion -#region demos/SSHRemoting/README.md Overrides - - demos/SSHRemoting/README.md -_config -2kCbnhT2dUE6WCGgVJ8Hyfu1z2wE4lifaJXLO7QJy0Y -com.openssh.sshd -ComputerName -ComputerType -ConfigurationName -Enter-PSSession -HostName -KeyFilePath -KeyPath -launchctl -New-PSSession -NoLogo -NoProfile -openssh-client -openssh-server -PasswordAuthentication -PSCredential -PSSessions -PubkeyAuthentication -RSAAuthentication -ssh.exe -sshd -sshd.exe -sshs -TestUser -UbuntuVM1 -UbuntuVM1s -usr -#endregion - #region demos/SystemD/readme.md Overrides - demos/SystemD/readme.md Get-SystemDJournal @@ -468,17 +485,37 @@ WindowsPSModulePath andschwa's CurrentUser hub.docker.com -microsoft NanoServer-Insider nanoserver-insider-powershell #endregion +#region docs/BREAKINGCHANGES.md Overrides +- docs/BREAKINGCHANGES.md +7-bit +CoreFX +honored +non-Windows +psd1 +runbooks +runspace +v1 +v2 +WMI-based +#endregion + #region docs/building/internals.md Overrides - docs/building/internals.md Catalog +flavor +libpsl MSBuild +nuget.exe +plugin powershell-unix src +v141 +x64_arm +x64_arm64 #endregion #region docs/building/macos.md Overrides @@ -486,15 +523,33 @@ src preview3 #endregion +#region docs/cmdlet-example/command-line-simple-example.md Overrides +- docs/cmdlet-example/command-line-simple-example.md +aka +classlib +dotnet +netstandard.dll +wsl +#endregion + +#region docs/cmdlet-example/visual-studio-simple-example.md Overrides +- docs/cmdlet-example/visual-studio-simple-example.md +dropdown +v3 +#endregion + #region docs/community/governance.md Overrides - docs/community/governance.md Aiello AngelCalvo BrucePay Calvo +daxian-dbw +Dongbo DON'Ts Hemant HemantMahawar +JamesWTruher joeyaiello jpsnover khansen00 @@ -504,6 +559,7 @@ Payette PRs Snover SteveL-MSFT +Truher #endregion #region docs/debugging/README.md Overrides @@ -581,9 +637,27 @@ sample-dotnet2 #region docs/installation/linux.md Overrides - docs/installation/linux.md +compat-openssl10 +dockerfile +libc6 libcurl +libcurl3 +libgcc1 +libgssapi-krb5-2 +libicu +libicu52 +libicu55 +libicu57 +liblttng-ust0 +libssl1.0.0 +libssl1.0.2 +libstdc +libunwind +libunwind8 +libuuid1 +openssl-libs OpenSUSE -TravisEz13 +zlib1g zypper #endregion @@ -600,6 +674,7 @@ windir - docs/KNOWNISSUES.md cp globbing +New-PSSession pipelining psl-omi-provider Register-WmiEvent @@ -616,6 +691,7 @@ RemoteSigned #region docs/learning-powershell/debugging-from-commandline.md Overrides - docs/learning-powershell/debugging-from-commandline.md _Debuggers +about_Debuggers celsius Set-PSBreakpoint test.ps1 @@ -726,6 +802,7 @@ Enable-RunspaceDebug Enable-WSManCredSSP Enable-WSManTrace Enter-PSHostProcess +Enter-PSSession Exit-PSHostProcess Exit-PSSession Export-BinaryMiLog @@ -791,6 +868,7 @@ New-LocalGroup New-LocalUser New-ModuleManifest New-PSDrive +New-PSSession New-PSRoleCapabilityFile New-PSSessionConfigurationFile New-ScriptFileInfo @@ -867,6 +945,7 @@ TabCompletion #region docs/testing-guidelines/TestRoadmap.md Overrides - docs/testing-guidelines/TestRoadmap.md +_no_ corefx DotCover Downlevel @@ -900,8 +979,10 @@ Gitter microsoft.com msi omnisharp-vscode +o opencode pkg +tgz UserVoice #endregion @@ -918,6 +999,7 @@ libpsl-native _history.txt _PSReadline 50ms +about_PSReadline AddToHistoryHandler AppData BackgroundColor @@ -981,184 +1063,6 @@ psd1 psm1 #endregion -#region src/Modules/Shared/Pester/CHANGELOG.md Overrides - - src/Modules/Shared/Pester/CHANGELOG.md -_be -AfterAll -AfterEach -ArgumentList -Assert-MockCalled -BeExactly -BeforeAll -BeforeEach -BeGreaterThan -BeLessThan -BeNullOrEmpty -BeOfType -beta2 -cleanup -CodeCoverage -DisableOldStyleAssertions -dynamicparam -eg -EnableExit -EnableLegacyAssertions -EnableLegacyExpectations -ErrorAction -ExcludeTagFilter -ExclusiveFilter -ExecutionContext -ExecutionPolicy -FunctionName -fynctions -GetDynamicParameters -Get-MockDynamicParameters -Get-TestDriveItem -GH-100 -GH-102 -GH-107 -GH-109 -GH-113 -GH-114 -GH-123 -GH-125 -GH-126 -GH-129 -GH-13 -GH-130 -GH-134 -GH-135 -GH-136 -GH-137 -GH-139 -GH-143 -GH-144 -GH-147 -GH-148 -GH-149 -GH-150 -GH-152 -GH-155 -GH-156 -GH-158 -GH-163 -GH-164 -GH-165 -GH-166 -GH-167 -GH-168 -GH-171 -GH-172 -GH-174 -GH-176 -GH-183 -GH-185 -GH-186 -GH-187 -GH-188 -GH-19 -GH-190 -GH-192 -GH-195 -GH-200 -GH-203 -GH-209 -GH-215 -GH-223 -GH-232 -GH-234 -GH-249 -GH-254 -GH-26 -GH-266 -GH-267 -GH-27 -GH-272 -GH-274 -GH-276 -GH-278 -GH-281 -GH-290 -GH-295 -GH-304 -GH-306 -GH-307 -GH-322 -GH-323 -GH-324 -GH-326 -GH-327 -GH-333 -GH-341 -GH-346 -GH-35 -GH-354 -GH-358 -GH-362 -GH-368 -GH-37 -GH-38 -GH-39 -GH-40 -GH-42 -GH-46 -GH-49 -GH-50 -GH-52 -GH-58 -GH-61 -GH-68 -GH-69 -GH-70 -GH-71 -GH-84 -GH-86 -GH-9 -GH-90 -GH-92 -GH-94 -GH-95 -GH-98 -GH-99 -InModuleScope -Invoke-Pester's -ISESteroids -LegacyNUnitXml -ModuleName -MyInvocation -nuget.exe -OutputFile -OutputFormat -OutputXml -ParameterFilter -PassThru -Passthu -pester.bat -Pester.bat -PesterException -PesterThrowFailureMessage -PSCommandPath -PSv3 -should.not -ShouldArgs -StrictMode -TestName -Tests.ps1. -v2 -v3 -v3.0 -Validate-Xml -Write-UsageForNewFixture -#endregion - -#region src/Modules/Shared/Pester/README.md Overrides - - src/Modules/Shared/Pester/README.md -hoc -pester-bdd-for-the-system-administrator -powershell-bdd-testing-pester-screencast -v1.0. -#endregion - #region src/powershell/README.md Overrides - src/powershell/README.md powershell-unix @@ -1190,3 +1094,12 @@ tests.zip v5.0 v6.0. #endregion + +#region test/tools/WebListener/README.md Overrides + - test/tools/WebListener/README.md +Auth +NoResume +NTLM +NumberBytes +ResponseHeaders +#endregion diff --git a/.travis.yml b/.travis.yml index b0a5387a276..9298ab22700 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,21 +3,21 @@ language: cpp git: depth: 1000 -os: - - linux - - osx -sudo: required -dist: trusty -osx_image: xcode8.1 - matrix: + include: + - os: linux + dist: trusty + sudo: required + - os: osx + osx_image: xcode8.1 fast_finish: true addons: artifacts: paths: - - $(ls powershell*{deb,pkg,AppImage} | tr "\n" ":") - - pester-tests.xml + - $(ls powershell*{deb,pkg,AppImage,gz} | tr "\n" ":") + - TestResultsSudo.xml + - TestResultsNoSudo.xml install: # Default 2.0.0 Ruby is buggy @@ -26,6 +26,10 @@ install: rvm install ruby-2.3.3; rvm --default use 2.3.3; fi + # Ensure that libcurl+openssl is used on macOS for greater feature support. + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + export DYLD_LIBRARY_PATH=/usr/local/opt/curl/lib:/usr/local/opt/openssl/lib:${DYLD_LIBRARY_PATH}; + fi - pushd tools - ./install-powershell.sh - popd @@ -35,11 +39,32 @@ install: npm install -g markdown-spellcheck@0.11.0; fi - ulimit -n 4096 - - powershell -File tools/travis.ps1 -Bootstrap + - pwsh -File tools/travis.ps1 -Stage Bootstrap script: - - powershell -File tools/travis.ps1 + - pwsh -File tools/travis.ps1 # spellcheck + # Ignore 'Pester' folder because it's third party - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then - mdspell '**/*.md' '!powershell/**/*.md' --ignore-numbers --ignore-acronyms --report; + mdspell '**/*.md' '!**/Pester/**/*.md' --ignore-numbers --ignore-acronyms --report; fi + +after_failure: + - pwsh -File tools/travis.ps1 -Stage Failure + +after_success: + - pwsh -File tools/travis.ps1 -Stage Success + +# travis-ci will quit using the cache if an enviroment variable changes +env: + global: + - CACHE_VERSION=netcoreapp.2.0.6-sdk.2.1.4 + - POWERSHELL_TELEMETRY_OPTOUT=1 + +# timeout uploading cache after 6 minutes (360 seconds) +cache: + timeout: 360 + directories: + - $HOME/.nuget + - $HOME/.dotnet + - $HOME/Library/Caches/Homebrew diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000000..b0c23e31c2d --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,11 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "ms-vscode.cpptools", + "ms-vscode.csharp", + "ms-vscode.PowerShell", + "twxs.cmake", + "DavidAnson.vscode-markdownlint" + ] +} diff --git a/.vscode/launch.json b/.vscode/launch.json index 5a51dd2dc7d..4ba261df08c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,8 +7,8 @@ "request": "launch", "justMyCode": false, "stopAtEntry": true, - "program": "${workspaceRoot}/debug/powershell", - "preLaunchTask": "build", + "program": "${workspaceRoot}/debug/pwsh", + "preLaunchTask": "Build", "externalConsole": true, "cwd": "${workspaceRoot}" }, @@ -18,6 +18,24 @@ "request": "attach", "justMyCode": false, "processId": "${command:pickProcess}" + }, + { + "type": "PowerShell", + "request": "launch", + "name": "PowerShell Launch Current File", + "script": "${file}", + "args": [], + "cwd": "${file}" + }, + { + "type": "PowerShell", + "request": "launch", + "name": "PowerShell Launch Current File w/Args Prompt", + "script": "${file}", + "args": [ + "${command:SpecifyScriptArgs}" + ], + "cwd": "${file}" } ] } diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000000..792e547d8a5 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,37 @@ +// Place your settings in this file to overwrite default and user settings. +{ + "editor.tabSize": 4, + "editor.insertSpaces": true, + + "files.insertFinalNewline": true, + + // Based on current .markdownlist.json settings: + // https://github.com/PowerShell/PowerShell/blob/master/.markdownlint.json + "markdownlint.config": { + "MD004": false, + "MD024": false, + "MD033": false, + "MD034": false, + "MD038": false, + "MD042": false + }, + + "[powershell]": { + "files.trimTrailingWhitespace": true + }, + + // Sets the codeformatting options to follow the given indent style in a way that is compatible with PowerShell syntax. For more information about the brace styles please refer to https://github.com/PoshCode/PowerShellPracticeAndStyle/issues/81. + "powershell.codeFormatting.preset": "OTBS", + + // Adds a space between a keyword and its associated scriptblock expression. + "powershell.codeFormatting.whitespaceBeforeOpenBrace": true, + + // Adds a space between a keyword (if, elseif, while, switch, etc) and its associated conditional expression. + "powershell.codeFormatting.whitespaceBeforeOpenParen": true, + + // Adds spaces before and after an operator ('=', '+', '-', etc.). + "powershell.codeFormatting.whitespaceAroundOperator": true, + + // Adds a space after a separator (',' and ';'). + "powershell.codeFormatting.whitespaceAfterSeparator": true +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 3806a5a8119..4283a9f10eb 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,16 +1,63 @@ { - "version": "0.1.0", - "command": "powershell", - "isShellCommand": true, - "showOutput": "always", - "suppressTaskName": true, - "args": [ "-command" ], + "version": "2.0.0", + + "windows": { + "options": { + "shell": { + "executable": "pwsh.exe", + "args": [ + "-NoProfile", + "-ExecutionPolicy", + "Bypass", + "-Command" + ] + } + } + }, + "linux": { + "options": { + "shell": { + "executable": "/usr/bin/pwsh", + "args": [ + "-NoProfile", + "-Command" + ] + } + } + }, + "osx": { + "options": { + "shell": { + "executable": "/usr/local/bin/pwsh", + "args": [ + "-NoProfile", + "-Command" + ] + } + } + }, "tasks": [ { - "taskName": "build", - "args": [ "Import-Module ${workspaceRoot}/build.psm1; Start-PSBuild -Output ${workspaceRoot}/debug" ], - "isBuildCommand": true, + "label": "Bootstrap", + "type": "shell", + "command": "Import-Module ${workspaceFolder}/build.psm1; Start-PSBootstrap", + "problemMatcher": [] + }, + { + "label": "Clean Build", + "type": "shell", + "command": "Import-Module ${workspaceFolder}/build.psm1; Start-PSBuild -Clean -Output (Join-Path ${workspaceFolder} debug)", + "problemMatcher": "$msCompile" + }, + { + "label": "Build", + "type": "shell", + "command": "Import-Module ${workspaceFolder}/build.psm1; Start-PSBuild -Output (Join-Path ${workspaceFolder} debug)", + "group": { + "kind": "build", + "isDefault": true + }, "problemMatcher": "$msCompile" } ] diff --git a/CHANGELOG.md b/CHANGELOG.md index 59b29f0d108..c1dacb2fa1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,509 @@ # Changelog +## v6.1.0-preview.1 - 2018-03-23 + +### Breaking Changes + +- Throw terminating error in `New-TemporaryFile` and make it not rely on the presence of the `TEMP` environment variable (#6182) (Thanks @bergmeister!) +- Remove the unnecessary `AddTypeCommandBase` class from `Add-Type` (#5407) (Thanks @iSazonov!) +- Remove unsupported members from the enum `Language` in `Add-Type` (#5829) (Thanks @iSazonov!) +- Fix range operator to work better with character ranges (#5732) (Thanks @iSazonov!) + +### Engine Updates and Fixes + +- Fix `ValidateSet` with generator in a module (#5702) +- Update `SAL` annotation and fix warnings (#5617) +- Add `ForEach` and `Where` methods to `PSCustomobject` (#5756) (Thanks @iSazonov!) +- Add `Count` and `Length` properties to `PSCustomobject` (#5745) (Thanks @iSazonov!) +- Make minor fixes in compiler to properly handle void type expression (#5764) +- Logging: Fix the escaped characters when generating `.resx` file from PowerShell `ETW` manifest. (#5892) +- Remove `PSv2` only code from `Types_Ps1Xml.cs` and `HostUtilities.cs` (#5907) (Thanks @iSazonov!) +- Enable passing arrays to `pwsh -EncodedArguments` on debug builds. (#5836) +- Logging: Handle path that contains spaces in `RegisterManifest.ps1` (#5859) (Thanks @tandasat!) +- Add `-settingsfile` to `pwsh` to support loading a custom powershell config file. (#5920) +- Return better error for `pwsh -WindowStyle` on unsupported platforms. (#5975) (Thanks @thezim!) +- Enable conversions from `PSMethod` to `Delegate` (#5287) (Thanks @powercode!) +- Minor code clean-up changes in tab completion code (#5737) (Thanks @kwkam!) +- Add lambda support to `-replace` operator (#6029) (Thanks @IISResetMe!) +- Fix retrieval of environment variables on Windows in cases where variable names differ only by case. (#6320) +- Fix the `NullRefException` when using `-PipelineVariable` with `DynamicParam` block (#6433) +- Add `NullReference` checks to two code paths related to `PseudoParameterBinder` (#5738) (Thanks @kwkam!) +- Fix `PropertyOnlyAdapter` to allow calling base methods (#6394) +- Improve table view for `Certs` and `Signatures` by adding `EnhancedKeyUsageList` and `StatusMessage` (#6123) +- Fix the filtering of analytic events on Unix platforms. (#6086) +- Update copyright and license headers (#6134) +- Set pipeline thread stack size to 10MB (#6224) (Thanks @iSazonov!) + +### General Cmdlet Updates and Fixes + +- Fix the `NullRefException` in `Enter-PSHostProcess` (#5995) +- Merge and Sort `BasicHtmlWebResponseObject` and `ContentHelper` in Web Cmdlets (#5720) (Thanks @markekraus!) +- Encoding for `New-ModuleManifest` on all platforms should be `UTF-8 NoBOM` (#5923) +- Make `Set-Location` use path with wildcard characters as literal if it exists (#5839) +- Combine Web Cmdlets partial class files (#5612) (Thanks @markekraus!) +- Change `Microsoft.PowerShell.Commands.SetDateCommand.SystemTime` to `struct`. (#6006) (Thanks @stknohg!) +- Add Simplified `multipart/form-data` support to Web Cmdlets through `-Form` parameter (#5972) (Thanks @markekraus!) +- Make a relative redirect URI absolute when `Authorization` header present (#6325) (Thanks @markekraus!) +- Make relation-link handling in Web Cmdlets case-insensitive (#6338) +- Make `Get-ChildItem -LiteralPath` accept `Include` or `Exclude` filter (#5462) +- Stop `ConvertTo-Json` when `Ctrl+c` is hit (#6392) +- Make `Resolve-Path -Relative` return useful path when `$PWD` and `-Path` is on different drive (#5740) (Thanks @kwkam!) +- Correct the `%c`, `%l`, `%k`, `%s` and `%j` formats in `Get-Date -UFormat` (#4805) (Thanks @iSazonov!) +- Add standard deviation implementation on `Measure-Object` (#6238) (Thanks @CloudyDino!) +- Make `Get-ChildItem /* -file` include `` as search directory (#5431) +- Enable setting `PSSession` Name when using `SSHTransport` and add `Transport` property (#5954) +- Add `Path` alias to `-FilePath` parameters and others for several commands (#5817) (Thanks @KevinMarquette!) +- Add the parameter `-Password` to `Get-PfxCertificate` (#6113) (Thanks @maybe-hello-world!) +- Don't add trailing spaces to last column when using `Format-Table` (#5568) +- Fix table alignment and padding. (#6230) +- Add `-SkipHeaderValidation` Support to `ContentType` on Web Cmdlets (#6018) (Thanks @markekraus!) +- Add common aliases for all `write-*` commands default message parameter (#5816) (Thanks @KevinMarquette!) +- Make `UTF-8` the default encoding for `application/json` (#6109) (Thanks @markekraus!) +- Enable `$env:PAGER` to work correctly if arguments are used (#6144) + +### Test + +- Convert Web Cmdlets test to `one-true-brace-style` formatting (#5716) (Thanks @markekraus!) +- Add a test for `IValidateSetValuesGenerator` in a module (#5830) (Thanks @iSazonov!) +- Fix function to test for docker OS due to change to use `linuxkit` for macOS (#5843) +- Replace `HttpListener` tests with `WebListener` (#5806, #5840, #5872) (Thanks @markekraus!) +- Stop `HttpListener` from running in Web Cmdlets tests (#5921) (Thanks @markekraus!) +- Fix `PSVersion` in `PSSessionConfiguration` tests (#5554) (Thanks @iSazonov!) +- Update test framework to support Pester v4 (#6064) +- Update tests to use Pester v4 Syntax. (#6294, #6257, #6306, #6304, #6298) +- Add negative tests for `Copy-Item` over remote sessions (#6231) +- Markdown test: Use strict in JavaScript (#6328) +- Add tests for `Get-Process` about the `-Module` and `-FileVersion` parameters (#6272) +- Add test for the `OsLocalDateTime` property of `Get-ComputerInfo`. (#6253) +- Change `Get-FileHash` tests to use raw bytes (#6430) +- Remove `runas.exe` from tests as we have tags to control this behavior (#6432) +- Refactor the `Get-Content` tests to use `-TestCases`. (#6082) +- Use `RequireAdminOnWindows` tag in `Set-Date` tests (#6034) (Thanks @stknohg!) +- Remove `-TimeOutSec` from non timeout related tests (#6055) (Thanks @markekraus!) +- Add verbosity and more accurate timeout implementation for `Start-WebListener` (#6013) (Thanks @markekraus!) +- Skip tests that use `ExecutionPolicy` cmdlets on Unix (#6021) +- Change Web Cmdlet tests to use `127.0.0.1` instead of `Localhost` (#6069) (Thanks @markekraus!) +- Fix `Start-PSPester` to include or exclude `RequireSudoOnUnix` tag smartly on Unix (#6241) +- Fix the terse output on Windows for test runs without admin privilege (#6252) +- Add `RequireSudoOnUnix` tag for `Get-Help` tests. (#6223) +- Add tests for `*-Item` Cmdlets in function provider (#6172) +- Support running tests in root privilege on Linux. (#6145) + +### Build and Packaging Improvements + +- Add option to add explorer shell context menu in Windows installer (#5774) (Thanks @bergmeister!) +- Make the explorer shell context menu registry entries platform specific to allow side by side of `x86` and `x64`. (#5824) (Thanks @bergmeister!) +- Fix start menu folder clash of shortcut when `x86` and `x64` are both installed by appending ` (x86)` for `x86` installation. (#5826) (Thanks @bergmeister!) +- Reduce image file sizes using lossless compression with `imgbot` (#5808) (Thanks @bergmeister!) +- Windows installer: Allow `Launch PowerShell` checkbox to be toggled using the space bar. (#5792) (Thanks @bergmeister!) +- Fix release packaging build (#6459) +- Fail `AppVeyor` Build if `MSI` does not build (#5755) (Thanks @bergmeister!) +- Cleanup temporarily created `WiX` files after compilation to be able to have a clean re-build (#5757) (Thanks @bergmeister!) +- Fix `install-powershell.ps1` for running during window setup (#5727) +- Start using `Travis-CI` cache (#6003) +- Fix build, packaging and installation scripts for `SLES` (#5918) (Thanks @tomconte!) +- Update recommended `WiX` toolset link to be generic to `WiX 3.x` but mention that latest version of 3.11 has to be taken (#5926) (Thanks @bergmeister!) +- Add service point manager call in `Install-PowerShell.ps1` to force `TLS1.2`. (#6310) (Thanks @DarqueWarrior!) +- Add `-Restore` when build `win-arm` and `win-arm64` (#6353) +- Make sure package verification failure fails the `AppVeyor` build (#6337) +- Specify the runtime when running `dotnet restore` in `Start-PSBuild` (#6345) +- Rename `log` and `logerror` to `Write-Log [$message] [-error]` (#6333) +- Make Linux packages use correct version scheme for preview releases (#6318) +- Add support for Debian in `installpsh-debian.sh` (#6314) (Thanks @Pawamoy!) +- MSI: Make preview builds to install Side by side with release builds (#6301) +- Add `TLS1.2` workaround for code coverage script (#6299) +- Cleanup after Powershell install for `CentOS` and `Fedora` Docker images (#6264) (Thanks @strawgate!) +- MSI: Update the environment variable PATH with proper value (#6441) +- MSI: Remove the version from the product name (#6415) +- Support non-GitHub commits in the change log generation script (#6389) +- Fix secret and JavaScript compliance issues (#6408) +- Remove `AppVeyor` specific cmdlet from `Start-NativeExecution` (#6263) +- Restore modules from the `NuGet` package cache by using `dotnet restore` (#6111) +- CI Build: Use `TRAVIS_PULL_REQUEST_SHA` to accurately get the commit message (#6024) +- Use `TLS1.2` on Windows during `Start-PSBootstrap` (#6235) (Thanks @CallmeJoeBob!) +- Use `TLS1.2` in `Start-PSBootStrap` without breaking `HTTPS` (#6236) (Thanks @markekraus!) +- Add options to enable `PSRemoting` and register Windows Event Logging Manifest to MSI installer (#5999) (Thanks @bergmeister!) + +### Documentation and Help Content + +- Separate macOS from Linux install instructions. (#5823) (Thanks @thezim!) +- Show usage (short) help if command line parameter is wrong (#5780) (Thanks @iSazonov!) +- Add the breaking changes doc for 6.0.0 release. (#5620) (Thanks @maertendMSFT!) +- Remove DockerFile for Fedora 25 and add DockerFile for Fedora 27 (#5984) (Thanks @seemethere!) +- Add a missing step to prepare the build environment on Mac. (#5901) (Thanks @zackJKnight!) +- Update `BREAKINGCHANGES.md` to include WebCmdlets breaking changes (#5852) (Thanks @markekraus!) +- Fix typos in `BREAKINGCHANGES.md` (#5913) (Thanks @brianbunke!) +- Update `macos.md` to use `brew cask upgrade` for upgrading powershell (#5875) (Thanks @timothywlewis!) +- Add verification step to macOS install docs (#5860) (Thanks @rpalo!) +- Fix links in macOS install docs (#5861) (Thanks @kanjibates!) +- Update docs with test guidelines with the `RequireSudoOnUnix` tag. (#6274) +- Add `Alpine` Linux support (#6367) (Thanks @kasper3!) +- Update to Governance doc to reflect current working model (#6323) +- Add guidance on adding copyright and license header to new source files (#6140) +- Fix the command to build type catalog in `internals.md` (#6084) (Thanks @ppadmavilasom!) +- Fix `Pull Request Process` dead link (#6066) (Thanks @IISResetMe!) +- Update processes to allow for coordinated vulnerability disclosure (#6042) +- Rework Windows Start menu folder name (#5891) (Thanks @Stanzilla!) +- Update `Raspbian` installation instructions to create `symlink` for `pwsh` (#6122) +- Fix various places that still refer to old versions of `pwsh` (#6179) (Thanks @bergmeister!) +- Correct a Linux installation typo (#6219) (Thanks @mababio!) +- Change synopsis of `install-powershell.ps1` to reflect that it works cross-platform (#5465) (Thanks @bergmeister!) + +## v6.0.2 - 2018-03-15 + +### Engine updates and fixes + +- Update PowerShell to use `2.0.6` dotnet core runtime and packages (#6403) + - This change addresses this vulnerability: [Microsoft Security Advisory `CVE-2018-0875`: Hash Collision can cause Denial of Service](https://github.com/PowerShell/Announcements/issues/4) + +### Build and Packaging Improvements + +- Add Ubuntu build without `AppImage` (#6380) +- Add scripts to set and or update the release tag in `VSTS` (#6107) +- Fix `DSC` Configuration compilation (#6225) +- Fix errors in `Start-PSBootStrap` during release builds (#6159) +- Fix spelling failures in `CI` (#6191) +- Use PowerShell `windowsservercore` Docker image for release builds (#6226) +- Use `ADD` instead of `Invoke-WebRequest` in `nanoserver` Docker file (#6255) +- When doing daily/test build in a non-release branch use the branch name as the preview name (#6355) +- Add Environment Variable override of telemetry (#6063) (Thanks @diddledan!) +- Build: Remove two unneeded lines from `Invoke-AppveyorFinish` (#6344) +- MSI: Refactor `New-MsiPackage` into `packaging.psm1` + and various fixes to enable patching + (#5871, #6221, #6254, #6303, #6356, #6208, #6334, #6379, #6094, #6192) +- MSI: Use `HKLM` instead of `HKCU` registry keys since the current installation scope is per-machine. (#5915) (Thanks @bergmeister!) + +## v6.0.1 - 2018-01-25 + +### Engine updates and fixes + +- Update PowerShell to use `2.0.5` dotnet core runtime and packages. (#5903, #5961) (Thanks @iSazonov!) + +### Build and Packaging Improvements + +- Re-release of `v6.0.0` as `v6.0.1` due to issues upgrading from pre-release versions + +### Test + +- Update regular expression to validate `GitCommitId` in `$PSVersionTable` to not require a pre-release tag (#5893) + +## v6.0.0 - 2018-01-10 + +### Breaking changes + +- Remove `sc` alias which conflicts with `sc.exe` (#5827) +- Separate group policy settings and enable policy controlled logging in PowerShell Core (#5791) + +### Engine updates and fixes + +- Handle `DLLImport` failure of `libpsrpclient` in PowerShell Remoting on Unix platforms (#5622) + +### Test + +- Replace `lee.io` Tests with `WebListener` (#5709) (Thanks @markekraus!) +- Update the docker based release package tests due to the removal of `Pester` module and other issues (#5692) +- Replace Remaining `HttpBin.org` Tests with `WebListener` (#5665) (Thanks @markekraus!) + +### Build and Packaging Improvements + +- Update x86 and x64 `MSI` packages to not overwrite each other (#5812) (Thanks @bergmeister!) +- Update `Restore-PSPester` to include the fix for nested describe errors (#5771) +- Automate the generation of release change log draft (#5712) + +### Documentation and Help Content + +- Updated help Uri to point to latest help content for `Microsoft.PowerShell.Core` module (#5820) +- Update the installation doc for `Raspberry-Pi` about supported devices (#5773) +- Fix a typo and a Markdown linting error in the Pull Request Template (#5807) (Thanks @markekraus!) +- Update submodule documentation for pester removal (#5786) (Thanks @bergmeister!) +- Change `Github` to `GitHub` in `CONTRIBUTING.md` (#5697) (Thanks @stuntguy3000!) +- Fix incorrect release date on the changelog (#5698) (Thanks @SwarfegaGit!) +- Add instructions to deploy `win-arm` build on Windows IoT (#5682) + +## v6.0.0-rc.2 - 2017-12-14 + +### Breaking changes + +- Skip null-element check for collections with a value-type element type (#5432) +- Make `AllSigned` execution policy require modules under `$PSHome` to be signed (#5511) + +### Engine updates and fixes + +- Update PowerShell to use `2.0.4` dotnet core runtime. (#5677) +- Remove references to the old executable `powershell` or `powershell.exe` (#5408) + +### General cmdlet updates and fixes + +- Remove unnecessary check for `Paths.count > 0`, in the `*-FileCatalog` CmdLets (#5596) +- Use explicit `libpsl-native` binary name for `dllimport`. (#5580) + +### Build and Packaging Improvements + +- Fix `Get-EnvironmentInformation` to properly check for CoreCLR (#5592) (Thanks @markekraus!) +- Make Travis CI use `libcurl+openssl+gssapi` (#5629) (Thanks @markekraus!) +- Disambiguate icon for daily builds on Windows (#5467) (Thanks @bergmeister!) +- Fix `Import-CliXml` tests which still use `powershell` instead of `pwsh` and make sure it fails if it regresses (#5521) (Thanks @markekraus!) +- Update port number used for WebCmdlets tests which broke due to a change in AppVeyor (#5520) (Thanks @markekraus!) +- Clean up use of `Runspaceconfiguration` from comments and xUnit test code (#5569) (Thanks @Bhaal22!) +- Replace `HttpListener` Response Tests with WebListener (#5540, #5605) (Thanks @markekraus!) +- Fix the path to `powershell_xxx.inc` in Start-Build (#5538) (Thanks @iSazonov!) +- Remove Pester as a module include with the PowerShell Packages. + You should be able to add it by running `Install-Module Pester`. (#5623, #5631) +- Refactor `New-UnixPackaging` into functions to make the large function more readable. (#5625) +- Make the experience better when `Start-PSPester` doesn't find Pester (#5673) +- Update packaging and release build scripts to produce zip packages for `win-arm` and `win-arm64` (#5664) +- Enable `Install-Debian` to work with VSTS Hosted Linux Preview (#5659) +- Add `linux-arm` tarball package to release build (#5652, #5660) +- Enable building for `win-arm` and `win-arm64` (#5524) +- Make macOS package require 10.12 or newer (#5649, #5654) +- Update signing subjects to something meaningful (#5650) +- Make `New-UnixPackage` more readable (#5625) +- Update `PowerShellGet` tests to validate the new install location of `AllUsers` scope. (#5633) +- Increase reliability of flaky test that fails intermittently in CI (#5641) +- Exclude markdown files from `Pester` folder from the Markdown meta test (#5636) +- Run tests for Windows installer only on Windows (#5619) +- Suppress the expected errors from `Select-Xml` tests (#5591) +- Add retry logic to prerequisite URL and output URL on failure so you can more easily troubleshoot (#5601, #5570) +- Make sure submodule are initialized when running Mac release build (#5496) +- Remove duplicate files in Windows packages in a folder called `signed` (#5527) +- Add PowerShell VSCode style settings (#5529) (Thanks @bergmeister) +- Add Travis CI matrix for improved job tagging (#5547) +- Remove community docker files from official docker image validation (#5508) + +### Documentation and Help Content + +- XML documentation fix for `CompletionResult` (#5550) (Thanks @bergmeister!) +- Change synopsis of `install-powershell.ps1` to reflect that it works cross-platform (#5465) (Thanks @bergmeister!) +- Add more helpful message for `AmbiguousParameterSet` exception (#5537) (Thanks @kvprasoon!) +- Update the contribution guideline to note that updating the changelog is required. (#5586) +- Updated doc to build arm/arm64 versions of `psrp.windows` and `PowerShell.Core.Instrumentation.dll` libraries (#5668) +- Update Contribution guidelines with work in progress guidance (#5655) +- Update code coverage tests to get GitCommitId using the ProductVersion from Assembly (#5651) +- Remove requirement to updating changelog update in PR (#5644, #5586) +- Minor refactoring of the release build scripts (#5632) +- Update PowerShell executable name in `using-vscode.md` (#5593) +- Fix xUnit test for PS (#4780) +- Update install link and instructions for R-Pi (#5495) + +### Compliance Work + +[Compliance](https://github.com/PowerShell/PowerShell/blob/master/docs/maintainers/issue-management.md#miscellaneous-labels) +work is required for Microsoft to continue to sign and release packages from the project as official Microsoft packages. + +- Remove `PerformWSManPluginReportCompletion`, which was not used, from `pwrshplugin.dll` (#5498) (Thanks @bergmeister!) +- Remove exclusion for hang and add context exception for remaining instances (#5595) +- Replace `strlen` with `strnlen` in native code (#5510) + +## v6.0.0-rc - 2017-11-16 + +### Breaking changes + +- Fix `-Verbose` to not override `$ErrorActionPreference`. (#5113) +- Fix `Get-Item -LiteralPath a*b` to return error if `a*b` doesn't actually exist. (#5197) +- Remove `AllScope` from most default aliases to reduce overhead on creating new scopes. (#5268) +- Change `$OutputEncoding` default to be `UTF8` without `BOM` rather than `ASCII`. (#5369) +- Add error on legacy credential over non-HTTPS for Web Cmdlets. (#5402) (Thanks @markekraus!) +- Fix single value JSON `null` in `Invoke-RestMethod`. (#5338) (Thanks @markekraus!) +- Add `PSTypeName` Support for `Import-Csv` and `ConvertFrom-Csv`. (#5389) (Thanks @markekraus!) + +### Engine updates and fixes + +- Add char range overload to the `..` operator, so `'a'..'z'` returns characters from 'a' to 'z'. (#5026) (Thanks @IISResetMe!) +- Remove `CommandFactory` because it serves no real purpose. (#5266) +- Change to not insert line breaks at console window width to output (except for tables). (#5193) +- Use `Ast` for context in parameter binding and fix to glob the native command argument only when it's not quoted. (#5188) +- Fix dynamic class assembly name. (#5292) +- Update PowerShell to use `2.0.4-servicing` dotnet core runtime. (#5295) +- Fix `ExecutionContext.LoadAssembly` to load with name when file cannot be found. (#5161) +- Speed up the check for suspicious content in script texts. (#5302) +- Use native `os_log` APIs on macOS for PowerShell Core logging. (#5310) +- Redirect `ETW` logging to `Syslog` on Linux. (#5144) +- Improve how we pass the array literal to native commands. (#5301) +- Make `SemanticVersion` compatible with `SemVer 2.0`. (#5037) (Thanks @iSazonov!) +- Revert refactoring changes that broke remoting to Windows PowerShell 5.1. (#5321) +- Port some fixes in `Job` for an issue that causes PowerShell to not respond. (#5258) +- Multiple improvements by `CodeRush` static analysis. (#5132) (Thanks @Himura2la!) +- Fix the Runspace cleanup issue that causes PowerShell to not respond on exit. (#5356) +- Update PowerShell to depend on new version of `psrp` and `libmi` nuget packages on Unix platforms. (#5469) + +### General cmdlet updates and fixes + +- Add `-AsHashtable` to `ConvertFrom-Json` to return a `Hashtable` instead. (#5043) (Thanks @bergmeister!) +- Fix `Import-module` to not report a loaded module was not found. (#5238) +- Fix performance issues in `Add-Type`. (#5243) (Thanks @iSazonov!) +- Fix `PSUserAgent` generation for Web Cmdlets on Windows 7. (#5256) (Thanks @markekraus!) +- Remove `DCOM` support from `*-Computer` cmdlets. (#5277) +- Add multiple link header support to Web Cmdlets. (#5265) (Thanks @markekraus!) +- Use wider columns for process id and user. (#5303) +- Add `Remove-Alias` Command. (#5143) (Thanks @PowershellNinja!) +- Update `installpsh-suse.sh` to work with the `tar.gz` package. (#5309) +- Add `Jobject` serialization support to `ConvertTo-Json`. (#5141) +- Display full help with 'help' function. (#5195) (Thanks @rkeithhill!) +- Fix `help` function to not pipe to `more` if objects are returned instead of help text. (#5395) +- Fix `Unblock-File` to not write an error if the file is already unblocked. (#5362) (Thanks @iSazonov!) +- Clean up FullCLR code from Web Cmdlets. (#5376) (Thanks @markekraus!) +- Exclude cmdlets that are not supported on Unix platforms. (#5083) +- Make `Import-Csv` support `CR`, `LF` and `CRLF` as line delimiters. (#5363) (Thanks @iSazonov!) +- Fix spelling in Web Cmdlet errors. (#5427) (Thanks @markekraus!) +- Add `SslProtocol` support to Web Cmdlets. (#5329) (Thanks @markekraus!) + +### Build and Packaging Improvements + +- Use `RCEdit` to embed icon and version information into `pwsh.exe`. (#5178) +- Update Docker file for Nano Server 1709 release. (#5252) +- Change VSCode build task to use `pwsh`. (#5255) +- Refactor building and packaging scripts for signing in release build workflow. (#5300) +- Always build with `-CrossGen` in CI to verify a fix in `CrossGen` tool. (#5315) +- Separate `Install-PowerShellRemoting.ps1` from `psrp.windows` nuget package. (#5330) +- Include symbols folder an embedded zip when packaging symbols. (#5333) +- Add Uniform Type Identifier conforming with Apple standards using a reverse DNS style prefix. (#5323) +- Update `Wix` toolset download link to newer version 3.11 (#5339) (Thanks @bergmeister!) +- Re-enable macOS launcher after fixing an issue that blocked macOS package generation. (#5291) (Thanks @thezim!) +- Set expected binaries and variable name for folder for symbols build. (#5357) +- Rename and update PowerShell `ETW` manifest to remove the Windows PowerShell dependency. (#5360) +- Add ability to produce `tar.gz` package for Raspbian. (#5387) +- Update `Find-Dotnet` to find dotnet with the compatible SDK. (#5341) (Thanks @rkeithhill!) +- Add signing manifest and script to update it with production values. (#5397) +- Add `install-powershell.ps1` to install PowerShell Core on windows. (#5383) +- Make `-Name` a dynamic parameter in `Start-PSPackage`. (#5415) +- Support `[package]` tag in PR CI and fix nightly build on macOS. (#5410) +- Enhance `install-powershell.ps1` to work on Linux and macOS. (#5411) +- Move the `RCEdit` step to the build phase rather than the packaging phase. (#5404) +- Allow packaging from a zip package to allow for signing. (#5418) +- Add automation to validate PowerShell Core packages using Docker containers. (#5401) +- Fix the `brew update` issue in bootstrap script. (#5400) +- Enable `install-powershell.ps1` to update the current running PowerShell Core. (#5429) +- Add standard set of VSCode workspace setting files. (#5457) (Thanks @rkeithhill!) +- Add support for installing PowerShell Core on Amazon Linux via `install-powershell.sh`. (#5461) (Thanks @DarwinJS!) +- Get `PowerShellGet` and `PackageManagement` from the PowerShell Gallery. (#5452) +- Fix `Start-PSBuild` on `WSL` if repository was already built on Windows. (#5346) (Thanks @bergmeister!) +- Fix build in VSCode and use an improved version of `tasks.json` from @rkeithhill. (#5453) +- Add scripts for signing packages in the release build workflow. (#5463) + +### Documentation and Help Content + +- Fix the codebase to use the consistent copyright string. (#5210) +- Add documentation about how to create `libpsl` and `psrp.windows` nuget packages. (#5278) +- Add help strings in PowerShell banner. (#5275) (Thanks @iSazonov!) +- Change all links in `README.md` to absolute as they are being used in other places outside of GitHub. (#5354) +- Update instructions to build on VSCode based on `pwsh`. (#5368) +- Update `FAQ.md` about how to use PowerShell Core nuget packages. (#5366) +- Correct the Fedora documentation (#5384) (Thanks @offthewoll!) +- Add instructions about how to create the `PowerShell.Core.Instrumentation` nuget package. (#5396) +- Updated PowerShell to use the latest help package. (#5454) + +### Compliance Work + +[Compliance](https://github.com/PowerShell/PowerShell/blob/master/docs/maintainers/issue-management.md#miscellaneous-labels) +work is required for Microsoft to continue to sign and release packages from the project as official Microsoft packages. + +- Replace the word `hang` with something more appropriate and add rules about other terms. (#5213, #5297, #5358) +- Use simplified names for compliance folders (#5388) +- Add compliance label description (#5355) +- Set `requestedExecutionLevel` to `asInvoker` for `pwsh.exe` on Windows. (#5285) +- Add `HighEntropyVA` to building pwsh. (#5455) + +## v6.0.0-beta.9 - 2017-10-24 + +### Breaking changes + +- Fix `ValueFromRemainingArguments` to have consistent behavior between script and C# cmdlets. (#2038) (Thanks @dlwyatt) +- Remove parameters `-importsystemmodules` and `-psconsoleFile` from `powershell.exe`. (#4995) +- Removed code to show a GUI prompt for credentials as PowerShell Core prompts in console. (#4995) +- Remove `-ComputerName` from `Get/Set/Remove-Service`. (#5094) +- Rename the executable name from `powershell` to `pwsh`. (#5101) +- Remove `RunspaceConfiguration` support. (#4942) +- Remove `-ComputerName` support since .NET Core `Process.GetProcesses(computer)` returns local processes. (#4960) +- Make `-NoTypeInformation` the default on `Export-Csv` and `ConvertTo-Csv`. (#5164) (Thanks @markekraus) +- Unify cmdlets with parameter `-Encoding` to be of type `System.Text.Encoding`. (#5080) + +### Engine updates and fixes + +- Fix PowerShell to update the `PATH` environment variable only if `PATH` exists. (#5021) +- Enable support of folders and files with colon in name on Unix. (#4959) +- Fix detection of whether `-LiteralPath` was used to suppress wildcard expansion for navigation cmdlets. (#5038) +- Enable using filesystem from a UNC location. (#4998) +- Escape trailing backslash when dealing with native command arguments. (#4965) +- Change location of `ModuleAnalysisCache` so it isn't shared with Windows PowerShell. (#5133) +- Put command discovery before scripts for Unix. (#5116) + +### General cmdlet updates and fixes + +- Correct comma position in `SecureStringCommands.resx`. (#5033) (Thanks @markekraus) +- User Agent of Web Cmdlets now reports the OS platform (#4937) (Thanks @LDSpits) +- Add the positional parameter attribute to `-InputObject` for `Set-Service`. (#5017) (Thanks @travisty-) +- Add `ValidateNotNullOrEmpty` attribute to `-UFormat` for `Get-Date`. (#5055) (Thanks @DdWr) +- Add `-NoNewLine` switch for `Out-String`. (#5056) (Thanks @raghav710) +- Improve progress messages written by Web Cmdlets. (#5078) (Thanks @markekraus) +- Add verb descriptions and alias prefixes for `Get-Verb`. (#4746) (Thanks @Tadas) +- Fix `Get-Content -Raw` to not miss the last line feed character. (#5076) +- Add authentication parameters to Web Cmdlets. (#5052) (Thanks @markekraus) + - Add `-Authentication` that provides three options: Basic, OAuth, and Bearer. + - Add `-Token` to get the bearer token for OAuth and Bearer options. + - Add `-AllowUnencryptedAuthentication` to bypass authentication that is provided for any transport scheme other than HTTPS. +- Fix `MatchInfoContext` clone implementation (#5121) (Thanks @dee-see) +- Exclude `PSHostProcess` cmdlets from Unix platforms. (#5105) +- Fix `Add-Member` to fetch resource string correctly. (#5114) +- Enable `Import-Module` to be case insensitive. (#5097) +- Add exports for `syslog` APIs in `libpsl-native`. (#5149) +- Fix `Get-ChildItem` to not ignore `-Depth` parameter when using with `-Include` or `-Exclude`. (#4985) (Thanks @Windos) +- Added properties `UserName`, `Description`, `DelayedAutoStart`, `BinaryPathName` and `StartupType` to the `ServiceController` objects returned by `Get-Service`. (#4907) (Thanks @joandrsn) + +### Build and Packaging Improvements + +- Treat `.rtf` files as binary so EOL don't get changed. (#5020) +- Improve the output of `tools/installpsh-osx.sh` and update Travis-CI to use Ruby 2.3.3. (#5065) +- Improve `Start-PSBootstrap` to locate dotnet SDK before installing it. (#5059) (Thanks @PetSerAl) +- Fix the prerequisite check of the MSI package. (#5070) +- Support creating `tar.gz` package for Linux and macOS. (#5085) +- Add release builds that produce symbols for compliance scans. (#5086) +- Update existing Docker files for the Linux package changes. (#5102) +- Add compiler switches and replace dangerous function with safer ones. (#5089) +- Add macOS launcher. (#5138) (Thanks @thezim) +- Replace `httpbin.org/response-headers` Tests with WebListener. (#5058) (Thanks @markekraus) +- Update `appimage.sh` to reflect the new name `pwsh`. (#5172) +- Update the man help file used in packaging. (#5173) +- Update to use `pwsh` in macOS launcher. (#5174) (Thanks @thezim) +- Add code to send web hook for Travis-CI daily build. (#5183) +- Add `global.json` to pick correct SDK version. (#5118) (Thanks @rkeithhill) +- Update packaging to only package PowerShell binaries when packaging symbols. (#5145) +- Update Docker files and related due to the name change. (#5156) + +### Code Cleanup + +- Clean up Json cmdlets. (#5001) (Thanks @iSazonov) +- Remove code guarded by `RELATIONSHIP_SUPPORTED` and `SUPPORTS_IMULTIVALUEPROPERTYCMDLETPROVIDER`, which has never been used. (#5066) +- Remove PSMI code that has never been used. (#5075) +- Remove unreachable code for `Stop-Job`. (#5091) (Thanks @travisty-) +- Removed font and codepage handling code that is only applicable to Windows PowerShell. (#4995) + +### Test + +- Fix a race condition between `WebListener` and Web Cmdlets tests. (#5035) (Thanks @markekraus) +- Add warning to `Start-PSPester` if Pester module is not found (#5069) (Thanks @DdWr) +- Add tests for DSC configuration compilation on Windows. (#5011) +- Test fixes and code coverage automation fixes. (#5046) + +### Documentation and Help Content + +- Update Pi demo instructions about installing libunwind8. (#4974) +- Add links on best practice guidelines in coding guideline. (#4983) (Thanks @iSazonov) +- Reformat command line help for `powershell -help` (#4989) (Thanks @iSazonov) +- Change logo in readme to current black icon. (#5030) +- Fix RPM package name in `README.md`. (#5044) +- Update `docs/building/linux.md` to reflect the current status of powershell build. (#5068) (Thanks @dee-see) +- Add black version of `.icns` file for macOS. (#5073) (Thanks @thezim) +- Update Arch Linux installation instructions. (#5048) (Thanks @kylesferrazza) +- Add submodule reminder to `testing-guidelines.md`. (#5061) (Thanks @DdWr) +- Update instructions in `docs/building/internals.md` for building from source. (#5072) (Thanks @kylesferrazza) +- Add UserVoice link to Issue Template. (#5100) (Thanks @markekraus) +- Add `Get-WebListenerUrl` Based Examples to WebListener `README.md`. (#4981) (Thanks @markekraus) +- Add document about how to create cmdlet with dotnet CLI. (#5117) (Thanks @rkeithhill) +- Update the help text for PowerShell executable with the new name `pwsh`. (#5182) +- Add new forward links for PowerShell 6.0.0 help content. (#4978) +- Fix VSCode `launch.json` to point to `pwsh`. (#5189) +- Add example of how to create .NET Core cmdlet with Visual Studio. (#5096) + ## v6.0.0-beta.8 - 2017-10-05 ### Breaking changes @@ -184,7 +688,7 @@ ### Breaking change -* Make invalid argument error messages for -File and -Command consistent and make exit codes consistent with Unix standards (#4573) +* Make invalid argument error messages for `-File` and `-Command` consistent and make exit codes consistent with Unix standards (#4573) ### Engine updates and fixes @@ -346,7 +850,7 @@ For more information on this, we invite you to read [this blog post explaining P ### Remoting -- Fixed hang when the SSH client abruptly terminates. (#4123) +- Fixed PowerShell not responding when the SSH client abruptly terminates. (#4123) ### Documentation @@ -677,7 +1181,7 @@ We made a number of fixes to the progress bar rendering and the `ProgressRecord` - Add '-Title' to 'Get-Credential' and unify the prompt experience - Update dependency list for PowerShell Core on Linux and OS X -- Fix 'powershell -Command -' to not hang and to not ignore the last command +- Fix 'powershell -Command -' to not stop responding and to not ignore the last command - Fix binary operator tab completion - Enable 'ConvertTo-Html' in PowerShell Core - Remove most Maximum* capacity variables diff --git a/DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY b/DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY new file mode 100644 index 00000000000..e69de29bb2d diff --git a/LICENSE.txt b/LICENSE.txt index 1df45821db0..f2618346d7b 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,25 +1,25 @@ PowerShell 6.0 -Copyright (c) Microsoft Corporation +Copyright (c) Microsoft Corporation. All rights reserved. -All rights reserved. +All rights reserved. MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the ""Software""), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the ""Software""), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/PowerShell.Common.props b/PowerShell.Common.props index ccbbd1ea40f..adb868eaa42 100644 --- a/PowerShell.Common.props +++ b/PowerShell.Common.props @@ -94,7 +94,8 @@ (c) Microsoft Corporation. All rights reserved. netcoreapp2.0 - 2.0.0 + 2.0.6 + Latest true true @@ -104,6 +105,7 @@ true ../signing/visualstudiopublic.snk true + true diff --git a/PowerShell-Win.sln b/PowerShell.sln similarity index 84% rename from PowerShell-Win.sln rename to PowerShell.sln index 35a5c99e93d..f831410072f 100644 --- a/PowerShell-Win.sln +++ b/PowerShell.sln @@ -1,34 +1,46 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 +# https://github.com/dotnet/project-system/blob/master/docs/opening-with-new-project-system.md#project-type-guids VisualStudioVersion = 15.0.26730.12 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "powershell-win-core", "src\powershell-win-core\powershell-win-core.csproj", "{8359D422-E0C4-4A0D-94EB-3C9DD16B7932}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "powershell-win-core", "src\powershell-win-core\powershell-win-core.csproj", "{8359D422-E0C4-4A0D-94EB-3C9DD16B7932}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Management.Automation", "src\System.Management.Automation\System.Management.Automation.csproj", "{AF660EE7-0183-4B79-A93F-221B6AC1C24B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Management.Automation", "src\System.Management.Automation\System.Management.Automation.csproj", "{AF660EE7-0183-4B79-A93F-221B6AC1C24B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.PowerShell.Commands.Utility", "src\Microsoft.PowerShell.Commands.Utility\Microsoft.PowerShell.Commands.Utility.csproj", "{EAB203E1-2A68-4166-BE54-5C44DE825229}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerShell.Commands.Utility", "src\Microsoft.PowerShell.Commands.Utility\Microsoft.PowerShell.Commands.Utility.csproj", "{EAB203E1-2A68-4166-BE54-5C44DE825229}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.PowerShell.CoreCLR.Eventing", "src\Microsoft.PowerShell.CoreCLR.Eventing\Microsoft.PowerShell.CoreCLR.Eventing.csproj", "{981D3972-343D-4E17-935B-037E1C622771}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerShell.CoreCLR.Eventing", "src\Microsoft.PowerShell.CoreCLR.Eventing\Microsoft.PowerShell.CoreCLR.Eventing.csproj", "{981D3972-343D-4E17-935B-037E1C622771}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.PowerShell.ConsoleHost", "src\Microsoft.PowerShell.ConsoleHost\Microsoft.PowerShell.ConsoleHost.csproj", "{8FFE645D-F0C9-4220-9A88-83062ED211D2}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerShell.ConsoleHost", "src\Microsoft.PowerShell.ConsoleHost\Microsoft.PowerShell.ConsoleHost.csproj", "{8FFE645D-F0C9-4220-9A88-83062ED211D2}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.PowerShell.Commands.Management", "src\Microsoft.PowerShell.Commands.Management\Microsoft.PowerShell.Commands.Management.csproj", "{FCE53A5E-5FAC-48BE-BAD8-2110040B5C2E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerShell.Commands.Management", "src\Microsoft.PowerShell.Commands.Management\Microsoft.PowerShell.Commands.Management.csproj", "{FCE53A5E-5FAC-48BE-BAD8-2110040B5C2E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.PowerShell.SDK", "src\Microsoft.PowerShell.SDK\Microsoft.PowerShell.SDK.csproj", "{4BC19063-1F66-467B-87DE-80449C72BCD6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerShell.SDK", "src\Microsoft.PowerShell.SDK\Microsoft.PowerShell.SDK.csproj", "{4BC19063-1F66-467B-87DE-80449C72BCD6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Management.Infrastructure.CimCmdlets", "src\Microsoft.Management.Infrastructure.CimCmdlets\Microsoft.Management.Infrastructure.CimCmdlets.csproj", "{131A8527-92D7-468F-822D-5354229A865C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Management.Infrastructure.CimCmdlets", "src\Microsoft.Management.Infrastructure.CimCmdlets\Microsoft.Management.Infrastructure.CimCmdlets.csproj", "{131A8527-92D7-468F-822D-5354229A865C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.PowerShell.Commands.Diagnostics", "src\Microsoft.PowerShell.Commands.Diagnostics\Microsoft.PowerShell.Commands.Diagnostics.csproj", "{439A24FC-8E0A-48B6-8227-44C297311F49}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerShell.Commands.Diagnostics", "src\Microsoft.PowerShell.Commands.Diagnostics\Microsoft.PowerShell.Commands.Diagnostics.csproj", "{439A24FC-8E0A-48B6-8227-44C297311F49}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.PowerShell.PSReadLine", "src\Microsoft.PowerShell.PSReadLine\Microsoft.PowerShell.PSReadLine.csproj", "{07BFD271-8992-4F34-9091-6CFC3E224A24}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerShell.PSReadLine", "src\Microsoft.PowerShell.PSReadLine\Microsoft.PowerShell.PSReadLine.csproj", "{07BFD271-8992-4F34-9091-6CFC3E224A24}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.WSMan.Management", "src\Microsoft.WSMan.Management\Microsoft.WSMan.Management.csproj", "{8F63D134-E413-4181-936D-D82F3F5F1D85}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.WSMan.Management", "src\Microsoft.WSMan.Management\Microsoft.WSMan.Management.csproj", "{8F63D134-E413-4181-936D-D82F3F5F1D85}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.PowerShell.Security", "src\Microsoft.PowerShell.Security\Microsoft.PowerShell.Security.csproj", "{C4F81816-C87A-4ABF-8A37-24AC16A0A6CF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerShell.Security", "src\Microsoft.PowerShell.Security\Microsoft.PowerShell.Security.csproj", "{C4F81816-C87A-4ABF-8A37-24AC16A0A6CF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.WSMan.Runtime", "src\Microsoft.WSMan.Runtime\Microsoft.WSMan.Runtime.csproj", "{D9CCCB67-4EBE-4854-AB52-C0129DC5BAE4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.WSMan.Runtime", "src\Microsoft.WSMan.Runtime\Microsoft.WSMan.Runtime.csproj", "{D9CCCB67-4EBE-4854-AB52-C0129DC5BAE4}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "powershell-unix", "src\powershell-unix\powershell-unix.csproj", "{73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}" +EndProject +# Configuration mapping comment +# All global configurations must be mapped to project configurations +# +# 4BC19063-1F66-467B-87DE-80449C72BCD6 - Microsoft.PowerShell.SDK +# 8359D422-E0C4-4A0D-94EB-3C9DD16B7932 - PowerShell-Win +# Linux is invalid and mapped to Release +# +# 73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690 - powershell-unix +# Only Linux is valid, all configurations mapped to Linux Global GlobalSection(SolutionConfigurationPlatforms) = preSolution CodeCoverage|Any CPU = CodeCoverage|Any CPU @@ -41,8 +53,8 @@ Global {8359D422-E0C4-4A0D-94EB-3C9DD16B7932}.CodeCoverage|Any CPU.Build.0 = CodeCoverage|Any CPU {8359D422-E0C4-4A0D-94EB-3C9DD16B7932}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8359D422-E0C4-4A0D-94EB-3C9DD16B7932}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8359D422-E0C4-4A0D-94EB-3C9DD16B7932}.Linux|Any CPU.ActiveCfg = Linux|Any CPU - {8359D422-E0C4-4A0D-94EB-3C9DD16B7932}.Linux|Any CPU.Build.0 = Linux|Any CPU + {8359D422-E0C4-4A0D-94EB-3C9DD16B7932}.Linux|Any CPU.ActiveCfg = Release|Any CPU + {8359D422-E0C4-4A0D-94EB-3C9DD16B7932}.Linux|Any CPU.Build.0 = Release|Any CPU {8359D422-E0C4-4A0D-94EB-3C9DD16B7932}.Release|Any CPU.ActiveCfg = Release|Any CPU {8359D422-E0C4-4A0D-94EB-3C9DD16B7932}.Release|Any CPU.Build.0 = Release|Any CPU {AF660EE7-0183-4B79-A93F-221B6AC1C24B}.CodeCoverage|Any CPU.ActiveCfg = CodeCoverage|Any CPU @@ -141,6 +153,14 @@ Global {D9CCCB67-4EBE-4854-AB52-C0129DC5BAE4}.Linux|Any CPU.Build.0 = Linux|Any CPU {D9CCCB67-4EBE-4854-AB52-C0129DC5BAE4}.Release|Any CPU.ActiveCfg = Release|Any CPU {D9CCCB67-4EBE-4854-AB52-C0129DC5BAE4}.Release|Any CPU.Build.0 = Release|Any CPU + {73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.Linux|Any CPU.ActiveCfg = Linux|Any CPU + {73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.Linux|Any CPU.Build.0 = Linux|Any CPU + {73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.Release|Any CPU.ActiveCfg = Linux|Any CPU + {73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.Release|Any CPU.Build.0 = Linux|Any CPU + {73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.Debug|Any CPU.ActiveCfg = Linux|Any CPU + {73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.Debug|Any CPU.Build.0 = Linux|Any CPU + {73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.CodeCoverage|Any CPU.ActiveCfg = Linux|Any CPU + {73EA0BE6-C0C5-4B56-A5AA-DADA4C01D690}.CodeCoverage|Any CPU.Build.0 = Linux|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/README.md b/README.md index f8924d4b579..07a25e91491 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ PowerShell Core is a cross-platform (Windows, Linux, and macOS) automation and c for dealing with structured data (e.g. JSON, CSV, XML, etc.), REST APIs, and object models. It includes a command-line shell, an associated scripting language and a framework for processing cmdlets. -[logo]: assets/Powershell_black_64.png +[logo]: https://raw.githubusercontent.com/PowerShell/PowerShell/master/assets/ps_black_64.svg?sanitize=true ## Windows PowerShell vs PowerShell Core @@ -19,60 +19,105 @@ Windows PowerShell specific issues should be opened on [UserVoice][]. If you are new to PowerShell and would like to learn more, we recommend reviewing the [getting started][] documentation. -[getting started]: docs/learning-powershell +[getting started]: https://github.com/PowerShell/PowerShell/tree/master/docs/learning-powershell ## Get PowerShell You can download and install a PowerShell package for any of the following platforms. -| Platform | Downloads | How to Install | -| ---------------------------------- | ---------------------- | ----------------------------- | -| Windows (x64) | [.msi][rl-windows-64] | [Instructions][in-windows] | -| Windows (x86) | [.msi][rl-windows-86] | [Instructions][in-windows] | -| Ubuntu 17.04 | [.deb][rl-ubuntu17] | [Instructions][in-ubuntu17] | -| Ubuntu 16.04 | [.deb][rl-ubuntu16] | [Instructions][in-ubuntu16] | -| Ubuntu 14.04 | [.deb][rl-ubuntu14] | [Instructions][in-ubuntu14] | -| Debian 8 | [.deb][rl-debian8] | [Instructions][in-deb8] | -| Debian 9 | [.deb][rl-debian9] | [Instructions][in-deb9] | -| CentOS 7 | [.rpm][rl-centos] | [Instructions][in-centos] | -| Red Hat Enterprise Linux 7 | [.rpm][rl-centos] | [Instructions][in-rhel7] | -| OpenSUSE 42.2 | [.rpm][rl-centos] | [Instructions][in-opensuse422]| -| Fedora 25 | [.rpm][rl-centos] | [Instructions][in-fedora25] | -| Fedora 26 | [.rpm][rl-centos] | [Instructions][in-fedora26] | -| Arch Linux | | [Instructions][in-archlinux] | -| Many Linux distributions | [.AppImage][rl-ai] | [Instructions][in-appimage] | -| macOS 10.12 | [.pkg][rl-macos] | [Instructions][in-macos] | -| Docker | | [Instructions][in-docker] | -| Kali Linux | [.deb][rl-ubuntu16] | [Instructions][in-kali] - -[rl-windows-64]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-beta.8/PowerShell-6.0.0-beta.8-win-x64.msi -[rl-windows-86]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-beta.8/PowerShell-6.0.0-beta.8-win-x86.msi -[rl-ubuntu17]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-beta.8/powershell_6.0.0-beta.8-1.ubuntu.17.04_amd64.deb -[rl-ubuntu16]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-beta.8/powershell_6.0.0-beta.8-1.ubuntu.16.04_amd64.deb -[rl-ubuntu14]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-beta.8/powershell_6.0.0-beta.8-1.ubuntu.14.04_amd64.deb -[rl-debian8]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-beta.8/powershell_6.0.0-beta.8-1.debian.8_amd64.deb -[rl-debian9]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-beta.8/powershell_6.0.0-beta.8-1.debian.9_amd64.deb -[rl-centos]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-beta.8/powershell-6.0.0_beta.8-1.rhel.7.x86_64.rpm -[rl-ai]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-beta.8/PowerShell-6.0.0-beta.8-x86_64.AppImage -[rl-macos]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-beta.8/powershell-6.0.0-beta.8-osx.10.12-x64.pkg - -[installation]: docs/installation -[in-windows]: docs/installation/windows.md#msi -[in-ubuntu14]: docs/installation/linux.md#ubuntu-1404 -[in-ubuntu16]: docs/installation/linux.md#ubuntu-1604 -[in-ubuntu17]: docs/installation/linux.md#ubuntu-1704 -[in-deb8]: docs/installation/linux.md#debian-8 -[in-deb9]: docs/installation/linux.md#debian-9 -[in-centos]: docs/installation/linux.md#centos-7 -[in-rhel7]: docs/installation/linux.md#red-hat-enterprise-linux-rhel-7 -[in-opensuse422]: docs/installation/linux.md#opensuse-422 -[in-fedora25]: docs/installation/linux.md#fedora-25 -[in-fedora26]: docs/installation/linux.md#fedora-26 -[in-archlinux]: docs/installation/linux.md#arch-linux -[in-appimage]: docs/installation/linux.md#linux-appimage -[in-macos]: docs/installation/linux.md#macos-1012 -[in-docker]: docker -[in-kali]: docs/installation/linux.md#kali +| Supported Platform | Downloads (stable) | Downloads (preview) | How to Install | +| -------------------------------------------| ------------------------| ----------------------| ------------------------------| +| [Windows (x64)][corefx-win] | [.msi][rl-windows-64] | [.msi][pv-windows-64] | [Instructions][in-windows] | +| [Windows (x86)][corefx-win] | [.msi][rl-windows-86] | [.msi][pv-windows-86] | [Instructions][in-windows] | +| [Ubuntu 17.04][corefx-linux] | [.deb][rl-ubuntu17] | [.deb][pv-ubuntu17] | [Instructions][in-ubuntu17] | +| [Ubuntu 16.04][corefx-linux] | [.deb][rl-ubuntu16] | [.deb][pv-ubuntu16] | [Instructions][in-ubuntu16] | +| [Ubuntu 14.04][corefx-linux] | [.deb][rl-ubuntu14] | [.deb][pv-ubuntu14] | [Instructions][in-ubuntu14] | +| [Debian 8.7+][corefx-linux] | [.deb][rl-debian8] | [.deb][pv-debian8] | [Instructions][in-deb8] | +| [Debian 9][corefx-linux] | [.deb][rl-debian9] | [.deb][pv-debian9] | [Instructions][in-deb9] | +| [CentOS 7][corefx-linux] | [.rpm][rl-centos] | [.rpm][pv-centos] | [Instructions][in-centos] | +| [Red Hat Enterprise Linux 7][corefx-linux] | [.rpm][rl-centos] | [.rpm][pv-centos] | [Instructions][in-rhel7] | +| [OpenSUSE 42.2][corefx-linux] | [.rpm][rl-centos] | [.rpm][pv-centos] | [Instructions][in-opensuse422]| +| [Fedora 25][corefx-linux] | [.rpm][rl-centos] | [.rpm][pv-centos] | [Instructions][in-fedora25] | +| [Fedora 26][corefx-linux] | [.rpm][rl-centos] | [.rpm][pv-centos] | [Instructions][in-fedora26] | +| [macOS 10.12+][corefx-macos] | [.pkg][rl-macos] | [.pkg][pv-macos] | [Instructions][in-macos] | +| Docker | | | [Instructions][in-docker] | + +You can download and install a PowerShell package for any of the following platforms, **which are supported by the community.** + +| Platform | Downloads (stable) | Downloads (preview) | How to Install | +| -------------------------| ------------------------| ----------------------------- | ------------------------------| +| Arch Linux | | | [Instructions][in-archlinux] | +| Kali Linux | [.deb][rl-ubuntu16] | [.deb][pv-ubuntu16] | [Instructions][in-kali] | +| Many Linux distributions | [.AppImage][rl-ai] | | [Instructions][in-appimage] | + +You can also download the PowerShell binary archives for Windows, macOS and Linux. + +| Platform | Downloads (stable) | Downloads (preview) | How to Install | +| ------------------------------------| ------------------------------------------------ | ------------------------------------------------| -----------------------------------------------| +| Windows | [32-bit][rl-winx86-zip]/[64-bit][rl-winx64-zip] | [32-bit][pv-winx86-zip]/[64-bit][pv-winx64-zip] | [Instructions][in-windows-zip] | +| macOS | [64-bit][rl-macos-tar] | [64-bit][pv-macos-tar] | [Instructions][in-tar] | +| Linux | [64-bit][rl-linux-tar] | [64-bit][pv-linux-tar] | [Instructions][in-tar] | +| Windows (arm) **Experimental** | [32-bit][rl-winarm]/[64-bit][rl-winarm64] | [32-bit][pv-winarm]/[64-bit][pv-winarm64] | [Instructions][in-windows-zip] | +| Raspbian (Stretch) **Experimental** | [.tgz][rl-raspbian] | [.tgz][pv-raspbian] | [Instructions][in-raspbian] | + +[rl-windows-64]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/PowerShell-6.0.2-win-x64.msi +[rl-windows-86]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/PowerShell-6.0.2-win-x86.msi +[rl-ubuntu17]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/powershell_6.0.2-1.ubuntu.17.04_amd64.deb +[rl-ubuntu16]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/powershell_6.0.2-1.ubuntu.16.04_amd64.deb +[rl-ubuntu14]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/powershell_6.0.2-1.ubuntu.14.04_amd64.deb +[rl-debian8]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/powershell_6.0.2-1.debian.8_amd64.deb +[rl-debian9]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/powershell_6.0.2-1.debian.9_amd64.deb +[rl-centos]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/powershell-6.0.2-1.rhel.7.x86_64.rpm +[rl-ai]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.1/PowerShell-6.0.1-x86_64.AppImage +[rl-macos]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/powershell-6.0.2-osx.10.12-x64.pkg +[rl-winarm]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/PowerShell-6.0.2-win-arm32.zip +[rl-winarm64]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/PowerShell-6.0.2-win-arm64.zip +[rl-winx86-zip]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/PowerShell-6.0.2-win-x86.zip +[rl-winx64-zip]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/PowerShell-6.0.2-win-x64.zip +[rl-macos-tar]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/powershell-6.0.2-osx-x64.tar.gz +[rl-linux-tar]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/powershell-6.0.2-linux-x64.tar.gz +[rl-raspbian]: https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/powershell-6.0.2-linux-arm32.tar.gz + +[pv-windows-64]: https://github.com/PowerShell/PowerShell/releases/download/v6.1.0-preview.1/PowerShell-6.1.0-preview.1-win-x64.msi +[pv-windows-86]: https://github.com/PowerShell/PowerShell/releases/download/v6.1.0-preview.1/PowerShell-6.1.0-preview.1-win-x86.msi +[pv-ubuntu17]: https://github.com/PowerShell/PowerShell/releases/download/v6.1.0-preview.1/powershell_6.1.0~preview.1-1.ubuntu.17.04_amd64.deb +[pv-ubuntu16]: https://github.com/PowerShell/PowerShell/releases/download/v6.1.0-preview.1/powershell_6.1.0~preview.1-1.ubuntu.16.04_amd64.deb +[pv-ubuntu14]: https://github.com/PowerShell/PowerShell/releases/download/v6.1.0-preview.1/powershell_6.1.0~preview.1-1.ubuntu.14.04_amd64.deb +[pv-debian8]: https://github.com/PowerShell/PowerShell/releases/download/v6.1.0-preview.1/powershell_6.1.0~preview.1-1.debian.8_amd64.deb +[pv-debian9]: https://github.com/PowerShell/PowerShell/releases/download/v6.1.0-preview.1/powershell_6.1.0~preview.1-1.debian.9_amd64.deb +[pv-centos]: https://github.com/PowerShell/PowerShell/releases/download/v6.1.0-preview.1/powershell-6.1.0~preview.1-1.rhel.7.x86_64.rpm +[pv-macos]: https://github.com/PowerShell/PowerShell/releases/download/v6.1.0-preview.1/powershell-6.1.0-preview.1-osx.10.12-x64.pkg +[pv-winarm]: https://github.com/PowerShell/PowerShell/releases/download/v6.1.0-preview.1/PowerShell-6.1.0-preview.1-win-arm32.zip +[pv-winarm64]: https://github.com/PowerShell/PowerShell/releases/download/v6.1.0-preview.1/PowerShell-6.1.0-preview.1-win-arm64.zip +[pv-winx86-zip]: https://github.com/PowerShell/PowerShell/releases/download/v6.1.0-preview.1/PowerShell-6.1.0-preview.1-win-x86.zip +[pv-winx64-zip]: https://github.com/PowerShell/PowerShell/releases/download/v6.1.0-preview.1/PowerShell-6.1.0-preview.1-win-x64.zip +[pv-macos-tar]: https://github.com/PowerShell/PowerShell/releases/download/v6.1.0-preview.1/powershell-6.1.0-preview.1-osx-x64.tar.gz +[pv-linux-tar]: https://github.com/PowerShell/PowerShell/releases/download/v6.1.0-preview.1/powershell-6.1.0-preview.1-linux-x64.tar.gz +[pv-raspbian]: https://github.com/PowerShell/PowerShell/releases/download/v6.1.0-preview.1/powershell-6.1.0-preview.1-linux-arm32.tar.gz + +[installation]: https://github.com/PowerShell/PowerShell/tree/master/docs/installation +[in-windows]: https://github.com/PowerShell/PowerShell/tree/master/docs/installation/windows.md#msi +[in-ubuntu14]: https://github.com/PowerShell/PowerShell/tree/master/docs/installation/linux.md#ubuntu-1404 +[in-ubuntu16]: https://github.com/PowerShell/PowerShell/tree/master/docs/installation/linux.md#ubuntu-1604 +[in-ubuntu17]: https://github.com/PowerShell/PowerShell/tree/master/docs/installation/linux.md#ubuntu-1704 +[in-deb8]: https://github.com/PowerShell/PowerShell/tree/master/docs/installation/linux.md#debian-8 +[in-deb9]: https://github.com/PowerShell/PowerShell/tree/master/docs/installation/linux.md#debian-9 +[in-centos]: https://github.com/PowerShell/PowerShell/tree/master/docs/installation/linux.md#centos-7 +[in-rhel7]: https://github.com/PowerShell/PowerShell/tree/master/docs/installation/linux.md#red-hat-enterprise-linux-rhel-7 +[in-opensuse422]: https://github.com/PowerShell/PowerShell/tree/master/docs/installation/linux.md#opensuse-422 +[in-fedora25]: https://github.com/PowerShell/PowerShell/tree/master/docs/installation/linux.md#fedora-25 +[in-fedora26]: https://github.com/PowerShell/PowerShell/tree/master/docs/installation/linux.md#fedora-26 +[in-archlinux]: https://github.com/PowerShell/PowerShell/tree/master/docs/installation/linux.md#arch-linux +[in-appimage]: https://github.com/PowerShell/PowerShell/tree/master/docs/installation/linux.md#linux-appimage +[in-macos]: https://github.com/PowerShell/PowerShell/tree/master/docs/installation/macos.md +[in-docker]: https://github.com/PowerShell/PowerShell/tree/master/docker +[in-kali]: https://github.com/PowerShell/PowerShell/tree/master/docs/installation/linux.md#kali +[in-windows-zip]: https://github.com/PowerShell/PowerShell/tree/master/docs/installation/windows.md#zip +[in-tar]: https://github.com/PowerShell/PowerShell/tree/master/docs/installation/linux.md#binary-archives +[in-raspbian]: https://github.com/PowerShell/PowerShell/tree/master/docs/installation/linux.md#raspbian +[corefx-win]:https://github.com/dotnet/core/blob/master/release-notes/2.0/2.0-supported-os.md#windows +[corefx-linux]:https://github.com/dotnet/core/blob/master/release-notes/2.0/2.0-supported-os.md#linux +[corefx-macos]:https://github.com/dotnet/core/blob/master/release-notes/2.0/2.0-supported-os.md#macos To install a specific version, visit [releases](https://github.com/PowerShell/PowerShell/releases). @@ -118,11 +163,11 @@ If you have any problems building, please consult the developer [FAQ][]. |--------------------------|-------------------|-------------------|----------------------| | [![av-nightly-image][]][av-nightly-site] | [![linux-nightly-image][]][tv-site] | [![macOS-nightly-image][]][tv-site] | [![cc-image][]][cc-site] | -[bd-linux]: docs/building/linux.md -[bd-windows]: docs/building/windows-core.md -[bd-macOS]: docs/building/macos.md +[bd-linux]: https://github.com/PowerShell/PowerShell/tree/master/docs/building/linux.md +[bd-windows]: https://github.com/PowerShell/PowerShell/tree/master/docs/building/windows-core.md +[bd-macOS]: https://github.com/PowerShell/PowerShell/tree/master/docs/building/macos.md -[FAQ]: docs/FAQ.md +[FAQ]: https://github.com/PowerShell/PowerShell/tree/master/docs/FAQ.md [tv-image]: https://travis-ci.org/PowerShell/PowerShell.svg?branch=master [tv-site]: https://travis-ci.org/PowerShell/PowerShell/branches @@ -151,7 +196,7 @@ If you already cloned but forgot to use `--recursive`, you can update submodules git submodule update --init ``` -See [working with the PowerShell repository](docs/git) for more information. +See [working with the PowerShell repository](https://github.com/PowerShell/PowerShell/tree/master/docs/git) for more information. ## Developing and Contributing @@ -163,9 +208,9 @@ If you are developing .NET Core C# applications targeting PowerShell Core, pleas Also make sure to check out our [PowerShell-RFC repository](https://github.com/powershell/powershell-rfc) for request-for-comments (RFC) documents to submit and give comments on proposed and future designs. -[check out our FAQ]: docs/FAQ.md#where-do-i-get-the-powershell-core-sdk-package -[Contribution Guide]: .github/CONTRIBUTING.md -[known issues]: docs/KNOWNISSUES.md +[check out our FAQ]: https://github.com/PowerShell/PowerShell/tree/master/docs/FAQ.md#where-do-i-get-the-powershell-core-sdk-package +[Contribution Guide]: https://github.com/PowerShell/PowerShell/tree/master/.github/CONTRIBUTING.md +[known issues]: https://github.com/PowerShell/PowerShell/tree/master/docs/KNOWNISSUES.md [GitHub issues]: https://github.com/PowerShell/PowerShell/issues [new issue]:https://github.com/PowerShell/PowerShell/issues/new @@ -173,7 +218,7 @@ Also make sure to check out our [PowerShell-RFC repository](https://github.com/p PowerShell is licensed under the [MIT license][]. -[MIT license]: LICENSE.txt +[MIT license]: https://github.com/PowerShell/PowerShell/tree/master/LICENSE.txt ### Windows Docker Files and Images @@ -185,7 +230,7 @@ License: By requesting and using the Container OS Image for Windows containers, ### Telemetry By default, PowerShell collects the OS description and the version of PowerShell (equivalent to `$PSVersionTable.OS` and `$PSVersionTable.GitCommitId`) using [Application Insights](https://azure.microsoft.com/en-us/services/application-insights/). -To opt-out of sending telemetry, delete the file `DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY` before starting PowerShell from the installed location. +To opt-out of sending telemetry, create an environment variable called `POWERSHELL_TELEMETRY_OPTOUT` set to a value of `1` before starting PowerShell from the installed location. The telemetry we collect fall under the [Microsoft Privacy Statement](https://privacy.microsoft.com/en-us/privacystatement/). ## Governance @@ -202,4 +247,4 @@ For more information see the [Code of Conduct FAQ][conduct-FAQ] or contact [open [conduct-code]: http://opensource.microsoft.com/codeofconduct/ [conduct-FAQ]: http://opensource.microsoft.com/codeofconduct/faq/ [conduct-email]: mailto:opencode@microsoft.com -[conduct-md]: ./CODE_OF_CONDUCT.md +[conduct-md]: https://github.com/PowerShell/PowerShell/tree/master/./CODE_OF_CONDUCT.md diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index 971899c4e05..755c5912d40 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -76,3 +76,30 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + + +------------------------------------------------- +File: NJsonSchema +------------------------------------------------- + +The MIT License (MIT) + +Copyright (c) 2016 Rico Suter + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/appveyor.yml b/appveyor.yml index 5c2ab1fc7fd..2dd6198324d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,7 +2,7 @@ image: Visual Studio 2017 -# cache version - netcoreapp.2.0.0 +# cache version - netcoreapp.2.0.6-sdk.2.1.4 cache: - '%LocalAppData%\Microsoft\dotnet -> appveyor.yml' - '%HOMEDRIVE%%HOMEPATH%\.nuget\packages -> appveyor.yml' @@ -10,6 +10,9 @@ cache: nuget: project_feed: true +environment: + POWERSHELL_TELEMETRY_OPTOUT: 1 + install: - git submodule update --init - ps: Import-Module .\tools\Appveyor.psm1 @@ -24,5 +27,5 @@ test_script: after_test: - ps: Invoke-AppVeyorAfterTest -on_finish: +on_finish: - ps: Invoke-AppveyorFinish diff --git a/assets/AppImageThirdPartyNotices.txt b/assets/AppImageThirdPartyNotices.txt index 53e24978b4d..0eaf1e0cd58 100644 --- a/assets/AppImageThirdPartyNotices.txt +++ b/assets/AppImageThirdPartyNotices.txt @@ -5,7 +5,7 @@ -Copyright © 1991-2016 Unicode, Inc. All rights reserved. +Copyright (c) 1991-2016 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in http://www.unicode.org/copyright.html Permission is hereby granted, free of charge, to any person obtaining diff --git a/assets/Powershell_256.png b/assets/Powershell_256.png index 8767330b82d..0f51af844e4 100644 Binary files a/assets/Powershell_256.png and b/assets/Powershell_256.png differ diff --git a/assets/Product.wxs b/assets/Product.wxs index 8f2362d098f..e8f080e6d93 100644 --- a/assets/Product.wxs +++ b/assets/Product.wxs @@ -5,19 +5,35 @@ - + + + + + + + + + + + + - - - - - - - + + + + + + - + @@ -31,10 +47,42 @@ - + + + + + + + + + + + + + + + @@ -43,9 +91,6 @@ - @@ -56,7 +101,7 @@ 1 - LAUNCHAPPONEXIT + LAUNCHAPPONEXIT=1 @@ -67,12 +112,15 @@ - + - + + + + @@ -99,23 +147,193 @@ - + + + + + + + + + + + + + + ADD_PATH=1 + + + + + ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + "1"]]> + + NOT Installed + Installed AND PATCH + + 1 + LicenseAccepted = "1" + + 1 + 1 + + 1 + 1 + NOT WIXUI_DONTVALIDATEPATH + "1"]]> + WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1" + 1 + 1 + 1 + + NOT Installed + Installed AND NOT PATCH + Installed AND PATCH + + 1 + + 1 + 1 + 1 + + + + + + diff --git a/assets/files.wxs b/assets/files.wxs new file mode 100644 index 00000000000..b33e2e2fb7d --- /dev/null +++ b/assets/files.wxs @@ -0,0 +1,2415 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/license.rtf b/assets/license.rtf index 0e507920b40..4b513defb3f 100644 --- a/assets/license.rtf +++ b/assets/license.rtf @@ -231,7 +231,7 @@ crosoft.com/office/word/2003/wordml}}\paperw12240\paperh15840\margl1440\margr144 {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}} \pard\plain \ltrpar\s15\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid3804850 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 { -\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \b\f2\fs20\cf17\lang9\langfe1033\langnp9\insrsid93983\charrsid93983 PowerShell 6.0}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \b\f2\fs20\cf17\lang9\langfe1033\langnp9\insrsid3804850\charrsid93983 +\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \b\f2\fs20\cf17\lang9\langfe1033\langnp9\insrsid93983\charrsid93983 PowerShell 6.1}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \b\f2\fs20\cf17\lang9\langfe1033\langnp9\insrsid3804850\charrsid93983 \par }{\rtlch\fcs1 \af2\afs18 \ltrch\fcs0 \f2\fs18\cf17\lang9\langfe1033\langnp9\insrsid3804850\charrsid93983 Copyright (c) Microsoft Corporation}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf17\lang9\langfe1033\langnp9\insrsid3804850\charrsid93983 \par }{\rtlch\fcs1 \af2\afs18 \ltrch\fcs0 \f2\fs18\cf17\lang9\langfe1033\langnp9\insrsid3804850\charrsid93983 All rights reserved.\~}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf17\lang9\langfe1033\langnp9\insrsid3804850\charrsid93983 \par }{\rtlch\fcs1 \af2\afs18 \ltrch\fcs0 \f2\fs18\cf17\lang9\langfe1033\langnp9\insrsid3804850\charrsid93983 MIT License}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf17\lang9\langfe1033\langnp9\insrsid3804850\charrsid93983 @@ -1245,4 +1245,4 @@ ffffffffffffffffffffffffffffffff52006f006f007400200045006e0074007200790000000000 85b5e0f4d101feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file +0000000000000000000000000000000000000000000000000105000000000000}} diff --git a/assets/macDialog.png b/assets/macDialog.png new file mode 100644 index 00000000000..432aeca610e Binary files /dev/null and b/assets/macDialog.png differ diff --git a/assets/patch-template.wxs b/assets/patch-template.wxs new file mode 100644 index 00000000000..f3c6c54e0c0 --- /dev/null +++ b/assets/patch-template.wxs @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/ps_black_64.svg b/assets/ps_black_64.svg new file mode 100644 index 00000000000..a238b21fee5 --- /dev/null +++ b/assets/ps_black_64.svg @@ -0,0 +1,120 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/assets/powershell.1.ronn b/assets/pwsh.1.ronn similarity index 95% rename from assets/powershell.1.ronn rename to assets/pwsh.1.ronn index eea00966b09..01e57148be0 100644 --- a/assets/powershell.1.ronn +++ b/assets/pwsh.1.ronn @@ -1,9 +1,9 @@ -powershell(1) -- command-line shell and .NET REPL +pwsh(1) -- PowerShell command-line shell and .NET REPL ================================================= ## SYNOPSIS -`powershell` [`-NoLogo`] [`-NoExit`] [`-NoProfile`] [`-NonInteractive`] +`pwsh` [`-NoLogo`] [`-NoExit`] [`-NoProfile`] [`-NonInteractive`] [`-InputFormat` {Text | XML}] [`-OutputFormat` {Text | XML}] [`-EncodedCommand` ] [`-File` ] [`-ExecutionPolicy` ] @@ -119,5 +119,5 @@ These are automatically defined PowerShell-language variables. ## COPYRIGHT -Copyright (c) 2016 Microsoft Corporation. -All rights reserved. \ No newline at end of file +Copyright (c) Microsoft Corporation. +All rights reserved. diff --git a/assets/pwsh.manifest b/assets/pwsh.manifest new file mode 100644 index 00000000000..3584aba51b5 --- /dev/null +++ b/assets/pwsh.manifest @@ -0,0 +1,26 @@ + + + PowerShell Core 6 + + + + + + + + + + + + + + + + + + + + diff --git a/build.psm1 b/build.psm1 index c89c4e019a6..6944f5181f2 100644 --- a/build.psm1 +++ b/build.psm1 @@ -1,9 +1,12 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + # On Unix paths is separated by colon # On Windows paths is separated by semicolon $script:TestModulePathSeparator = [System.IO.Path]::PathSeparator $dotnetCLIChannel = "release" -$dotnetCLIRequiredVersion = "2.0.0" +$dotnetCLIRequiredVersion = $(Get-Content $PSScriptRoot/global.json | ConvertFrom-Json).Sdk.Version # Track if tags have been sync'ed $tagsUpToDate = $false @@ -97,19 +100,13 @@ function Get-PSCommitId function Get-EnvironmentInformation { $environment = @{} - # Use the .NET Core APIs to determine the current platform. - # If a runtime exception is thrown, we are on Windows PowerShell, not PowerShell Core, - # because System.Runtime.InteropServices.RuntimeInformation - # and System.Runtime.InteropServices.OSPlatform do not exist in Windows PowerShell. - try { - $Runtime = [System.Runtime.InteropServices.RuntimeInformation] - $OSPlatform = [System.Runtime.InteropServices.OSPlatform] - + # PowerShell Core will likely not be built on pre-1709 nanoserver + if ($PSVersionTable.ContainsKey("PSEdition") -and "Core" -eq $PSVersionTable.PSEdition) { $environment += @{'IsCoreCLR' = $true} - $environment += @{'IsLinux' = $Runtime::IsOSPlatform($OSPlatform::Linux)} - $environment += @{'IsMacOS' = $Runtime::IsOSPlatform($OSPlatform::OSX)} - $environment += @{'IsWindows' = $Runtime::IsOSPlatform($OSPlatform::Windows)} - } catch { + $environment += @{'IsLinux' = $IsLinux} + $environment += @{'IsMacOS' = $IsMacOS} + $environment += @{'IsWindows' = $IsWindows} + } else { $environment += @{'IsCoreCLR' = $false} $environment += @{'IsLinux' = $false} $environment += @{'IsMacOS' = $false} @@ -141,9 +138,11 @@ function Get-EnvironmentInformation $environment += @{'IsCentOS' = $LinuxInfo.ID -match 'centos' -and $LinuxInfo.VERSION_ID -match '7'} $environment += @{'IsFedora' = $LinuxInfo.ID -match 'fedora' -and $LinuxInfo.VERSION_ID -ge 24} $environment += @{'IsOpenSUSE' = $LinuxInfo.ID -match 'opensuse'} - $environment += @{'IsOpenSUSE13' = $Environment.IsOpenSUSE -and $LinuxInfo.VERSION_ID -match '13'} + $environment += @{'IsSLES' = $LinuxInfo.ID -match 'sles'} + $environment += @{'IsOpenSUSE13' = $Environmenst.IsOpenSUSE -and $LinuxInfo.VERSION_ID -match '13'} $environment += @{'IsOpenSUSE42.1' = $Environment.IsOpenSUSE -and $LinuxInfo.VERSION_ID -match '42.1'} - $environment += @{'IsRedHatFamily' = $Environment.IsCentOS -or $Environment.IsFedora -or $Environment.IsOpenSUSE} + $environment += @{'IsRedHatFamily' = $Environment.IsCentOS -or $Environment.IsFedora} + $environment += @{'IsSUSEFamily' = $Environment.IsSLES -or $Environment.IsOpenSUSE} # Workaround for temporary LD_LIBRARY_PATH hack for Fedora 24 # https://github.com/PowerShell/PowerShell/issues/2511 @@ -178,8 +177,12 @@ function Start-BuildNativeWindowsBinaries { [ValidateSet('Debug', 'Release')] [string]$Configuration = 'Release', - [ValidateSet('x64', 'x86')] - [string]$Arch = 'x64' + # The `x64_arm` syntax is the build environment for VS2017, `x64` means the host is an x64 machine and will use + # the x64 built tool. The `arm` refers to the target architecture when doing cross compilation. + [ValidateSet('x64', 'x86', 'x64_arm64', 'x64_arm')] + [string]$Arch = 'x64', + + [switch]$Clean ) if (-not $Environment.IsWindows) { @@ -187,7 +190,7 @@ function Start-BuildNativeWindowsBinaries { return } - # cmake is needed to build powershell.exe + # cmake is needed to build pwsh.exe if (-not (precheck 'cmake' $null)) { throw 'cmake not found. Run "Start-PSBootstrap -BuildWindowsNative". You can also install it from https://chocolatey.org/packages/cmake' } @@ -199,8 +202,16 @@ function Start-BuildNativeWindowsBinaries { throw 'Win 10 SDK not found. Run "Start-PSBootstrap -BuildWindowsNative" or install Microsoft Windows 10 SDK from https://developer.microsoft.com/en-US/windows/downloads/windows-10-sdk' } - $vcPath = (Get-Item(Join-Path -Path "$env:VS140COMNTOOLS" -ChildPath '../../vc')).FullName + if ($env:VS140COMNTOOLS -ne $null) { + $vcPath = (Get-Item(Join-Path -Path "$env:VS140COMNTOOLS" -ChildPath '../../vc')).FullName + } else { + $vcPath = (Get-ChildItem "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2017" -Filter "VC" -Directory -Recurse | Select-Object -First 1).FullName + } + $atlMfcIncludePath = Join-Path -Path $vcPath -ChildPath 'atlmfc/include' + if (!(Test-Path $atlMfcIncludePath)) { # for VS2017, need to search for it + $atlMfcIncludePath = (Get-ChildItem $vcPath -Filter AtlBase.h -Recurse -File | Select-Object -First 1).DirectoryName + } # atlbase.h is included in the pwrshplugin project if ((Test-Path -Path $atlMfcIncludePath\atlbase.h) -eq $false) { @@ -208,44 +219,64 @@ function Start-BuildNativeWindowsBinaries { } # vcvarsall.bat is used to setup environment variables - if ((Test-Path -Path $vcPath\vcvarsall.bat) -eq $false) { - throw "Could not find Visual Studio vcvarsall.bat at $vcPath. Please ensure the optional feature 'Common Tools for Visual C++' is installed." + $vcvarsallbatPath = "$vcPath\vcvarsall.bat" + if (!(Test-Path -Path $vcvarsallbatPath)) { # for VS2017, need to search for it + $vcvarsallbatPath = (Get-ChildItem $vcPath -Filter vcvarsall.bat -Recurse -File | Select-Object -First 1).FullName + } + + if ((Test-Path -Path $vcvarsallbatPath) -eq $false) { + throw "Could not find Visual Studio vcvarsall.bat at $vcvarsallbatPath. Please ensure the optional feature 'Common Tools for Visual C++' is installed." } - log "Start building native Windows binaries" + Write-Log "Start building native Windows binaries" + + if ($Clean) { + git clean -fdx + Remove-Item $HOME\source\cmakecache.txt -ErrorAction SilentlyContinue + } try { Push-Location "$PSScriptRoot\src\powershell-native" # setup cmakeGenerator + $cmakeGeneratorPlatform = "" if ($Arch -eq 'x86') { - $cmakeGenerator = 'Visual Studio 14 2015' + $cmakeGenerator = 'Visual Studio 15 2017' + $cmakeArch = 'x86' + } elseif ($Arch -eq 'x64_arm') { + $cmakeGenerator = 'Visual Studio 15 2017 ARM' + $cmakeArch = 'arm' + } elseif ($Arch -eq 'x64_arm64') { + $cmakeGenerator = 'Visual Studio 15 2017' + $cmakeArch = 'arm64' + $cmakeGeneratorPlatform = "-A ARM64" } else { - $cmakeGenerator = 'Visual Studio 14 2015 Win64' + $cmakeGenerator = 'Visual Studio 15 2017 Win64' + $cmakeArch = 'x64' } # Compile native resources $currentLocation = Get-Location - @("nativemsh/pwrshplugin") | ForEach-Object { + @("nativemsh\pwrshplugin") | ForEach-Object { $nativeResourcesFolder = $_ Get-ChildItem $nativeResourcesFolder -Filter "*.mc" | ForEach-Object { $command = @" -cmd.exe /C cd /d "$currentLocation" "&" "$($vcPath)\vcvarsall.bat" "$Arch" "&" mc.exe -o -d -c -U "$($_.FullName)" -h "$nativeResourcesFolder" -r "$nativeResourcesFolder" +cmd.exe /C cd /d "$currentLocation" "&" "$vcvarsallbatPath" "$Arch" "&" mc.exe -o -d -c -U "$($_.FullName)" -h "$currentLocation\$nativeResourcesFolder" -r "$currentLocation\$nativeResourcesFolder" "@ - log " Executing mc.exe Command: $command" - Start-NativeExecution { Invoke-Expression -Command:$command 2>&1 } + Write-Log " Executing mc.exe Command: $command" + Start-NativeExecution { Invoke-Expression -Command:$command } } } + # make sure we use version we installed and not from VS + $cmakePath = (Get-Command cmake).Source # Disabling until I figure out if it is necessary # $overrideFlags = "-DCMAKE_USER_MAKE_RULES_OVERRIDE=$PSScriptRoot\src\powershell-native\windows-compiler-override.txt" $overrideFlags = "" - $location = Get-Location - $command = @" -cmd.exe /C cd /d "$location" "&" "$($vcPath)\vcvarsall.bat" "$Arch" "&" cmake "$overrideFlags" -DBUILD_ONECORE=ON -DBUILD_TARGET_ARCH=$Arch -G "$cmakeGenerator" . "&" msbuild ALL_BUILD.vcxproj "/p:Configuration=$Configuration" +cmd.exe /C cd /d "$currentLocation" "&" "$vcvarsallbatPath" "$Arch" "&" "$cmakePath" "$overrideFlags" -DBUILD_ONECORE=ON -DBUILD_TARGET_ARCH=$cmakeArch -G "$cmakeGenerator" $cmakeGeneratorPlatform "$currentLocation" "&" msbuild ALL_BUILD.vcxproj "/p:Configuration=$Configuration" "@ - log " Executing Build Command: $command" + Write-Log " Executing Build Command: $command" Start-NativeExecution { Invoke-Expression -Command:$command } # Copy the binaries from the local build directory to the packaging directory @@ -254,13 +285,30 @@ cmd.exe /C cd /d "$location" "&" "$($vcPath)\vcvarsall.bat" "$Arch" "&" cmake "$ $FilesToCopy | ForEach-Object { $srcPath = [IO.Path]::Combine((Get-Location), "bin", $Configuration, "CoreClr/$_") - log " Copying $srcPath to $dstPath" + Write-Log " Copying $srcPath to $dstPath" Copy-Item $srcPath $dstPath } - # Place the remoting configuration script in the same directory - # as the binary so it will get published. - Copy-Item .\Install-PowerShellRemoting.ps1 $dstPath + # + # Build the ETW manifest resource-only binary + # + $location = "$PSScriptRoot\src\PowerShell.Core.Instrumentation" + Set-Location -Path $location + + Remove-Item $HOME\source\cmakecache.txt -ErrorAction SilentlyContinue + + $command = @" +cmd.exe /C cd /d "$location" "&" "$vcvarsallbatPath" "$Arch" "&" "$cmakePath" "$overrideFlags" -DBUILD_ONECORE=ON -DBUILD_TARGET_ARCH=$cmakeArch -G "$cmakeGenerator" $cmakeGeneratorPlatform "$location" "&" msbuild ALL_BUILD.vcxproj "/p:Configuration=$Configuration" +"@ + Write-Log " Executing Build Command for PowerShell.Core.Instrumentation: $command" + Start-NativeExecution { Invoke-Expression -Command:$command } + + # Copy the binary to the packaging directory + # NOTE: No PDB file; it's a resource-only DLL. + # VS2017 puts this in $HOME\source + $srcPath = [IO.Path]::Combine($HOME, "source", $Configuration, 'PowerShell.Core.Instrumentation.dll') + Copy-Item -Path $srcPath -Destination $dstPath + } finally { Pop-Location } @@ -306,7 +354,7 @@ function Start-BuildNativeUnixBinaries { $Native = "$PSScriptRoot/src/libpsl-native" $Lib = "$PSScriptRoot/src/powershell-unix/libpsl-native.$Ext" - log "Start building $Lib" + Write-Log "Start building $Lib" git clean -qfdX $Native @@ -343,6 +391,7 @@ function Start-PSBuild { [switch]$TypeGen, [switch]$Clean, [switch]$PSModuleRestore, + [switch]$CI, # this switch will re-build only System.Management.Automation.dll # it's useful for development, to do a quick changes in the engine @@ -350,11 +399,14 @@ function Start-PSBuild { # These runtimes must match those in project.json # We do not use ValidateScript since we want tab completion + # If this parameter is not provided it will get determined automatically. [ValidateSet("win7-x64", "win7-x86", "osx.10.12-x64", "linux-x64", - "linux-arm")] + "linux-arm", + "win-arm", + "win-arm64")] [string]$Runtime, [ValidateSet('Linux', 'Debug', 'Release', 'CodeCoverage', '')] # We might need "Checked" as well @@ -362,7 +414,7 @@ function Start-PSBuild { [switch]$CrossGen, - [ValidatePattern("^v\d+\.\d+\.\d+(-\w+\.\d+)?$")] + [ValidatePattern("^v\d+\.\d+\.\d+(-\w+(\.\d+)?)?$")] [ValidateNotNullOrEmpty()] [string]$ReleaseTag ) @@ -371,8 +423,12 @@ function Start-PSBuild { throw "Cross compiling for linux-arm is only supported on Ubuntu environment" } + if ("win-arm","win-arm64" -contains $Runtime -and -not $Environment.IsWindows) { + throw "Cross compiling for win-arm or win-arm64 is only supported on Windows environment" + } + function Stop-DevPowerShell { - Get-Process powershell* | + Get-Process pwsh* | Where-Object { $_.Modules | Where-Object { @@ -383,7 +439,7 @@ function Start-PSBuild { } if ($Clean) { - log "Cleaning your working directory. You can also do it with 'git clean -fdX'" + Write-Log "Cleaning your working directory. You can also do it with 'git clean -fdX'" Push-Location $PSScriptRoot try { git clean -fdX @@ -397,9 +453,6 @@ function Start-PSBuild { } } - # create the telemetry flag file - $null = new-item -force -type file "$psscriptroot/DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY" - # Add .NET CLI tools to PATH Find-Dotnet @@ -438,6 +491,7 @@ Fix steps: Configuration=$Configuration Verbose=$true SMAOnly=[bool]$SMAOnly + PSModuleRestore=$PSModuleRestore } $script:Options = New-PSOptions @OptionsArguments @@ -446,7 +500,7 @@ Fix steps: } # setup arguments - $Arguments = @("publish") + $Arguments = @("publish","--no-restore","/property:GenerateFullPaths=true") if ($Output) { $Arguments += "--output", $Output } @@ -468,48 +522,36 @@ Fix steps: } # handle Restore - if ($Restore -or -not (Test-Path "$($Options.Top)/obj/project.assets.json")) { - log "Run dotnet restore" - - $srcProjectDirs = @($Options.Top, "$PSScriptRoot/src/TypeCatalogGen", "$PSScriptRoot/src/ResGen") - $testProjectDirs = Get-ChildItem "$PSScriptRoot/test/*.csproj" -Recurse | ForEach-Object { [System.IO.Path]::GetDirectoryName($_) } - - $RestoreArguments = @("--verbosity") - if ($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent) { - $RestoreArguments += "detailed" - } else { - $RestoreArguments += "quiet" - } - - ($srcProjectDirs + $testProjectDirs) | ForEach-Object { Start-NativeExecution { dotnet restore $_ $RestoreArguments } } - } + Restore-PSPackage -Options $Options -Force:$Restore # handle ResGen # Heuristic to run ResGen on the fresh machine if ($ResGen -or -not (Test-Path "$PSScriptRoot/src/Microsoft.PowerShell.ConsoleHost/gen")) { - log "Run ResGen (generating C# bindings for resx files)" + Write-Log "Run ResGen (generating C# bindings for resx files)" Start-ResGen } - # handle TypeGen - if ($TypeGen -or -not (Test-Path "$PSScriptRoot/src/System.Management.Automation/CoreCLR/CorePsTypeCatalog.cs")) { - log "Run TypeGen (generating CorePsTypeCatalog.cs)" - Start-TypeGen + # Handle TypeGen + # .inc file name must be different for Windows and Linux to allow build on Windows and WSL. + $incFileName = "powershell_$($Options.Runtime).inc" + if ($TypeGen -or -not (Test-Path "$PSScriptRoot/src/TypeCatalogGen/$incFileName")) { + Write-Log "Run TypeGen (generating CorePsTypeCatalog.cs)" + Start-TypeGen -IncFileName $incFileName } - # Get the folder path where powershell.exe is located. + # Get the folder path where pwsh.exe is located. $publishPath = Split-Path $Options.Output -Parent try { # Relative paths do not work well if cwd is not changed to project Push-Location $Options.Top - log "Run dotnet $Arguments from $pwd" + Write-Log "Run dotnet $Arguments from $pwd" Start-NativeExecution { dotnet $Arguments } if ($CrossGen) { Start-CrossGen -PublishPath $publishPath -Runtime $script:Options.Runtime - log "PowerShell.exe with ngen binaries is available at: $($Options.Output)" + Write-Log "pwsh.exe with ngen binaries is available at: $($Options.Output)" } else { - log "PowerShell output: $($Options.Output)" + Write-Log "PowerShell output: $($Options.Output)" } } finally { Pop-Location @@ -518,7 +560,7 @@ Fix steps: # publish netcoreapp2.0 reference assemblies try { Push-Location "$PSScriptRoot/src/TypeCatalogGen" - $refAssemblies = Get-Content -Path "powershell.inc" | Where-Object { $_ -like "*microsoft.netcore.app*" } | ForEach-Object { $_.TrimEnd(';') } + $refAssemblies = Get-Content -Path $incFileName | Where-Object { $_ -like "*microsoft.netcore.app*" } | ForEach-Object { $_.TrimEnd(';') } $refDestFolder = Join-Path -Path $publishPath -ChildPath "ref" if (Test-Path $refDestFolder -PathType Container) { @@ -543,28 +585,107 @@ Fix steps: } } + if ($Environment.IsWindows) { + ## need RCEdit to modify the binaries embedded resources + if (-not (Test-Path "~/.rcedit/rcedit-x64.exe")) { + throw "RCEdit is required to modify pwsh.exe resources, please run 'Start-PSBootStrap' to install" + } + + $ReleaseVersion = "" + if ($ReleaseTagToUse) { + $ReleaseVersion = $ReleaseTagToUse + } else { + $ReleaseVersion = (Get-PSCommitId -WarningAction SilentlyContinue) -replace '^v' + } + # in VSCode, depending on where you started it from, the git commit id may be empty so provide a default value + if (!$ReleaseVersion) { + $ReleaseVersion = "6.0.0" + $fileVersion = "6.0.0" + } else { + $fileVersion = $ReleaseVersion.Split("-")[0] + } + + # in VSCode, the build output folder doesn't include the name of the exe so we have to add it for rcedit + $pwshPath = $Options.Output + if (!$pwshPath.EndsWith("pwsh.exe")) { + $pwshPath = Join-Path $Options.Output "pwsh.exe" + } + + Start-NativeExecution { & "~/.rcedit/rcedit-x64.exe" $pwshPath --set-icon "$PSScriptRoot\assets\Powershell_black.ico" ` + --set-file-version $fileVersion --set-product-version $ReleaseVersion --set-version-string "ProductName" "PowerShell Core 6" ` + --set-version-string "LegalCopyright" "(C) Microsoft Corporation. All Rights Reserved." ` + --application-manifest "$PSScriptRoot\assets\pwsh.manifest" } | Write-Verbose + } + # download modules from powershell gallery. # - PowerShellGet, PackageManagement, Microsoft.PowerShell.Archive - if($PSModuleRestore) + if ($PSModuleRestore) { + Restore-PSModuleToBuild -PublishPath $publishPath + } + + # Restore the Pester module + if ($CI) { + Restore-PSPester -Destination (Join-Path $publishPath "Modules") + } +} + +function Restore-PSPackage +{ + param( + [ValidateNotNullOrEmpty()] + [Parameter()] + [string[]] $ProjectDirs, + + [ValidateNotNullOrEmpty()] + [Parameter()] + $Options = (Get-PSOptions -DefaultToNew), + + [switch] $Force + ) + + if (-not $ProjectDirs) { - $ProgressPreference = "SilentlyContinue" - log "Restore PowerShell modules to $publishPath" + $ProjectDirs = @($Options.Top, "$PSScriptRoot/src/TypeCatalogGen", "$PSScriptRoot/src/ResGen", "$PSScriptRoot/src/Modules") + } - $modulesDir = Join-Path -Path $publishPath -ChildPath "Modules" + if ($Force -or (-not (Test-Path "$($Options.Top)/obj/project.assets.json"))) { - # Restore modules from myget feed - Restore-PSModule -Destination $modulesDir -Name @( - # PowerShellGet depends on PackageManagement module, so PackageManagement module will be installed with the PowerShellGet module. - 'PowerShellGet' - ) + $RestoreArguments = @("--runtime",$Options.Runtime,"--verbosity") + if ($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent) { + $RestoreArguments += "detailed" + } else { + $RestoreArguments += "quiet" + } - # Restore modules from powershellgallery feed - Restore-PSModule -Destination $modulesDir -Name @( - 'Microsoft.PowerShell.Archive' - ) -SourceLocation "https://www.powershellgallery.com/api/v2/" + $ProjectDirs | ForEach-Object { + Write-Log "Run dotnet restore $_ $RestoreArguments" + Start-NativeExecution { dotnet restore $_ $RestoreArguments } + } } } +function Restore-PSModuleToBuild +{ + param( + [Parameter(Mandatory)] + [string] + $PublishPath + ) + + Write-Log "Restore PowerShell modules to $publishPath" + $modulesDir = Join-Path -Path $publishPath -ChildPath "Modules" + Copy-PSGalleryModules -Destination $modulesDir +} + +function Restore-PSPester +{ + param( + [ValidateNotNullOrEmpty()] + [string] $Destination = ([IO.Path]::Combine((Split-Path (Get-PSOptions -DefaultToNew).Output), "Modules")) + ) + Save-Module -Name Pester -Path $Destination -Repository PSGallery +} + function Compress-TestContent { [CmdletBinding()] param( @@ -595,14 +716,18 @@ function New-PSOptions { "win7-x64", "osx.10.12-x64", "linux-x64", - "linux-arm")] + "linux-arm", + "win-arm", + "win-arm64")] [string]$Runtime, [switch]$CrossGen, [string]$Output, - [switch]$SMAOnly + [switch]$SMAOnly, + + [switch]$PSModuleRestore ) # Add .NET CLI tools to PATH @@ -680,9 +805,9 @@ function New-PSOptions { } $Executable = if ($Environment.IsLinux -or $Environment.IsMacOS) { - "powershell" + "pwsh" } elseif ($Environment.IsWindows) { - "powershell.exe" + "pwsh.exe" } # Build the Output path @@ -711,19 +836,39 @@ function New-PSOptions { } return @{ RootInfo = [PSCustomObject]$RootInfo - Top = $Top; - Configuration = $Configuration; - Framework = $Framework; - Runtime = $Runtime; - Output = $Output; - CrossGen = $CrossGen } + Top = $Top + Configuration = $Configuration + Framework = $Framework + Runtime = $Runtime + Output = $Output + CrossGen = $CrossGen.IsPresent + PSModuleRestore = $PSModuleRestore.IsPresent } } # Get the Options of the last build function Get-PSOptions { + param( + [Parameter(HelpMessage='Defaults to New-PSOption if a build has not ocurred.')] + [switch] + $DefaultToNew + ) + + if(!$script:Options -and $DefaultToNew.IsPresent) + { + return New-PSOptions + } + return $script:Options } +function Set-PSOptions { + param( + [PSObject] + $Options + ) + + $script:Options = $Options +} function Get-PSOutput { [CmdletBinding()]param( @@ -738,7 +883,6 @@ function Get-PSOutput { } } - function Get-PesterTag { param ( [Parameter(Position=0)][string]$testbase = "$PSScriptRoot/test/powershell" ) $alltags = @{} @@ -761,7 +905,7 @@ function Get-PesterTag { } $values = $vAst.FindAll({$args[0] -is "System.Management.Automation.Language.StringConstantExpressionAst"},$true).Value $values | ForEach-Object { - if (@('REQUIREADMINONWINDOWS', 'SLOW') -contains $_) { + if (@('REQUIREADMINONWINDOWS', 'REQUIRESUDOONUNIX', 'SLOW') -contains $_) { # These are valid tags also, but they are not the priority tags } elseif (@('CI', 'FEATURE', 'SCENARIO') -contains $_) { @@ -805,10 +949,8 @@ function Publish-PSTestTools { @{Path="${PSScriptRoot}/test/tools/TestExe";Output="testexe"} @{Path="${PSScriptRoot}/test/tools/WebListener";Output="WebListener"} ) - if ($null -eq $Options) - { - $Options = New-PSOptions - } + + $Options = Get-PSOptions -DefaultToNew # Publish tools so it can be run by tests foreach ($tool in $tools) @@ -836,8 +978,8 @@ function Start-PSPester { [string[]]$Tag = @("CI","Feature"), [string[]]$Path = @("$PSScriptRoot/test/common","$PSScriptRoot/test/powershell"), [switch]$ThrowOnFailure, - [string]$binDir = (Split-Path (New-PSOptions).Output), - [string]$powershell = (Join-Path $binDir 'powershell'), + [string]$binDir = (Split-Path (Get-PSOptions -DefaultToNew).Output), + [string]$powershell = (Join-Path $binDir 'pwsh'), [string]$Pester = ([IO.Path]::Combine($binDir, "Modules", "Pester")), [Parameter(ParameterSetName='Unelevate',Mandatory=$true)] [switch]$Unelevate, @@ -845,15 +987,17 @@ function Start-PSPester { [switch]$Terse, [Parameter(ParameterSetName='PassThru',Mandatory=$true)] [switch]$PassThru, + [Parameter(ParameterSetName='PassThru',HelpMessage='Run commands on Linux with sudo.')] + [switch]$Sudo, [switch]$IncludeFailingTest ) - if (-not (Get-Module -ListAvailable -Name $Pester -ErrorAction SilentlyContinue)) + if (-not (Get-Module -ListAvailable -Name $Pester -ErrorAction SilentlyContinue)) { Write-Warning @" Pester module not found. -Make sure that the proper git submodules are installed by running: - git submodule update --init +Restore the module to '$Pester' by running: + Restore-PSPester "@ return; } @@ -888,57 +1032,73 @@ Make sure that the proper git submodules are installed by running: $ExcludeTag += 'RequireAdminOnWindows' } } + elseif (-not $Environment.IsWindows -and (-not $Sudo.IsPresent)) + { + if (-not $PSBoundParameters.ContainsKey('ExcludeTag')) + { + $ExcludeTag += 'RequireSudoOnUnix' + } + } + elseif (-not $Environment.IsWindows -and $Sudo.IsPresent) + { + if (-not $PSBoundParameters.ContainsKey('Tag')) + { + $Tag = 'RequireSudoOnUnix' + } + } Write-Verbose "Running pester tests at '$path' with tag '$($Tag -join ''', ''')' and ExcludeTag '$($ExcludeTag -join ''', ''')'" -Verbose Publish-PSTestTools | ForEach-Object {Write-Host $_} # All concatenated commands/arguments are suffixed with the delimiter (space) - $Command = "" + + # Disable telemetry for all startups of pwsh in tests + $command = "`$env:POWERSHELL_TELEMETRY_OPTOUT = 1;" if ($Terse) { - $Command += "`$ProgressPreference = 'silentlyContinue'; " + $command += "`$ProgressPreference = 'silentlyContinue'; " } # Autoload (in subprocess) temporary modules used in our tests - $Command += '$env:PSModulePath = '+"'$TestModulePath$TestModulePathSeparator'" + '+$($env:PSModulePath);' + $command += '$env:PSModulePath = '+"'$TestModulePath$TestModulePathSeparator'" + '+$($env:PSModulePath);' # Windows needs the execution policy adjusted if ($Environment.IsWindows) { - $Command += "Set-ExecutionPolicy -Scope Process Unrestricted; " + $command += "Set-ExecutionPolicy -Scope Process Unrestricted; " } - $Command += "Import-Module '$Pester'; " + $command += "Import-Module '$Pester'; " if ($Unelevate) { $outputBufferFilePath = [System.IO.Path]::GetTempFileName() } - $Command += "Invoke-Pester " + $command += "Invoke-Pester " - $Command += "-OutputFormat ${OutputFormat} -OutputFile ${OutputFile} " + $command += "-OutputFormat ${OutputFormat} -OutputFile ${OutputFile} " if ($ExcludeTag -and ($ExcludeTag -ne "")) { - $Command += "-ExcludeTag @('" + (${ExcludeTag} -join "','") + "') " + $command += "-ExcludeTag @('" + (${ExcludeTag} -join "','") + "') " } if ($Tag) { - $Command += "-Tag @('" + (${Tag} -join "','") + "') " + $command += "-Tag @('" + (${Tag} -join "','") + "') " } # sometimes we need to eliminate Pester output, especially when we're # doing a daily build as the log file is too large if ( $Quiet ) { - $Command += "-Quiet " + $command += "-Quiet " } if ( $PassThru ) { - $Command += "-PassThru " + $command += "-PassThru " } - $Command += "'" + ($Path -join "','") + "'" + $command += "'" + ($Path -join "','") + "'" if ($Unelevate) { - $Command += " *> $outputBufferFilePath; '__UNELEVATED_TESTS_THE_END__' >> $outputBufferFilePath" + $command += " *> $outputBufferFilePath; '__UNELEVATED_TESTS_THE_END__' >> $outputBufferFilePath" } - Write-Verbose $Command + Write-Verbose $command $script:nonewline = $true $script:inerror = $false @@ -960,6 +1120,14 @@ Make sure that the proper git submodules are installed by running: $script:nonewline = $true $script:inerror = $false } + elseif ($trimmedline.StartsWith("Executing script ")) { + # Skip lines where Pester reports that is executing a test script + return + } + elseif ($trimmedline -match "^\d+(\.\d+)?m?s$") { + # Skip the time elapse like '12ms', '1ms', '1.2s' and '12.53s' + return + } else { if ($script:nonewline) { Write-Host "`n" -NoNewline @@ -986,6 +1154,8 @@ Make sure that the proper git submodules are installed by running: # To ensure proper testing, the module path must not be inherited by the spawned process try { $originalModulePath = $env:PSModulePath + $originalTelemetry = $env:POWERSHELL_TELEMETRY_OPTOUT + $env:POWERSHELL_TELEMETRY_OPTOUT = 1 if ($Unelevate) { Start-UnelevatedProcess -process $powershell -arguments @('-noprofile', '-c', $Command) @@ -1027,36 +1197,42 @@ Make sure that the proper git submodules are installed by running: $passThruFile = [System.IO.Path]::GetTempFileName() try { - $Command += "|Export-Clixml -Path '$passThruFile' -Force" - if ($Terse) - { - Start-NativeExecution -sb {& $powershell -noprofile -c $Command} | ForEach-Object { Write-Terse $_} + $command += "|Export-Clixml -Path '$passThruFile' -Force" + + $passThruCommand = {& $powershell -noprofile -c $command } + if ($Sudo.IsPresent) { + $passThruCommand = {& sudo $powershell -noprofile -c $command } } - else + + $writeCommand = { Write-Host $_ } + if ($Terse) { - Start-NativeExecution -sb {& $powershell -noprofile -c $Command} | ForEach-Object { Write-Host $_} + $writeCommand = { Write-Terse $_ } } + + Start-NativeExecution -sb $passThruCommand | ForEach-Object $writeCommand Import-Clixml -Path $passThruFile | Where-Object {$_.TotalCount -is [Int32]} } finally { - Remove-Item $passThruFile -ErrorAction SilentlyContinue + Remove-Item $passThruFile -ErrorAction SilentlyContinue -Force } } else { if ($Terse) { - Start-NativeExecution -sb {& $powershell -noprofile -c $Command} | ForEach-Object { Write-Terse -line $_ } + Start-NativeExecution -sb {& $powershell -noprofile -c $command} | ForEach-Object { Write-Terse -line $_ } } else { - Start-NativeExecution -sb {& $powershell -noprofile -c $Command} + Start-NativeExecution -sb {& $powershell -noprofile -c $command} } } } } finally { $env:PSModulePath = $originalModulePath + $env:POWERSHELL_TELEMETRY_OPTOUT = $originalTelemetry if ($Unelevate) { Remove-Item $outputBufferFilePath @@ -1112,15 +1288,62 @@ function Show-PSPesterError throw 'Unknown Show-PSPester parameter set' } - logerror ("Description: " + $description) - logerror ("Name: " + $name) - logerror "message:" - logerror $message - logerror "stack-trace:" - logerror $stackTrace + Write-Log -Error ("Description: " + $description) + Write-Log -Error ("Name: " + $name) + Write-Log -Error "message:" + Write-Log -Error $message + Write-Log -Error "stack-trace:" + Write-Log -Error $stackTrace } +function Test-XUnitTestResults +{ + param( + [Parameter(Mandatory)] + [ValidateNotNullOrEmpty()] + [string] $TestResultsFile + ) + + if(-not (Test-Path $TestResultsFile)) + { + throw "File not found $TestResultsFile" + } + + try + { + $results = [xml] (Get-Content $TestResultsFile) + } + catch + { + throw "Cannot convert $TestResultsFile to xml : $($_.message)" + } + + $failedTests = $results.assemblies.assembly.collection | Where-Object failed -gt 0 + + if(-not $failedTests) + { + return $true + } + + foreach($failure in $failedTests) + { + $description = $failure.test.type + $name = $failure.test.method + $message = $failure.test.failure.message.'#cdata-section' + $stackTrace = $failure.test.failure.'stack-trace'.'#cdata-section' + + Write-Log -Error ("Description: " + $description) + Write-Log -Error ("Name: " + $name) + Write-Log -Error "message:" + Write-Log -Error $message + Write-Log -Error "stack-trace:" + Write-Log -Error $stackTrace + } + + throw "$($failedTests.failed) tests failed" +} + # # Read the test result file and # Throw if a test failed @@ -1146,7 +1369,7 @@ function Test-PSPesterResults $x = [xml](Get-Content -raw $testResultsFile) if ([int]$x.'test-results'.failures -gt 0) { - logerror "TEST FAILURES" + Write-Log -Error "TEST FAILURES" # switch between methods, SelectNode is not available on dotnet core if ( "System.Xml.XmlDocumentXPathExtensions" -as [Type] ) { @@ -1171,7 +1394,7 @@ function Test-PSPesterResults } elseif ($ResultObject.FailedCount -gt 0) { - logerror 'TEST FAILURES' + Write-Log -Error 'TEST FAILURES' $ResultObject.TestResult | Where-Object {$_.Passed -eq $false} | ForEach-Object { Show-PSPesterError -testFailureObject $_ @@ -1182,53 +1405,73 @@ function Test-PSPesterResults } } - function Start-PSxUnit { - [CmdletBinding()]param() - - log "xUnit tests are currently disabled pending fixes due to API and AssemblyLoadContext changes - @andschwa" - return - - if ($Environment.IsWindows) { - throw "xUnit tests are only currently supported on Linux / OS X" - } - - if ($Environment.IsMacOS) { - log "Not yet supported on OS X, pretending they passed..." - return - } + [CmdletBinding()]param( + [string] $SequentialTestResultsFile = "SequentialXUnitResults.xml", + [string] $ParallelTestResultsFile = "ParallelXUnitResults.xml" + ) # Add .NET CLI tools to PATH Find-Dotnet - $Arguments = "--configuration", "Linux", "-parallel", "none" - if ($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent) { - $Arguments += "-verbose" - } - $Content = Split-Path -Parent (Get-PSOutput) if (-not (Test-Path $Content)) { throw "PowerShell must be built before running tests!" } + if (Test-Path $SequentialTestResultsFile) { + Remove-Item $SequentialTestResultsFile -Force -ErrorAction SilentlyContinue + } + if (Test-Path $ParallelTestResultsFile) { + Remove-Item $ParallelTestResultsFile -Force -ErrorAction SilentlyContinue + } + try { Push-Location $PSScriptRoot/test/csharp + # Path manipulation to obtain test project output directory - $Output = Join-Path $pwd ((Split-Path -Parent (Get-PSOutput)) -replace (New-PSOptions).Top) - Write-Verbose "Output is $Output" + dotnet restore - Copy-Item -ErrorAction SilentlyContinue -Recurse -Path $Content/* -Include Modules,libpsl-native* -Destination $Output - Start-NativeExecution { dotnet test $Arguments } + if(-not $Environment.IsWindows) + { + if($Environment.IsMacOS) + { + $nativeLib = "$Content/libpsl-native.dylib" + } + else + { + $nativeLib = "$Content/libpsl-native.so" + } + + $requiredDependencies = @( + $nativeLib, + "$Content/Microsoft.Management.Infrastructure.dll", + "$Content/System.Text.Encoding.CodePages.dll" + ) - if ($LASTEXITCODE -ne 0) { - throw "$LASTEXITCODE xUnit tests failed" + if((Test-Path $requiredDependencies) -notcontains $false) + { + $options = New-PSOptions + $Destination = "bin/$($options.configuration)/$($options.framework)" + New-Item $Destination -ItemType Directory -Force > $null + Copy-Item -Path $requiredDependencies -Destination $Destination -Force + } + else + { + throw "Dependencies $requiredDependencies not met." + } } - } finally { + + # '-fxversion' workaround required due to https://github.com/dotnet/cli/issues/7901#issuecomment-343323674 + # Run sequential tests first, and then run the tests that can execute in parallel + dotnet xunit -fxversion 2.0.5 -configuration $Options.configuration -xml $SequentialTestResultsFile -namespace "PSTests.Sequential" -parallel none + dotnet xunit -fxversion 2.0.5 -configuration $Options.configuration -xml $ParallelTestResultsFile -namespace "PSTests.Parallel" -nobuild + } + finally { Pop-Location } } - function Install-Dotnet { [CmdletBinding()] param( @@ -1288,8 +1531,6 @@ function Get-RedHatPackageManager { "yum install -y -q" } elseif ($Environment.IsFedora) { "dnf install -y -q" - } elseif ($Environment.IsOpenSUSE) { - "zypper --non-interactive install" } else { throw "Error determining package manager for this distribution." } @@ -1311,7 +1552,7 @@ function Start-PSBootstrap { [switch]$Force ) - log "Installing PowerShell build dependencies" + Write-Log "Installing PowerShell build dependencies" Push-Location $PSScriptRoot/tools @@ -1352,12 +1593,21 @@ function Start-PSBootstrap { elseif ($Environment.IsUbuntu16) { $Deps += "libicu55" } # Packaging tools - if ($Package) { $Deps += "ruby-dev", "groff" } + if ($Package) { $Deps += "ruby-dev", "groff", "libffi-dev" } # Install dependencies - Start-NativeExecution { - Invoke-Expression "$sudo apt-get update -qq" - Invoke-Expression "$sudo apt-get install -y -qq $Deps" + # change the fontend from apt-get to noninteractive + $originalDebianFrontEnd=$env:DEBIAN_FRONTEND + $env:DEBIAN_FRONTEND='noninteractive' + try { + Start-NativeExecution { + Invoke-Expression "$sudo apt-get update -qq" + Invoke-Expression "$sudo apt-get install -y -qq $Deps" + } + } + finally { + # change the apt frontend back to the original + $env:DEBIAN_FRONTEND=$originalDebianFrontEnd } } elseif ($Environment.IsRedHatFamily) { # Build tools @@ -1367,7 +1617,7 @@ function Start-PSBootstrap { $Deps += "libicu", "libunwind" # Packaging tools - if ($Package) { $Deps += "ruby-devel", "rpm-build", "groff" } + if ($Package) { $Deps += "ruby-devel", "rpm-build", "groff", 'libffi-devel' } $PackageManager = Get-RedHatPackageManager @@ -1379,6 +1629,26 @@ function Start-PSBootstrap { $baseCommand = $PackageManager } + # Install dependencies + Start-NativeExecution { + Invoke-Expression "$baseCommand $Deps" + } + } elseif ($Environment.IsSUSEFamily) { + # Build tools + $Deps += "gcc", "cmake", "make" + + # Packaging tools + if ($Package) { $Deps += "ruby-devel", "rpmbuild", "groff", 'libffi-devel' } + + $PackageManager = "zypper --non-interactive install" + $baseCommand = "$sudo $PackageManager" + + # On OpenSUSE 13.2 container, sudo does not exist, so don't use it if not needed + if($NoSudo) + { + $baseCommand = $PackageManager + } + # Install dependencies Start-NativeExecution { Invoke-Expression "$baseCommand $Deps" @@ -1397,15 +1667,20 @@ function Start-PSBootstrap { Start-NativeExecution { brew install $Deps } -IgnoreExitcode # Install patched version of curl - Start-NativeExecution { brew install curl --with-openssl } -IgnoreExitcode + Start-NativeExecution { brew install curl --with-openssl --with-gssapi } -IgnoreExitcode } # Install [fpm](https://github.com/jordansissel/fpm) and [ronn](https://github.com/rtomayko/ronn) if ($Package) { try { - # We cannot guess if the user wants to run gem install as root - Start-NativeExecution { gem install fpm -v 1.8.1 } - Start-NativeExecution { gem install ronn } + # We cannot guess if the user wants to run gem install as root on linux and windows, + # but macOs usually requires sudo + $gemsudo = '' + if($Environment.IsMacOS) { + $gemsudo = $sudo + } + Start-NativeExecution ([ScriptBlock]::Create("$gemsudo gem install fpm -v 1.9.3")) + Start-NativeExecution ([ScriptBlock]::Create("$gemsudo gem install ronn -v 0.7.3")) } catch { Write-Warning "Installation of fpm and ronn gems failed! Must resolve manually." } @@ -1424,26 +1699,47 @@ function Start-PSBootstrap { if(!$dotNetExists -or $dotNetVersion -ne $dotnetCLIRequiredVersion -or $Force.IsPresent) { if($Force.IsPresent) { - log "Installing dotnet due to -Force." + Write-Log "Installing dotnet due to -Force." } elseif(!$dotNetExistis) { - log "dotnet not present. Installing dotnet." + Write-Log "dotnet not present. Installing dotnet." } else { - log "dotnet out of date ($dotNetVersion). Updating dotnet." + Write-Log "dotnet out of date ($dotNetVersion). Updating dotnet." } $DotnetArguments = @{ Channel=$Channel; Version=$Version; NoSudo=$NoSudo } Install-Dotnet @DotnetArguments } else { - log "dotnet is already installed. Skipping installation." + Write-Log "dotnet is already installed. Skipping installation." } # Install Windows dependencies if `-Package` or `-BuildWindowsNative` is specified if ($Environment.IsWindows) { + ## The VSCode build task requires 'pwsh.exe' to be found in Path + if (-not (Get-Command -Name pwsh.exe -CommandType Application -ErrorAction SilentlyContinue)) + { + Write-Log "pwsh.exe not found. Install latest PowerShell Core release and add it to Path" + $psInstallFile = [System.IO.Path]::Combine($PSScriptRoot, "tools", "install-powershell.ps1") + & $psInstallFile -AddToPath + } + + ## need RCEdit to modify the binaries embedded resources + if (-not (Test-Path "~/.rcedit/rcedit-x64.exe")) + { + Write-Log "Install RCEdit for modifying exe resources" + $rceditUrl = "https://github.com/electron/rcedit/releases/download/v1.0.0/rcedit-x64.exe" + New-Item -Path "~/.rcedit" -Type Directory -Force > $null + + ## need to specify TLS version 1.2 since GitHub API requires it + [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 + + Invoke-WebRequest -OutFile "~/.rcedit/rcedit-x64.exe" -Uri $rceditUrl + } + if ($BuildWindowsNative) { - log "Install Windows dependencies for building PSRP plugin" + Write-Log "Install Windows dependencies for building PSRP plugin" $machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE') $newMachineEnvironmentPath = $machinePath @@ -1455,40 +1751,40 @@ function Start-PSBootstrap { $chocolateyPath = "$env:AllUsersProfile\chocolatey\bin" if(precheck 'choco' $null) { - log "Chocolatey is already installed. Skipping installation." + Write-Log "Chocolatey is already installed. Skipping installation." } elseif(($cmakePresent -eq $false) -or ($sdkPresent -eq $false)) { - log "Chocolatey not present. Installing chocolatey." + Write-Log "Chocolatey not present. Installing chocolatey." if ($Force -or $PSCmdlet.ShouldProcess("Install chocolatey via https://chocolatey.org/install.ps1")) { Invoke-Expression ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')) if (-not ($machinePath.ToLower().Contains($chocolateyPath.ToLower()))) { - log "Adding $chocolateyPath to Path environment variable" + Write-Log "Adding $chocolateyPath to Path environment variable" $env:Path += ";$chocolateyPath" $newMachineEnvironmentPath += ";$chocolateyPath" } else { - log "$chocolateyPath already present in Path environment variable" + Write-Log "$chocolateyPath already present in Path environment variable" } } else { Write-Error "Chocolatey is required to install missing dependencies. Please install it from https://chocolatey.org/ manually. Alternatively, install cmake and Windows 10 SDK." return } } else { - log "Skipping installation of chocolatey, cause both cmake and Win 10 SDK are present." + Write-Log "Skipping installation of chocolatey, cause both cmake and Win 10 SDK are present." } # Install cmake $cmakePath = "${env:ProgramFiles}\CMake\bin" - if($cmakePresent) { - log "Cmake is already installed. Skipping installation." + if($cmakePresent -and !($force.IsPresent)) { + Write-Log "Cmake is already installed. Skipping installation." } else { - log "Cmake not present. Installing cmake." - Start-NativeExecution { choco install cmake -y --version 3.6.0 } + Write-Log "Cmake not present or -Force used. Installing cmake." + Start-NativeExecution { choco install cmake -y --version 3.10.0 } if (-not ($machinePath.ToLower().Contains($cmakePath.ToLower()))) { - log "Adding $cmakePath to Path environment variable" + Write-Log "Adding $cmakePath to Path environment variable" $env:Path += ";$cmakePath" $newMachineEnvironmentPath = "$cmakePath;$newMachineEnvironmentPath" } else { - log "$cmakePath already present in Path environment variable" + Write-Log "$cmakePath already present in Path environment variable" } } @@ -1496,15 +1792,15 @@ function Start-PSBootstrap { $packageName = "windows-sdk-10.0" if (-not $sdkPresent) { - log "Windows 10 SDK not present. Installing $packageName." + Write-Log "Windows 10 SDK not present. Installing $packageName." Start-NativeExecution { choco install windows-sdk-10.0 -y } } else { - log "Windows 10 SDK present. Skipping installation." + Write-Log "Windows 10 SDK present. Skipping installation." } # Update path machine environment variable if ($newMachineEnvironmentPath -ne $machinePath) { - log "Updating Path machine environment variable" + Write-Log "Updating Path machine environment variable" if ($Force -or $PSCmdlet.ShouldProcess("Update Path machine environment variable to $newMachineEnvironmentPath")) { [Environment]::SetEnvironmentVariable('Path', $newMachineEnvironmentPath, 'MACHINE') } @@ -1520,7 +1816,7 @@ function Publish-NuGetFeed { param( [string]$OutputPath = "$PSScriptRoot/nuget-artifacts", - [ValidatePattern("^v\d+\.\d+\.\d+(-\w+\.\d+)?$")] + [ValidatePattern("^v\d+\.\d+\.\d+(-\w+(\.\d+)?)?$")] [ValidateNotNullOrEmpty()] [string]$ReleaseTag ) @@ -1597,7 +1893,7 @@ function Start-DevPowerShell { # splatting for the win $startProcessArgs = @{ - FilePath = "$binDir\powershell" + FilePath = "$binDir\pwsh" ArgumentList = "$ArgumentList" } @@ -1622,7 +1918,11 @@ function Start-DevPowerShell { function Start-TypeGen { [CmdletBinding()] - param() + param + ( + [ValidateNotNullOrEmpty()] + $IncFileName = 'powershell.inc' + ) # Add .NET CLI tools to PATH Find-Dotnet @@ -1643,7 +1943,7 @@ function Start-TypeGen Push-Location "$PSScriptRoot/src/Microsoft.PowerShell.SDK" try { - $ps_inc_file = "$PSScriptRoot/src/TypeCatalogGen/powershell.inc" + $ps_inc_file = "$PSScriptRoot/src/TypeCatalogGen/$IncFileName" dotnet msbuild .\Microsoft.PowerShell.SDK.csproj /t:_GetDependencies "/property:DesignTimeBuild=true;_DependencyFile=$ps_inc_file" /nologo } finally { Pop-Location @@ -1651,7 +1951,7 @@ function Start-TypeGen Push-Location "$PSScriptRoot/src/TypeCatalogGen" try { - dotnet run ../System.Management.Automation/CoreCLR/CorePsTypeCatalog.cs powershell.inc + dotnet run ../System.Management.Automation/CoreCLR/CorePsTypeCatalog.cs $IncFileName } finally { Pop-Location } @@ -1673,16 +1973,25 @@ function Start-ResGen } } - function Find-Dotnet() { $originalPath = $env:PATH - $dotnetPath = if ($Environment.IsWindows) { - "$env:LocalAppData\Microsoft\dotnet" - } else { - "$env:HOME/.dotnet" - } + $dotnetPath = if ($Environment.IsWindows) { "$env:LocalAppData\Microsoft\dotnet" } else { "$env:HOME/.dotnet" } - if (-not (precheck 'dotnet' "Could not find 'dotnet', appending $dotnetPath to PATH.")) { + # If there dotnet is already in the PATH, check to see if that version of dotnet can find the required SDK + # This is "typically" the globally installed dotnet + if (precheck dotnet) { + # Must run from within repo to ensure global.json can specify the required SDK version + Push-Location $PSScriptRoot + $dotnetCLIInstalledVersion = (dotnet --version) + Pop-Location + if ($dotnetCLIInstalledVersion -ne $dotnetCLIRequiredVersion) { + Write-Warning "The 'dotnet' in the current path can't find SDK version ${dotnetCLIRequiredVersion}, prepending $dotnetPath to PATH." + # Globally installed dotnet doesn't have the required SDK version, prepend the user local dotnet location + $env:PATH = $dotnetPath + [IO.Path]::PathSeparator + $env:PATH + } + } + else { + Write-Warning "Could not find 'dotnet', appending $dotnetPath to PATH." $env:PATH += [IO.Path]::PathSeparator + $dotnetPath } @@ -1721,7 +2030,6 @@ function Convert-TxtResourceToXml } } - function script:Use-MSBuild { # TODO: we probably should require a particular version of msbuild, if we are taking this dependency # msbuild v14 and msbuild v4 behaviors are different for XAML generation @@ -1740,19 +2048,27 @@ function script:Use-MSBuild { Set-Alias msbuild $frameworkMsBuildLocation -Scope Script } +function script:Write-Log +{ + param + ( + [Parameter(Position=0, Mandatory)] + [ValidateNotNullOrEmpty()] + [string] $message, -function script:log([string]$message) { - Write-Host -Foreground Green $message - #reset colors for older package to at return to default after error message on a compilation error - [console]::ResetColor() -} - -function script:logerror([string]$message) { - Write-Host -Foreground Red $message + [switch] $error + ) + if ($error) + { + Write-Host -Foreground Red $message + } + else + { + Write-Host -Foreground Green $message + } #reset colors for older package to at return to default after error message on a compilation error [console]::ResetColor() } - function script:precheck([string]$command, [string]$missedMessage) { $c = Get-Command $command -ErrorAction SilentlyContinue if (-not $c) { @@ -1768,15 +2084,44 @@ function script:precheck([string]$command, [string]$missedMessage) { # this function wraps native command Execution # for more information, read https://mnaoumov.wordpress.com/2015/01/11/execution-of-external-commands-in-powershell-done-right/ -function script:Start-NativeExecution([scriptblock]$sb, [switch]$IgnoreExitcode) +function script:Start-NativeExecution { + param( + [scriptblock]$sb, + [switch]$IgnoreExitcode, + [switch]$VerboseOutputOnError + ) $backupEAP = $script:ErrorActionPreference $script:ErrorActionPreference = "Continue" try { - & $sb + if($VerboseOutputOnError.IsPresent) + { + $output = & $sb + } + else + { + & $sb + } + # note, if $sb doesn't have a native invocation, $LASTEXITCODE will # point to the obsolete value if ($LASTEXITCODE -ne 0 -and -not $IgnoreExitcode) { + if($VerboseOutputOnError.IsPresent -and $output) + { + $output | Out-String | Write-Verbose -Verbose + } + + # Get caller location for easier debugging + $caller = Get-PSCallStack -ErrorAction SilentlyContinue + if($caller) + { + $callerLocationParts = $caller[1].Location -split ":\s*line\s*" + $callerFile = $callerLocationParts[0] + $callerLine = $callerLocationParts[1] + + $errorMessage = "Execution of {$sb} by ${callerFile}: line $callerLine failed with exit code $LASTEXITCODE" + throw $errorMessage + } throw "Execution of {$sb} failed with exit code $LASTEXITCODE" } } finally { @@ -1784,166 +2129,6 @@ function script:Start-NativeExecution([scriptblock]$sb, [switch]$IgnoreExitcode) } } -# Builds coming out of this project can have version number as 'a.b.c' OR 'a.b.c-d-f' -# This function converts the above version into major.minor[.build[.revision]] format -function Get-PackageVersionAsMajorMinorBuildRevision -{ - [CmdletBinding()] - param ( - # Version of the Package - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] $Version - ) - - Write-Verbose "Extract the version in the form of major.minor[.build[.revision]] for $Version" - $packageVersionTokens = $Version.Split('-') - $packageVersion = ([regex]::matches($Version, "\d+(\.\d+)+"))[0].value - - if (1 -eq $packageVersionTokens.Count) { - # In case the input is of the form a.b.c, add a '0' at the end for revision field - $packageVersion = $packageVersion + '.0' - } elseif (1 -lt $packageVersionTokens.Count) { - # We have all the four fields - $packageBuildTokens = ([regex]::Matches($packageVersionTokens[1], "\d+"))[0].value - $packageVersion = $packageVersion + '.' + $packageBuildTokens - } - - $packageVersion -} - -function New-MSIPackage -{ - [CmdletBinding()] - param ( - - # Name of the Product - [ValidateNotNullOrEmpty()] - [string] $ProductName = 'PowerShell', - - # Suffix of the Name - [string] $ProductNameSuffix, - - # Version of the Product - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] $ProductVersion, - - # Product Guid needs to change for every version to support SxS install - [ValidateNotNullOrEmpty()] - [string] $ProductGuid = 'a5249933-73a1-4b10-8a4c-13c98bdc16fe', - - # Source Path to the Product Files - required to package the contents into an MSI - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] $ProductSourcePath, - - # File describing the MSI Package creation semantics - [ValidateNotNullOrEmpty()] - [string] $ProductWxsPath = "$PSScriptRoot\assets\Product.wxs", - - # Path to Assets folder containing artifacts such as icons, images - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] $AssetsPath, - - # Path to license.rtf file - for the EULA - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] $LicenseFilePath, - - # Architecture to use when creating the MSI - [Parameter(Mandatory = $true)] - [ValidateSet("x86", "x64")] - [ValidateNotNullOrEmpty()] - [string] $ProductTargetArchitecture, - - # Force overwrite of package - [Switch] $Force - ) - - ## AppVeyor base image might update the version for Wix. Hence, we should - ## not hard code version numbers. - $wixToolsetBinPath = "${env:ProgramFiles(x86)}\WiX Toolset *\bin" - - Write-Verbose "Ensure Wix Toolset is present on the machine @ $wixToolsetBinPath" - if (-not (Test-Path $wixToolsetBinPath)) - { - throw "Wix Toolset is required to create MSI package. Please install Wix from https://wix.codeplex.com/downloads/get/1540240" - } - - ## Get the latest if multiple versions exist. - $wixToolsetBinPath = (Get-ChildItem $wixToolsetBinPath).FullName | Sort-Object -Descending | Select-Object -First 1 - - Write-Verbose "Initialize Wix executables - Heat.exe, Candle.exe, Light.exe" - $wixHeatExePath = Join-Path $wixToolsetBinPath "Heat.exe" - $wixCandleExePath = Join-Path $wixToolsetBinPath "Candle.exe" - $wixLightExePath = Join-Path $wixToolsetBinPath "Light.exe" - - $ProductSemanticVersion = Get-PackageSemanticVersion -Version $ProductVersion - $ProductVersion = Get-PackageVersionAsMajorMinorBuildRevision -Version $ProductVersion - - $assetsInSourcePath = Join-Path $ProductSourcePath 'assets' - New-Item $assetsInSourcePath -type directory -Force | Write-Verbose - - Write-Verbose "Place dependencies such as icons to $assetsInSourcePath" - Copy-Item "$AssetsPath\*.ico" $assetsInSourcePath -Force - - $productVersionWithName = $ProductName + '_' + $ProductVersion - $productSemanticVersionWithName = $ProductName + '-' + $ProductSemanticVersion - - Write-Verbose "Create MSI for Product $productSemanticVersionWithName" - - [Environment]::SetEnvironmentVariable("ProductSourcePath", $ProductSourcePath, "Process") - # These variables are used by Product.wxs in assets directory - [Environment]::SetEnvironmentVariable("ProductName", $ProductName, "Process") - [Environment]::SetEnvironmentVariable("ProductGuid", $ProductGuid, "Process") - [Environment]::SetEnvironmentVariable("ProductVersion", $ProductVersion, "Process") - [Environment]::SetEnvironmentVariable("ProductSemanticVersion", $ProductSemanticVersion, "Process") - [Environment]::SetEnvironmentVariable("ProductVersionWithName", $productVersionWithName, "Process") - [Environment]::SetEnvironmentVariable("ProductTargetArchitecture", $ProductTargetArchitecture, "Process") - $ProductProgFilesDir = "ProgramFiles64Folder" - if ($ProductTargetArchitecture -eq "x86") - { - $ProductProgFilesDir = "ProgramFilesFolder" - } - [Environment]::SetEnvironmentVariable("ProductProgFilesDir", $ProductProgFilesDir, "Process") - - $wixFragmentPath = (Join-path $env:Temp "Fragment.wxs") - $wixObjProductPath = (Join-path $env:Temp "Product.wixobj") - $wixObjFragmentPath = (Join-path $env:Temp "Fragment.wixobj") - - $packageName = $productSemanticVersionWithName - if ($ProductNameSuffix) { - $packageName += "-$ProductNameSuffix" - } - $msiLocationPath = Join-Path $pwd "$packageName.msi" - - if(!$Force.IsPresent -and (Test-Path -Path $msiLocationPath)) - { - Write-Error -Message "Package already exists, use -Force to overwrite, path: $msiLocationPath" -ErrorAction Stop - } - - $WiXHeatLog = & $wixHeatExePath dir $ProductSourcePath -dr $productVersionWithName -cg $productVersionWithName -gg -sfrag -srd -scom -sreg -out $wixFragmentPath -var env.ProductSourcePath -v - $WiXCandleLog = & $wixCandleExePath "$ProductWxsPath" "$wixFragmentPath" -out (Join-Path "$env:Temp" "\\") -ext WixUIExtension -ext WixUtilExtension -arch x64 -v - $WiXLightLog = & $wixLightExePath -out $msiLocationPath $wixObjProductPath $wixObjFragmentPath -ext WixUIExtension -ext WixUtilExtension -dWixUILicenseRtf="$LicenseFilePath" -v - - Remove-Item -ErrorAction SilentlyContinue *.wixpdb -Force - - if (Test-Path $msiLocationPath) - { - Write-Verbose "You can find the MSI @ $msiLocationPath" -Verbose - $msiLocationPath - } - else - { - $WiXHeatLog | Out-String | Write-Verbose -Verbose - $WiXCandleLog | Out-String | Write-Verbose -Verbose - $WiXLightLog | Out-String | Write-Verbose -Verbose - throw "Failed to create $msiLocationPath" - } -} - function Start-CrossGen { [CmdletBinding()] param( @@ -1957,7 +2142,9 @@ function Start-CrossGen { "win7-x64", "osx.10.12-x64", "linux-x64", - "linux-arm")] + "linux-arm", + "win-arm", + "win-arm64")] [string] $Runtime ) @@ -2011,8 +2198,10 @@ function Start-CrossGen { $crossGenRuntime = if ($Environment.IsWindows) { if ($Runtime -match "-x86") { "win-x86" - } else { + } elseif ($Runtime -match "-x64") { "win-x64" + } elseif (!($env:PROCESSOR_ARCHITECTURE -match "arm")) { + throw "crossgen for 'win-arm' and 'win-arm64' must be run on that platform" } } elseif ($Runtime -eq "linux-arm") { throw "crossgen is not available for 'linux-arm'" @@ -2153,106 +2342,61 @@ function Clear-PSRepo } # Install PowerShell modules such as PackageManagement, PowerShellGet -function Restore-PSModule +function Copy-PSGalleryModules { [CmdletBinding()] param( [Parameter(Mandatory=$true)] - [ValidateNotNullOrEmpty()] - [string[]]$Name, - - [Parameter(Mandatory=$true)] - [ValidateNotNullOrEmpty()] - [string]$Destination, - - [string]$SourceLocation="https://powershell.myget.org/F/powershellmodule/api/v2/", - - [string]$RequiredVersion - ) - - $needRegister = $true - $RepositoryName = "mygetpsmodule" - - # Check if the PackageManagement works in the base-oS or PowerShellCore - Get-PackageProvider -Name NuGet -ForceBootstrap -Verbose:$VerbosePreference - Get-PackageProvider -Name PowerShellGet -Verbose:$VerbosePreference - - # Get the existing registered PowerShellGet repositories - $psrepos = PowerShellGet\Get-PSRepository + [string]$Destination + ) - foreach ($repo in $psrepos) - { - if(($repo.SourceLocation -eq $SourceLocation) -or ($repo.SourceLocation.TrimEnd("/") -eq $SourceLocation.TrimEnd("/"))) - { - # found a registered repository that matches the source location - $needRegister = $false - $RepositoryName = $repo.Name - break - } + if (!$Destination.EndsWith("Modules")) { + throw "Installing to an unexpected location" } - if($needRegister) - { - $regVar = PowerShellGet\Get-PSRepository -Name $RepositoryName -ErrorAction SilentlyContinue - if($regVar) - { - PowerShellGet\UnRegister-PSRepository -Name $RepositoryName - } - - log "Registering PSRepository with name: $RepositoryName and sourcelocation: $SourceLocation" - PowerShellGet\Register-PSRepository -Name $RepositoryName -SourceLocation $SourceLocation -ErrorVariable ev -verbose - if($ev) - { - throw ("Failed to register repository '{0}'" -f $RepositoryName) - } + Find-DotNet + Restore-PSPackage - $regVar = PowerShellGet\Get-PSRepository -Name $RepositoryName - if(-not $regVar) - { - throw ("'{0}' is not registered" -f $RepositoryName) - } + $cache = dotnet nuget locals global-packages -l + if ($cache -match "info : global-packages: (.*)") { + $nugetCache = $matches[1] + } + else { + throw "Can't find nuget global cache" } - log ("Name='{0}', Destination='{1}', Repository='{2}'" -f ($Name -join ','), $Destination, $RepositoryName) - - # do not output progress - $ProgressPreference = "SilentlyContinue" - $Name | ForEach-Object { + $psGalleryProj = [xml](Get-Content -Raw $PSScriptRoot\src\Modules\PSGalleryModules.csproj) - $command = @{ - Name=$_ - Path = $Destination - Repository =$RepositoryName - } + foreach ($m in $psGalleryProj.Project.ItemGroup.PackageReference) { + $name = $m.Include + $version = $m.Version + Write-Log "Name='$Name', Version='$version', Destination='$Destination'" - if($RequiredVersion) - { - $command.Add("RequiredVersion", $RequiredVersion) + # Remove the build revision from the src (nuget drops it). + $srcVer = if ($version -match "(\d+.\d+.\d+).\d+") { + $matches[1] + } else { + $version } - # pull down the module - log "running save-module $_" - PowerShellGet\Save-Module @command -Force - - # Remove PSGetModuleInfo.xml file - Find-Module -Name $_ -Repository $RepositoryName -IncludeDependencies | ForEach-Object { - Remove-Item -Path $Destination\$($_.Name)\*\PSGetModuleInfo.xml -Force + # Remove semantic version in the destination directory + $destVer = if ($version -match "(\d+.\d+.\d+)-.+") { + $matches[1] + } else { + $version } - } - # Clean up - if($needRegister) - { - $regVar = PowerShellGet\Get-PSRepository -Name $RepositoryName -ErrorAction SilentlyContinue - if($regVar) - { - log "Unregistering PSRepository with name: $RepositoryName" - PowerShellGet\UnRegister-PSRepository -Name $RepositoryName - } + # Nuget seems to always use lowercase in the cache + $src = "$nugetCache/$($name.ToLower())/$srcVer" + $dest = "$Destination/$name/$destVer" + + Remove-Item -Force -ErrorAction Ignore -Recurse "$Destination/$name" + New-Item -Path $dest -ItemType Directory -Force -ErrorAction Stop > $null + $dontCopy = '*.nupkg', '*.nupkg.sha512', '*.nuspec', 'System.Runtime.InteropServices.RuntimeInformation.dll' + Copy-Item -Exclude $dontCopy -Recurse $src/* $dest } } - $script:RESX_TEMPLATE = @' diff --git a/demos/Apache/Apache/Apache.psm1 b/demos/Apache/Apache/Apache.psm1 index a572561f103..489502a6d39 100644 --- a/demos/Apache/Apache/Apache.psm1 +++ b/demos/Apache/Apache/Apache.psm1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + #Region utility functions $global:sudocmd = "sudo" @@ -216,7 +219,6 @@ Function Restart-ApacheHTTPServer{ } - Function Get-ApacheModule{ $cmd = GetApacheCmd diff --git a/demos/Apache/apache-demo.ps1 b/demos/Apache/apache-demo.ps1 index 30ada4e97e7..1f5d60587d7 100644 --- a/demos/Apache/apache-demo.ps1 +++ b/demos/Apache/apache-demo.ps1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + Import-Module $PSScriptRoot/Apache/Apache.psm1 #list Apache Modules diff --git a/demos/Azure/Azure-Demo.ps1 b/demos/Azure/Azure-Demo.ps1 index d3688e7ea18..444ec34973d 100644 --- a/demos/Azure/Azure-Demo.ps1 +++ b/demos/Azure/Azure-Demo.ps1 @@ -1,4 +1,7 @@ -### The techniques used in this demo are documented at +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +### The techniques used in this demo are documented at ### https://azure.microsoft.com/en-us/documentation/articles/powershell-azure-resource-manager/ ### Import AzureRM.Profile.NetCore.Preview and AzureRM.Resources.NetCore.Preview modules. diff --git a/demos/DSC/dsc-demo.ps1 b/demos/DSC/dsc-demo.ps1 index 95b694c638a..f393916408b 100644 --- a/demos/DSC/dsc-demo.ps1 +++ b/demos/DSC/dsc-demo.ps1 @@ -1,3 +1,5 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. #Get Distro type and set distro-specific variables $OSname = Get-Content "/etc/os-release" |Select-String -Pattern "^Name=" diff --git a/demos/Docker-PowerShell/Docker-PowerShell.ps1 b/demos/Docker-PowerShell/Docker-PowerShell.ps1 index 3517e805882..4639f7ee1d0 100644 --- a/demos/Docker-PowerShell/Docker-PowerShell.ps1 +++ b/demos/Docker-PowerShell/Docker-PowerShell.ps1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + # This is a short example of the Docker-PowerShell module. The same cmdlets may be used to manage both local & remote machines, including both Windows & Linux hosts # The only difference between them is the example container image is pulled & run. @@ -26,4 +29,4 @@ Get-Container | Where-Object State -eq "exited" | Remove-Container Remove-ContainerImage hello-world # And list the container images left on the container host -Get-ContainerImage \ No newline at end of file +Get-ContainerImage diff --git a/demos/Raspberry-Pi/README.md b/demos/Raspberry-Pi/README.md deleted file mode 100644 index 0e528f1dfa1..00000000000 --- a/demos/Raspberry-Pi/README.md +++ /dev/null @@ -1,86 +0,0 @@ -# Running PowerShell Core 6 on a Raspberry-Pi - -## Setup your Pi - -Note that CoreCLR (and thus PowerShell Core) will only work on Pi 2 and Pi 3 devices as other devices -like [Pi Zero](https://github.com/dotnet/coreclr/issues/10605) have an unsupported processor. - -Download [Raspbian](https://www.raspberrypi.org/downloads/raspbian/) and follow the [installation instructions](https://www.raspberrypi.org/documentation/installation/installing-images/README.md) to get it onto your Pi. - -Once your Pi is up and running, [enable SSH remoting](https://www.raspberrypi.org/documentation/remote-access/ssh/). - -## Building PowerShell Core 6 for arm32 - -We'll need to cross-compile for the Linux arm32 architecture from Ubuntu. - -Follow the [Linux instructions to Build PowerShell](https://github.com/PowerShell/PowerShell/blob/master/docs/building/linux.md). - -Once your environment is working, you'll need to setup the toolchain for cross compilation: - -```powershell -Start-PSBootstrap -BuildLinuxArm -``` - -You can now build PowerShell Core: - -```powershell -Start-PSBuild -Clean -Runtime linux-arm -PSModuleRestore -``` - -Note that it's important to do a `-Clean` build because if you previously built for Ubuntu, it won't try to rebuild the native library `pslnative` for arm32. - -## Copy the bits to your Pi - -Use SSH to copy the bits remotely, replace `yourPi` with the name or IP address of your Pi. - -```powershell -scp -r "$(split-path (Get-PSOutput))/*" pi@yourPi:/home/pi/powershell -``` - -## Get latest CoreCLR runtime - -We need to get a CoreCLR that fixes a [threading bug](https://github.com/dotnet/coreclr/pull/13922) which is in DotNetCore 2.0.0. - -You can do these steps locally on your Pi, but we're using SSH remoting here. - -We'll be using the latest [build](https://github.com/dotnet/core-setup#daily-builds) from master which has the fix. -Note that at the time of authoring these instructions, the 2.0.x servicing build didn't have the necessary fix and the 2.1.x builds may be more unstable. - -We'll use `curl` to get the latest DotNetCore runtime. - -```bash -sudo apt install curl -``` - -Now we'll download it and unpack it. - -```bash -# Connect to your Pi. -ssh pi@yourpi -# We'll make a folder to put latest CoreCLR runtime. -mkdir dotnet -cd dotnet -# Download the latest CoreCLR runtime. -curl -O https://dotnetcli.blob.core.windows.net/dotnet/Runtime/master/dotnet-runtime-latest-linux-arm.tar.gz -# Unpack it. -tar xvf ./dotnet-runtime-latest-linux-arm.tar.gz -# We're going to overwrite the CoreCLR bits we built with newer ones, replace the version named folder below as appropriate. -# If you build a newer version of PowerShell Core, you'll need to make sure you get latest CoreCLR runtime otherwise you may hit a segmentation fault. -cp shared/Microsoft.NetCore.App/2.1.0-preview1-25719-04/* ~/powershell -``` - -## Start PowerShell - -```bash -~/powershell/powershell -``` - -Note that until arm32 is [fully supported by CoreCLR](https://github.com/dotnet/coreclr/issues/3977), it's not supported by PowerShell Core. - -If you get an error complaining about `libunwind.so.8` not being found, you'll need to install it as it's required by CoreCLR. - -```bash -sudo apt install libunwind8 -``` - -Have fun! diff --git a/demos/SSHRemoting/README.md b/demos/SSHRemoting/README.md deleted file mode 100644 index 25f93922f32..00000000000 --- a/demos/SSHRemoting/README.md +++ /dev/null @@ -1,221 +0,0 @@ -# PowerShell Remoting Over SSH - -## Overview - -PowerShell remoting normally uses WinRM for connection negotiation and data transport. -SSH was chosen for this remoting implementation since it is now available for both Linux and Windows platforms and allows true multiplatform PowerShell remoting. -However, WinRM also provides a robust hosting model for PowerShell remote sessions which this implementation does not yet do. -And this means that PowerShell remote endpoint configuration and JEA (Just Enough Administration) is not yet supported in this implementation. - -PowerShell SSH remoting lets you do basic PowerShell session remoting between Windows and Linux machines. -This is done by creating a PowerShell hosting process on the target machine as an SSH subsystem. -Eventually this will be changed to a more general hosting model similar to how WinRM works in order to support endpoint configuration and JEA. - -The New-PSSession, Enter-PSSession and Invoke-Command cmdlets now have a new parameter set to facilitate this new remoting connection - -```powershell -[-HostName ] [-UserName ] [-KeyFilePath ] -``` - -This new parameter set will likely change but for now allows you to create SSH PSSessions that you can interact with from the command line or invoke commands and scripts on. -You specify the target machine with the HostName parameter and provide the user name with UserName. -When running the cmdlets interactively at the PowerShell command line you will be prompted for a password. -But you also have the option to use SSH key authentication and provide a private key file path with the KeyFilePath parameter. - -## General setup information - -SSH is required to be installed on all machines. -You should install both client (ssh.exe) and server (sshd.exe) so that you can experiment with remoting to and from the machines. -For Windows you will need to install [Win32 OpenSSH from GitHub](https://github.com/PowerShell/Win32-OpenSSH/releases). -For Linux you will need to install SSH (including sshd server) appropriate to your platform. -You will also need a recent PowerShell build or package from GitHub having the SSH remoting feature. -SSH subsystems is used to establish a PowerShell process on the remote machine and the SSH server will need to be configured for that. -In addition you will need to enable password authentication and optionally key based authentication. - -## Setup on Windows Machine - -1. Install the latest [PowerShell for Windows] build from GitHub - - You can tell if it has the SSH remoting support by looking at the parameter sets for New-PSSession - ```powershell - PS> Get-Command New-PSSession -syntax - New-PSSession [-HostName] [-Name ] [-UserName ] [-KeyFilePath ] [-SSHTransport] [] - ``` -1. Install the latest [Win32 Open SSH] build from GitHub using the [installation] instructions -1. Edit the sshd_config file at the location where you installed Win32 Open SSH - - Make sure password authentication is enabled - ```none - PasswordAuthentication yes - ``` - - Add a PowerShell subsystem entry, replace `c:/program files/powershell/6.0.0/powershell.exe` with the correct path to the version you want to use - ```none - Subsystem powershell c:/program files/powershell/6.0.0/powershell.exe -sshs -NoLogo -NoProfile - ``` - - Optionally enable key authentication - ```none - PubkeyAuthentication yes - ``` -1. Restart the sshd service - ```powershell - Restart-Service sshd - ``` -1. Add the path where OpenSSH is installed to your Path Env Variable - - This should be along the lines of `C:\Program Files\OpenSSH\` - - This allows for the ssh.exe to be found - -## Setup on Linux (Ubuntu 14.04) Machine - -1. Install the latest [PowerShell for Linux] build from GitHub -1. Install [Ubuntu SSH] as needed - ```bash - sudo apt install openssh-client - sudo apt install openssh-server - ``` -1. Edit the sshd_config file at location /etc/ssh - - Make sure password authentication is enabled - ```none - PasswordAuthentication yes - ``` - - Add a PowerShell subsystem entry - ```none - Subsystem powershell /usr/bin/powershell -sshs -NoLogo -NoProfile - ``` - - Optionally enable key authentication - ```none - PubkeyAuthentication yes - ``` -1. Restart the sshd service - ```bash - sudo service sshd restart - ``` - -## Setup on MacOS Machine - -1. Install the latest [PowerShell for MacOS] build - - Make sure SSH Remoting is enabled by following these steps: - + Open `System Preferences` - + Click on `Sharing` - + Check `Remote Login` - Should say `Remote Login: On` - + Allow access to appropriate users -1. Edit the `sshd_config` file at location `/private/etc/ssh/sshd_config` - - Use your favorite editor or - ```bash - sudo nano /private/etc/ssh/sshd_config - ``` - - Make sure password authentication is enabled - ```none - PasswordAuthentication yes - ``` - - Add a PowerShell subsystem entry - ```none - Subsystem powershell /usr/local/bin/powershell -sshs -NoLogo -NoProfile - ``` - - Optionally enable key authentication - ```none - PubkeyAuthentication yes - ``` -1. Restart the sshd service - ```bash - sudo launchctl stop com.openssh.sshd - sudo launchctl start com.openssh.sshd - ``` - -## PowerShell Remoting Example - -The easiest way to test remoting is to just try it on a single machine. -Here I will create a remote session back to the same machine on a Linux box. -Notice that I am using PowerShell cmdlets from a command prompt so we see prompts from SSH asking to verify the host computer as well as password prompts. -You can do the same thing on a Windows machine to ensure remoting is working there and then remote between machines by simply changing the host name. - -```powershell -# -# Linux to Linux -# -PS /home/TestUser> $session = New-PSSession -HostName UbuntuVM1 -UserName TestUser -The authenticity of host 'UbuntuVM1 (9.129.17.107)' cannot be established. -ECDSA key fingerprint is SHA256:2kCbnhT2dUE6WCGgVJ8Hyfu1z2wE4lifaJXLO7QJy0Y. -Are you sure you want to continue connecting (yes/no)? -TestUser@UbuntuVM1s password: - -PS /home/TestUser> $session - - Id Name ComputerName ComputerType State ConfigurationName Availability - -- ---- ------------ ------------ ----- ----------------- ------------ - 1 SSH1 UbuntuVM1 RemoteMachine Opened DefaultShell Available - -PS /home/TestUser> Enter-PSSession $session - -[UbuntuVM1]: PS /home/TestUser> uname -a -Linux TestUser-UbuntuVM1 4.2.0-42-generic 49~14.04.1-Ubuntu SMP Wed Jun 29 20:22:11 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux - -[UbuntuVM1]: PS /home/TestUser> Exit-PSSession - -PS /home/TestUser> Invoke-Command $session -ScriptBlock { Get-Process powershell } - -Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName PSComputerName -------- ------ ----- ----- ------ -- -- ----------- -------------- - 0 0 0 19 3.23 10635 635 powershell UbuntuVM1 - 0 0 0 21 4.92 11033 017 powershell UbuntuVM1 - 0 0 0 20 3.07 11076 076 powershell UbuntuVM1 - - -# -# Linux to Windows -# -PS /home/TestUser> Enter-PSSession -HostName WinVM1 -UserName PTestName -PTestName@WinVM1s password: - -[WinVM1]: PS C:\Users\PTestName\Documents> cmd /c ver - -Microsoft Windows [Version 10.0.10586] - -[WinVM1]: PS C:\Users\PTestName\Documents> - -# -# Windows to Windows -# -C:\Users\PSUser\Documents>"C:\Program Files\PowerShell\6.0.0.17\powershell.exe" -PowerShell -Copyright (C) Microsoft Corporation. All rights reserved. - -PS C:\Users\PSUser\Documents> $session = New-PSSession -HostName WinVM2 -UserName PSRemoteUser -The authenticity of host 'WinVM2 (10.13.37.3)' can't be established. -ECDSA key fingerprint is SHA256:kSU6slAROyQVMEynVIXAdxSiZpwDBigpAF/TXjjWjmw. -Are you sure you want to continue connecting (yes/no)? -Warning: Permanently added 'WinVM2,10.13.37.3' (ECDSA) to the list of known hosts. -PSRemoteUser@WinVM2's password: -PS C:\Users\PSUser\Documents> $session - - Id Name ComputerName ComputerType State ConfigurationName Availability - -- ---- ------------ ------------ ----- ----------------- ------------ - 1 SSH1 WinVM2 RemoteMachine Opened DefaultShell Available - - -PS C:\Users\PSUser\Documents> Enter-PSSession -Session $session -[WinVM2]: PS C:\Users\PSRemoteUser\Documents> $PSVersionTable - -Name Value ----- ----- -PSEdition Core -PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...} -SerializationVersion 1.1.0.1 -BuildVersion 3.0.0.0 -CLRVersion -PSVersion 6.0.0-alpha -WSManStackVersion 3.0 -PSRemotingProtocolVersion 2.3 -GitCommitId v6.0.0-alpha.17 - - -[WinVM2]: PS C:\Users\PSRemoteUser\Documents> -``` - -### Known Issues - -1. sudo command does not work in remote session to Linux machine. - -[PowerShell for Windows]: https://github.com/PowerShell/PowerShell/blob/master/docs/installation/windows.md#msi -[Win32 Open SSH]: https://github.com/PowerShell/Win32-OpenSSH -[installation]: https://github.com/PowerShell/Win32-OpenSSH/wiki/Install-Win32-OpenSSH -[PowerShell for Linux]: https://github.com/PowerShell/PowerShell/blob/master/docs/installation/linux.md#ubuntu-1404 -[Ubuntu SSH]: https://help.ubuntu.com/lts/serverguide/openssh-server.html -[PowerShell for MacOS]: https://github.com/PowerShell/PowerShell/blob/master/docs/installation/linux.md#macos-1012 diff --git a/demos/SystemD/SystemD/SystemD.psm1 b/demos/SystemD/SystemD/SystemD.psm1 index 38ea8fd4146..b127a2e5169 100644 --- a/demos/SystemD/SystemD/SystemD.psm1 +++ b/demos/SystemD/SystemD/SystemD.psm1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + Function Get-SystemDJournal { [CmdletBinding()] param ( @@ -15,4 +18,4 @@ Function Get-SystemDJournal { { $Result } -} \ No newline at end of file +} diff --git a/demos/SystemD/journalctl-demo.ps1 b/demos/SystemD/journalctl-demo.ps1 index 7e4fc37831b..c979a97467b 100644 --- a/demos/SystemD/journalctl-demo.ps1 +++ b/demos/SystemD/journalctl-demo.ps1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + Import-Module $PSScriptRoot/SystemD/SystemD.psm1 #list recent journal events diff --git a/demos/crontab/CronTab/CronTab.psd1 b/demos/crontab/CronTab/CronTab.psd1 index 4c8f772bf27..df7d8149420 100755 --- a/demos/crontab/CronTab/CronTab.psd1 +++ b/demos/crontab/CronTab/CronTab.psd1 @@ -13,13 +13,13 @@ CompatiblePSEditions = @('Core') GUID = '508bb97f-de2e-482e-aae2-01caec0be8c7' # Author of this module -Author = 'Microsoft' +Author = 'PowerShell' # Company or vendor of this module -CompanyName = 'Unknown' +CompanyName = 'Microsoft Corporation' # Copyright statement for this module -Copyright = '(c) 2016 Microsoft. All rights reserved.' +Copyright = 'Copyright (c) Microsoft Corporation. All rights reserved.' # Description of the functionality provided by this module Description = 'Sample module for managing CronTab' diff --git a/demos/crontab/CronTab/CronTab.psm1 b/demos/crontab/CronTab/CronTab.psm1 index ee90c69f782..15fedb52070 100644 --- a/demos/crontab/CronTab/CronTab.psm1 +++ b/demos/crontab/CronTab/CronTab.psm1 @@ -1,3 +1,5 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. using namespace System.Collections.Generic using namespace System.Management.Automation diff --git a/demos/crontab/crontab.ps1 b/demos/crontab/crontab.ps1 index f0ef43376ae..72cc084d41e 100644 --- a/demos/crontab/crontab.ps1 +++ b/demos/crontab/crontab.ps1 @@ -1,3 +1,5 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. Import-Module $PSScriptRoot/CronTab/CronTab.psd1 diff --git a/demos/dsc.ps1 b/demos/dsc.ps1 index 27e09f29e46..8f93dd507c3 100644 --- a/demos/dsc.ps1 +++ b/demos/dsc.ps1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + # DSC MOF Compilation # DSC Configuration() script that: # Defines base configuration users, groups, settings @@ -8,4 +11,4 @@ # Show the .ps1 # Run the .ps1 to generate a MOF # Apply the MOF locally with Start-DSCConfiguration -# Show the newly configured state \ No newline at end of file +# Show the newly configured state diff --git a/demos/install/README.md b/demos/install/README.md deleted file mode 100644 index 54049e09158..00000000000 --- a/demos/install/README.md +++ /dev/null @@ -1,5 +0,0 @@ -## Install demo - -For Windows refer to the [installation instructions](https://github.com/PowerShell/PowerShell/blob/master/docs/installation/windows.md) - -For Linux, using [download.sh](https://github.com/PowerShell/PowerShell/blob/master/tools/download.sh) is the best way to deploy PowerShell bits \ No newline at end of file diff --git a/demos/powershellget/PowerShellGet.ps1 b/demos/powershellget/PowerShellGet.ps1 index 67032152418..0dc33f85c46 100644 --- a/demos/powershellget/PowerShellGet.ps1 +++ b/demos/powershellget/PowerShellGet.ps1 @@ -1,4 +1,7 @@ -#region find, install, update, uninstall the PowerShell scripts from an online repository. +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +#region find, install, update, uninstall the PowerShell scripts from an online repository. # Value: equivalent of pypi # List of PowerShellGet commands @@ -74,4 +77,4 @@ Set-PSRepository -Name "myPrivateGallery" -InstallationPolicy "Untrusted" # Remove a private feed Unregister-PSRepository -Name "myPrivateGallery" -#endregion \ No newline at end of file +#endregion diff --git a/demos/python/README.md b/demos/python/README.md index 66ec4862d7a..d2d1486e2fe 100644 --- a/demos/python/README.md +++ b/demos/python/README.md @@ -1,8 +1,8 @@ -## PowerShell/Python Interoperation Demo +# PowerShell/Python Interoperation Demo -The "demo_script.ps1" file in this directory walks through a +The `demo_script.ps1` file in this directory walks through a demonstration of basic interoperation between PowerShell and Python including how to use JSON to exchange structured objects between Python and PowerShell. -The other files in this directory are referenced by demo_script.ps1. +The other files in this directory are referenced by `demo_script.ps1`. diff --git a/demos/python/class1.ps1 b/demos/python/class1.ps1 index 16b426a91db..291677fd948 100644 --- a/demos/python/class1.ps1 +++ b/demos/python/class1.ps1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + # # Wrap Python script in such a way to make it easy to # consume from PowerShell diff --git a/demos/python/demo_script.ps1 b/demos/python/demo_script.ps1 index 0544efe15e5..586e14a2085 100644 --- a/demos/python/demo_script.ps1 +++ b/demos/python/demo_script.ps1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + # # Demo simple interoperation between PowerShell and Python @@ -55,7 +58,6 @@ cat inline_python.ps1 # and run it ./inline_python - #################################### # cleanup rm hi diff --git a/demos/python/inline_python.ps1 b/demos/python/inline_python.ps1 index c9026304c91..fdad32a8601 100644 --- a/demos/python/inline_python.ps1 +++ b/demos/python/inline_python.ps1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + # # An example showing inline Python code in a PowerShell script # diff --git a/demos/rest/rest.ps1 b/demos/rest/rest.ps1 index 59bea0ce0d4..db9867e8d28 100644 --- a/demos/rest/rest.ps1 +++ b/demos/rest/rest.ps1 @@ -1,4 +1,6 @@ - +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + #----------------- function Get-Issue diff --git a/docker/.gitignore b/docker/.gitignore deleted file mode 100644 index 9cc0e40f1bb..00000000000 --- a/docker/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -logs/**/*.log -packages/ diff --git a/docker/InstallTarballPackage.sh b/docker/InstallTarballPackage.sh index 90fcc6bbf5b..1bc807a0b92 100644 --- a/docker/InstallTarballPackage.sh +++ b/docker/InstallTarballPackage.sh @@ -5,7 +5,7 @@ set -e # # Example use: -# ./InstallTarballPackage.sh "6.0.0-beta.8" "powershell-6.0.0-beta.8-linux-x64.tar.gz" +# ./InstallTarballPackage.sh "6.0.0-beta.9" "powershell-6.0.0-beta.9-linux-x64.tar.gz" # usage() { echo "usage: $0 " @@ -24,7 +24,7 @@ then usage fi -POWERSHELL_LINKFILE=/usr/bin/powershell +POWERSHELL_LINKFILE=/usr/bin/pwsh # Download the powershell .tar.gz package curl -L -o /tmp/powershell.tar.gz https://github.com/PowerShell/PowerShell/releases/download/v$POWERSHELL_VERSION/$POWERSHELL_PACKAGE @@ -35,7 +35,7 @@ mkdir -p /opt/microsoft/powershell/$POWERSHELL_VERSION tar zxf /tmp/powershell.tar.gz -C /opt/microsoft/powershell/$POWERSHELL_VERSION # Create the symbolic link that points to powershell -ln -s /opt/microsoft/powershell/$POWERSHELL_VERSION/powershell $POWERSHELL_LINKFILE +ln -s /opt/microsoft/powershell/$POWERSHELL_VERSION/pwsh $POWERSHELL_LINKFILE # Add the symbolic link path to /etc/shells if [ ! -f /etc/shells ] ; then echo $POWERSHELL_LINKFILE > /etc/shells ; diff --git a/docker/README.md b/docker/README.md index ab6ada0c920..ebe45dbecda 100644 --- a/docker/README.md +++ b/docker/README.md @@ -46,7 +46,7 @@ adf6ad28fa0e: Pull complete Digest: sha256:92c79c5fcdaf3027626643aef556344b8b4cbdaccf8443f543303319949c7f3a Status: Downloaded newer image for microsoft/powershell:latest PowerShell -Copyright © 2016 Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. PS /> Write-Host "Hello, World!" Hello, World! diff --git a/docker/community/amazonlinux/Dockerfile b/docker/community/amazonlinux/Dockerfile index a18792047a7..4045d8352db 100644 --- a/docker/community/amazonlinux/Dockerfile +++ b/docker/community/amazonlinux/Dockerfile @@ -2,8 +2,8 @@ FROM amazonlinux:latest -ARG POWERSHELL_VERSION=6.0.0-beta.8 -ARG POWERSHELL_PACKAGE=powershell-6.0.0-beta.8-linux-x64.tar.gz +ARG POWERSHELL_VERSION=6.0.2 +ARG POWERSHELL_PACKAGE=powershell-6.0.2-linux-x64.tar.gz ARG IMAGE_NAME=microsoft/powershell:amazonlinux LABEL maintainer="PowerShell Team " \ @@ -16,10 +16,10 @@ LABEL maintainer="PowerShell Team " \ org.label-schema.vendor="PowerShell" \ org.label-schema.version=${POWERSHELL_VERSION} \ org.label-schema.schema-version="1.0" \ - org.label-schema.docker.cmd="docker run ${IMAGE_NAME} powershell -c '$psversiontable'" \ + org.label-schema.docker.cmd="docker run ${IMAGE_NAME} pwsh -c '$psversiontable'" \ org.label-schema.docker.cmd.devel="docker run ${IMAGE_NAME}" \ - org.label-schema.docker.cmd.test="docker run ${IMAGE_NAME} powershell -c Invoke-Pester" \ - org.label-schema.docker.cmd.help="docker run ${IMAGE_NAME} powershell -c Get-Help" + org.label-schema.docker.cmd.test="docker run ${IMAGE_NAME} pwsh -c Invoke-Pester" \ + org.label-schema.docker.cmd.help="docker run ${IMAGE_NAME} pwsh -c Get-Help" # TODO: addd LABEL org.label-schema.vcs-ref=${VCS_REF} @@ -29,7 +29,7 @@ ENV LC_ALL $LANG RUN localedef --charmap=UTF-8 --inputfile=en_US $LANG # Install dependencies and clean up -RUN yum install -y \ +RUN yum install -y \ curl \ libunwind \ libicu \ @@ -52,4 +52,4 @@ RUN rm -f /InstallTarballPackage.sh # Use PowerShell as the default shell # Use array to avoid Docker prepending /bin/sh -c -CMD [ "powershell" ] +CMD [ "pwsh" ] diff --git a/docker/community/archlinux/Dockerfile b/docker/community/archlinux/Dockerfile index 9fbf0ca532d..2ef0f170a8e 100644 --- a/docker/community/archlinux/Dockerfile +++ b/docker/community/archlinux/Dockerfile @@ -25,12 +25,12 @@ LABEL maintainer="PowerShell Community " \ org.label-schema.name="powershell" \ org.label-schema.vendor="PowerShell" \ org.label-schema.schema-version="1.0" \ - org.label-schema.docker.cmd="docker run ${IMAGE_NAME} powershell -c '$psversiontable'" \ + org.label-schema.docker.cmd="docker run ${IMAGE_NAME} pwsh -c '$psversiontable'" \ org.label-schema.docker.cmd.devel="docker run ${IMAGE_NAME}" \ - org.label-schema.docker.cmd.test="docker run ${IMAGE_NAME} powershell -c Invoke-Pester" \ - org.label-schema.docker.cmd.help="docker run ${IMAGE_NAME} powershell -c Get-Help" + org.label-schema.docker.cmd.test="docker run ${IMAGE_NAME} pwsh -c Invoke-Pester" \ + org.label-schema.docker.cmd.help="docker run ${IMAGE_NAME} pwsh -c Get-Help" COPY --from=build-env /build/powershell-bin/*.xz /powershell-package/ RUN ls /powershell-package/* RUN pacman -Syu --noconfirm libunwind; \ - pacman -U --noconfirm /powershell-package/*.xz \ No newline at end of file + pacman -U --noconfirm /powershell-package/*.xz diff --git a/docker/release/centos7/Dockerfile b/docker/release/centos7/Dockerfile index af6acfb0867..0a6d43de1a9 100644 --- a/docker/release/centos7/Dockerfile +++ b/docker/release/centos7/Dockerfile @@ -2,7 +2,7 @@ FROM centos:7 -ARG POWERSHELL_VERSION=6.0.0-beta.8 +ARG POWERSHELL_VERSION=6.0.2 ARG IMAGE_NAME=microsoft/powershell:centos7 LABEL maintainer="PowerShell Team " \ @@ -15,10 +15,10 @@ LABEL maintainer="PowerShell Team " \ org.label-schema.vendor="PowerShell" \ org.label-schema.version=${POWERSHELL_VERSION} \ org.label-schema.schema-version="1.0" \ - org.label-schema.docker.cmd="docker run ${IMAGE_NAME} powershell -c '$psversiontable'" \ + org.label-schema.docker.cmd="docker run ${IMAGE_NAME} pwsh -c '$psversiontable'" \ org.label-schema.docker.cmd.devel="docker run ${IMAGE_NAME}" \ - org.label-schema.docker.cmd.test="docker run ${IMAGE_NAME} powershell -c Invoke-Pester" \ - org.label-schema.docker.cmd.help="docker run ${IMAGE_NAME} powershell -c Get-Help" + org.label-schema.docker.cmd.test="docker run ${IMAGE_NAME} pwsh -c Invoke-Pester" \ + org.label-schema.docker.cmd.help="docker run ${IMAGE_NAME} pwsh -c Get-Help" # TODO: addd LABEL org.label-schema.vcs-ref=${VCS_REF} @@ -29,7 +29,7 @@ ENV LC_ALL $LANG RUN localedef --charmap=UTF-8 --inputfile=en_US $LANG # Install dependencies and clean up -RUN yum install -y \ +RUN yum install -y \ curl \ && yum clean all @@ -38,8 +38,9 @@ RUN curl https://packages.microsoft.com/config/rhel/7/prod.repo | tee /etc/yum.r # Install latest powershell from Microsoft YUM Repo RUN yum install -y \ - powershell + powershell \ + && yum clean all # Use PowerShell as the default shell # Use array to avoid Docker prepending /bin/sh -c -CMD [ "powershell" ] +CMD [ "pwsh" ] diff --git a/docker/release/fedora26/Dockerfile b/docker/release/fedora26/Dockerfile index db57ce3adf6..6adbcaba0d0 100644 --- a/docker/release/fedora26/Dockerfile +++ b/docker/release/fedora26/Dockerfile @@ -2,7 +2,7 @@ FROM fedora:26 -ARG POWERSHELL_VERSION=6.0.0-beta.8 +ARG POWERSHELL_VERSION=6.0.2 ARG IMAGE_NAME=microsoft/powershell:fedora26 LABEL maintainer="PowerShell Team " \ @@ -15,15 +15,15 @@ LABEL maintainer="PowerShell Team " \ org.label-schema.vendor="PowerShell" \ org.label-schema.version=${POWERSHELL_VERSION} \ org.label-schema.schema-version="1.0" \ - org.label-schema.docker.cmd="docker run ${IMAGE_NAME} powershell -c '$psversiontable'" \ + org.label-schema.docker.cmd="docker run ${IMAGE_NAME} pwsh -c '$psversiontable'" \ org.label-schema.docker.cmd.devel="docker run ${IMAGE_NAME}" \ - org.label-schema.docker.cmd.test="docker run ${IMAGE_NAME} powershell -c Invoke-Pester" \ - org.label-schema.docker.cmd.help="docker run ${IMAGE_NAME} powershell -c Get-Help" + org.label-schema.docker.cmd.test="docker run ${IMAGE_NAME} pwsh -c Invoke-Pester" \ + org.label-schema.docker.cmd.help="docker run ${IMAGE_NAME} pwsh -c Get-Help" # TODO: addd LABEL org.label-schema.vcs-ref=${VCS_REF} # Install dependencies and clean up -RUN dnf install -y \ +RUN dnf install -y \ curl \ glibc-locale-source \ && dnf clean all @@ -37,7 +37,8 @@ RUN localedef --charmap=UTF-8 --inputfile=en_US $LANG RUN curl https://packages.microsoft.com/config/rhel/7/prod.repo | tee /etc/yum.repos.d/microsoft.repo # Install latest powershell from Microsoft YUM Repo -RUN dnf install -y powershell +RUN dnf install -y powershell \ + && dnf clean all # Use array to avoid Docker prepending /bin/sh -c -CMD [ "powershell" ] +CMD [ "pwsh" ] diff --git a/docker/release/fedora25/Dockerfile b/docker/release/fedora27/Dockerfile similarity index 79% rename from docker/release/fedora25/Dockerfile rename to docker/release/fedora27/Dockerfile index a8010f9c4f9..276d1716cbb 100644 --- a/docker/release/fedora25/Dockerfile +++ b/docker/release/fedora27/Dockerfile @@ -1,9 +1,9 @@ -# Docker image file that describes an fedora 25 image with PowerShell installed from Microsoft YUM Repo +# Docker image file that describes an fedora 27 image with PowerShell installed from Microsoft YUM Repo -FROM fedora:25 +FROM fedora:27 -ARG POWERSHELL_VERSION=6.0.0-beta.8 -ARG IMAGE_NAME=microsoft/powershell:fedora25 +ARG POWERSHELL_VERSION=6.0.2 +ARG IMAGE_NAME=microsoft/powershell:fedora27 LABEL maintainer="PowerShell Team " \ readme.md="https://github.com/PowerShell/PowerShell/blob/master/docker/README.md" \ @@ -15,15 +15,15 @@ LABEL maintainer="PowerShell Team " \ org.label-schema.vendor="PowerShell" \ org.label-schema.version=${POWERSHELL_VERSION} \ org.label-schema.schema-version="1.0" \ - org.label-schema.docker.cmd="docker run ${IMAGE_NAME} powershell -c '$psversiontable'" \ + org.label-schema.docker.cmd="docker run ${IMAGE_NAME} pwsh -c '$psversiontable'" \ org.label-schema.docker.cmd.devel="docker run ${IMAGE_NAME}" \ - org.label-schema.docker.cmd.test="docker run ${IMAGE_NAME} powershell -c Invoke-Pester" \ - org.label-schema.docker.cmd.help="docker run ${IMAGE_NAME} powershell -c Get-Help" + org.label-schema.docker.cmd.test="docker run ${IMAGE_NAME} pwsh -c Invoke-Pester" \ + org.label-schema.docker.cmd.help="docker run ${IMAGE_NAME} pwsh -c Get-Help" # TODO: addd LABEL org.label-schema.vcs-ref=${VCS_REF} # Install dependencies and clean up -RUN dnf install -y \ +RUN dnf install -y \ curl \ glibc-locale-source \ && dnf clean all @@ -37,7 +37,8 @@ RUN localedef --charmap=UTF-8 --inputfile=en_US $LANG RUN curl https://packages.microsoft.com/config/rhel/7/prod.repo | tee /etc/yum.repos.d/microsoft.repo # Install latest powershell from Microsoft YUM Repo -RUN dnf install -y powershell +RUN dnf install -y powershell \ + && dnf clean all # Use array to avoid Docker prepending /bin/sh -c -CMD [ "powershell" ] +CMD [ "pwsh" ] diff --git a/docker/release/nanoserver-insider/Dockerfile b/docker/release/nanoserver-insider/Dockerfile deleted file mode 100755 index 2a20c8b5c8a..00000000000 --- a/docker/release/nanoserver-insider/Dockerfile +++ /dev/null @@ -1,55 +0,0 @@ -# escape=` -# Args used by from statements must be defined here: -ARG NanoServerVersion=10.0.16257.1000 -ARG WindowsServerCoreVersion=10.0.16257.1000 -ARG WindowsServerCoreRepo=microsoft/windowsservercore-insider -ARG NanoServerRepo=microsoft/nanoserver-insider - -# Use server core as an installer container to extract PowerShell, -# As this is a multi-stage build, this stage will eventually be thrown away -FROM ${WindowsServerCoreRepo}:$WindowsServerCoreVersion AS installer-env - -# Arguments for installing powershell, must be defined in the container they are used -ARG PS_VERSION=6.0.0-beta.8 - -ENV PS_DOWNLOAD_URL https://github.com/PowerShell/PowerShell/releases/download/v$PS_VERSION/PowerShell-$PS_VERSION-win-x64.zip - -SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] -RUN Invoke-WebRequest $Env:PS_DOWNLOAD_URL -OutFile powershell.zip - -RUN Expand-Archive powershell.zip -DestinationPath \PowerShell - -# Install PowerShell into NanoServer -FROM ${NanoServerRepo}:$NanoServerVersion - -ARG VCS_REF="none" -ARG PS_VERSION=6.0.0-beta.8 -ARG IMAGE_NAME=microsoft/nanoserver-insider-powershell - -LABEL maintainer="PowerShell Team " ` - readme.md="https://github.com/PowerShell/PowerShell/blob/master/docker/README.md" ` - description="This Dockerfile will install the latest release of PS." ` - org.label-schema.usage="https://github.com/PowerShell/PowerShell/tree/master/docker#run-the-docker-image-you-built" ` - org.label-schema.url="https://github.com/PowerShell/PowerShell/blob/master/docker/README.md" ` - org.label-schema.vcs-url="https://github.com/PowerShell/PowerShell" ` - org.label-schema.name="powershell" ` - org.label-schema.vcs-ref=${VCS_REF} ` - org.label-schema.vendor="PowerShell" ` - org.label-schema.version=${PS_VERSION} ` - org.label-schema.schema-version="1.0" ` - org.label-schema.docker.cmd="docker run ${IMAGE_NAME} powershell -c '$psversiontable'" ` - org.label-schema.docker.cmd.devel="docker run ${IMAGE_NAME}" ` - org.label-schema.docker.cmd.test="docker run ${IMAGE_NAME} powershell -c Invoke-Pester" ` - org.label-schema.docker.cmd.help="docker run ${IMAGE_NAME} powershell -c Get-Help" - -# Copy Powershell from the installer containter -ENV ProgramFiles C:\Program Files -COPY --from=installer-env ["\\PowerShell\\", "$ProgramFiles\\PowerShell"] - -# Persist %PSCORE% ENV variable for user convenience -ENV PSCORE="$ProgramFiles\PowerShell\PowerShell.exe" - -# Set the path -RUN setx PATH "%PATH%;%ProgramFiles%\PowerShell" - -CMD ["PowerShell.exe"] diff --git a/docker/release/nanoserver/Dockerfile b/docker/release/nanoserver/Dockerfile old mode 100644 new mode 100755 index 47569baefb5..bb4477da1f9 --- a/docker/release/nanoserver/Dockerfile +++ b/docker/release/nanoserver/Dockerfile @@ -1,9 +1,32 @@ # escape=` -FROM microsoft/nanoserver:latest +# Args used by from statements must be defined here: +ARG NanoServerVersion=1709 +ARG WindowsServerCoreVersion=latest +ARG WindowsServerCoreRepo=microsoft/windowsservercore +ARG NanoServerRepo=microsoft/nanoserver -ARG POWERSHELL_ZIP=https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-beta.8/PowerShell-6.0.0-beta.8-win-x64.zip -ARG POWERSHELL_VERSION=6.0.0-beta.8 -ARG IMAGE_NAME=microsoft/powershell:nanoserver +# Use server core as an installer container to extract PowerShell, +# As this is a multi-stage build, this stage will eventually be thrown away +FROM ${WindowsServerCoreRepo}:$WindowsServerCoreVersion AS installer-env + +# Arguments for installing powershell, must be defined in the container they are used +ARG PS_VERSION=6.0.2 + +ENV PS_DOWNLOAD_URL https://github.com/PowerShell/PowerShell/releases/download/v$PS_VERSION/PowerShell-$PS_VERSION-win-x64.zip + +SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] + +RUN if (!($env:PS_VERSION -match '^\d+\.\d+\.\d+(-\w+(\.\d+)?)?$' )) {throw ('PS_Version ({0}) must match the regex "^\d+\.\d+\.\d+(-\w+(\.\d+)?)?$"' -f $env:PS_VERSION)} +ADD $PS_DOWNLOAD_URL /powershell.zip + +RUN Expand-Archive powershell.zip -DestinationPath \PowerShell + +# Install PowerShell into NanoServer +FROM ${NanoServerRepo}:$NanoServerVersion + +ARG VCS_REF="none" +ARG PS_VERSION=6.0.2 +ARG IMAGE_NAME=microsoft/powershell LABEL maintainer="PowerShell Team " ` readme.md="https://github.com/PowerShell/PowerShell/blob/master/docker/README.md" ` @@ -12,50 +35,23 @@ LABEL maintainer="PowerShell Team " ` org.label-schema.url="https://github.com/PowerShell/PowerShell/blob/master/docker/README.md" ` org.label-schema.vcs-url="https://github.com/PowerShell/PowerShell" ` org.label-schema.name="powershell" ` + org.label-schema.vcs-ref=${VCS_REF} ` org.label-schema.vendor="PowerShell" ` - org.label-schema.version=${POWERSHELL_VERSION} ` + org.label-schema.version=${PS_VERSION} ` org.label-schema.schema-version="1.0" ` - org.label-schema.docker.cmd="docker run ${IMAGE_NAME} powershell -c '$psversiontable'" ` + org.label-schema.docker.cmd="docker run ${IMAGE_NAME} pwsh -c '$psversiontable'" ` org.label-schema.docker.cmd.devel="docker run ${IMAGE_NAME}" ` - org.label-schema.docker.cmd.test="docker run ${IMAGE_NAME} powershell -c Invoke-Pester" ` - org.label-schema.docker.cmd.help="docker run ${IMAGE_NAME} powershell -c Get-Help" - -# TODO: addd LABEL org.label-schema.vcs-ref=${VCS_REF} - -RUN setx /M PATH "%ProgramFiles%\PowerShell\latest;%PATH%" -# Setup PowerShell - Log-to > C:\Docker.log -SHELL ["C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", "-command"] -ADD $POWERSHELL_ZIP /powershell-win-x64.zip - -# Install PowerShell package and clean up -RUN $ErrorActionPreference='Stop'; ` - $ConfirmPreference='None'; ` - $VerbosePreference='Continue'; ` - Start-Transcript -path C:\Dockerfile.log -append -IncludeInvocationHeader ; ` - $PSVersionTable | Write-Output ; ` - $VerInfo = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' ; ` - ('FullBuildString: '+$VerInfo.BuildLabEx) | Write-Output ; ` - ('OperatingSystem: '+$VerInfo.ProductName+' '+$VerInfo.EditionId+' '+$VerInfo.InstallationType) | Write-Output ; ` - [System.IO.FileInfo]$ZipFile = Get-Item -Path ./powershell-win-x64.zip ; ` - New-Item -Path $Env:ProgramFiles/PowerShell -ItemType Directory -Force | out-null ; ` - [System.IO.DirectoryInfo]$PsFolder=New-Item -Path $Env:ProgramFiles\PowerShell -ItemType Directory -Force ; ` - Add-Type -AssemblyName System.IO.Compression.ZipFile ; ` - [System.IO.Compression.ZipFile]::ExtractToDirectory($ZipFile,$PsFolder) ; ` - if (Get-ChildItem -Path $PsFolder/powershell.exe) { ` - Remove-Item -Path $ZipFile ; ` - New-Item -Type SymbolicLink -Path $PsFolder\ -Name latest -Value $PsFolder ` - } else { throw 'Installation failed! See c:\Dockerfile.log' } ; - -# Verify New Powershell.exe runs -SHELL ["C:\\Program Files\\PowerShell\\latest\\PowerShell.exe", "-command"] -RUN Start-Transcript -path C:\Dockerfile.log -append -IncludeInvocationHeader ; ` - $ErrorActionPreference='Stop'; ` - Write-Output $PSVersionTable ; ` - If (-not($PSVersionTable.PSEdition -Match 'Core')) { ` - Throw [String]$('['+$PSVersionTable.PSEdition+'] is not [Core]!') ; ` - } ; + org.label-schema.docker.cmd.test="docker run ${IMAGE_NAME} pwsh -c Invoke-Pester" ` + org.label-schema.docker.cmd.help="docker run ${IMAGE_NAME} pwsh -c Get-Help" + +# Copy Powershell Core from the installer containter +ENV ProgramFiles C:\Program Files +COPY --from=installer-env ["\\PowerShell\\", "$ProgramFiles\\PowerShell"] # Persist %PSCORE% ENV variable for user convenience -ENV PSCORE='"C:\Program Files\PowerShell\latest\PowerShell.exe"' +ENV PSCORE="$ProgramFiles\PowerShell\pwsh.exe" + +# Set the path +RUN setx PATH "%PATH%;%ProgramFiles%\PowerShell" -CMD ["PowerShell.exe"] +CMD ["pwsh.exe"] diff --git a/docker/release/opensuse42.2/Dockerfile b/docker/release/opensuse42.2/Dockerfile index ded9ba4824b..30cea5e7844 100644 --- a/docker/release/opensuse42.2/Dockerfile +++ b/docker/release/opensuse42.2/Dockerfile @@ -2,8 +2,8 @@ FROM opensuse:42.2 -ARG POWERSHELL_VERSION=6.0.0-beta.8 -ARG POWERSHELL_PACKAGE=powershell-6.0.0-beta.8-linux-x64.tar.gz +ARG POWERSHELL_VERSION=6.0.2 +ARG POWERSHELL_PACKAGE=powershell-6.0.2-linux-x64.tar.gz ARG IMAGE_NAME=microsoft/powershell:opensuse42.2 LABEL maintainer="PowerShell Team " \ @@ -16,10 +16,10 @@ LABEL maintainer="PowerShell Team " \ org.label-schema.vendor="PowerShell" \ org.label-schema.version=${POWERSHELL_VERSION} \ org.label-schema.schema-version="1.0" \ - org.label-schema.docker.cmd="docker run ${IMAGE_NAME} powershell -c '$psversiontable'" \ + org.label-schema.docker.cmd="docker run ${IMAGE_NAME} pwsh -c '$psversiontable'" \ org.label-schema.docker.cmd.devel="docker run ${IMAGE_NAME}" \ - org.label-schema.docker.cmd.test="docker run ${IMAGE_NAME} powershell -c Invoke-Pester" \ - org.label-schema.docker.cmd.help="docker run ${IMAGE_NAME} powershell -c Get-Help" + org.label-schema.docker.cmd.test="docker run ${IMAGE_NAME} pwsh -c Invoke-Pester" \ + org.label-schema.docker.cmd.help="docker run ${IMAGE_NAME} pwsh -c Get-Help" # TODO: addd LABEL org.label-schema.vcs-ref=${VCS_REF} @@ -54,4 +54,4 @@ RUN /InstallTarballPackage.sh $POWERSHELL_VERSION $POWERSHELL_PACKAGE # Remove the script RUN rm -f /InstallTarballPackage.sh -CMD [ "powershell" ] +CMD [ "pwsh" ] diff --git a/docker/release/ubuntu14.04/Dockerfile b/docker/release/ubuntu14.04/Dockerfile index bfaedd808b8..0fc946026c0 100644 --- a/docker/release/ubuntu14.04/Dockerfile +++ b/docker/release/ubuntu14.04/Dockerfile @@ -2,7 +2,7 @@ FROM ubuntu:trusty -ARG POWERSHELL_VERSION=6.0.0-beta.8 +ARG POWERSHELL_VERSION=6.0.2 ARG IMAGE_NAME=microsoft/powershell:ubuntu14.04 LABEL maintainer="PowerShell Team " \ @@ -15,10 +15,10 @@ LABEL maintainer="PowerShell Team " \ org.label-schema.vendor="PowerShell" \ org.label-schema.version=${POWERSHELL_VERSION} \ org.label-schema.schema-version="1.0" \ - org.label-schema.docker.cmd="docker run ${IMAGE_NAME} powershell -c '$psversiontable'" \ + org.label-schema.docker.cmd="docker run ${IMAGE_NAME} pwsh -c '$psversiontable'" \ org.label-schema.docker.cmd.devel="docker run ${IMAGE_NAME}" \ - org.label-schema.docker.cmd.test="docker run ${IMAGE_NAME} powershell -c Invoke-Pester" \ - org.label-schema.docker.cmd.help="docker run ${IMAGE_NAME} powershell -c Get-Help" + org.label-schema.docker.cmd.test="docker run ${IMAGE_NAME} pwsh -c Invoke-Pester" \ + org.label-schema.docker.cmd.help="docker run ${IMAGE_NAME} pwsh -c Get-Help" # TODO: addd LABEL org.label-schema.vcs-ref=${VCS_REF} @@ -33,12 +33,12 @@ RUN apt-get update \ apt-utils \ ca-certificates \ curl \ - apt-transport-https \ + apt-transport-https \ && rm -rf /var/lib/apt/lists/* # Import the public repository GPG keys for Microsoft RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - - + # Register the Microsoft Ubuntu 14.04 repository RUN curl https://packages.microsoft.com/config/ubuntu/14.04/prod.list | tee /etc/apt/sources.list.d/microsoft.list @@ -49,4 +49,4 @@ RUN apt-get update \ # Use PowerShell as the default shell # Use array to avoid Docker prepending /bin/sh -c -CMD [ "powershell" ] +CMD [ "pwsh" ] diff --git a/docker/release/ubuntu16.04/Dockerfile b/docker/release/ubuntu16.04/Dockerfile index 6190970a419..2fd44e6f1b1 100644 --- a/docker/release/ubuntu16.04/Dockerfile +++ b/docker/release/ubuntu16.04/Dockerfile @@ -2,7 +2,7 @@ FROM ubuntu:xenial -ARG POWERSHELL_VERSION=6.0.0-beta.8 +ARG POWERSHELL_VERSION=6.0.2 ARG IMAGE_NAME=microsoft/powershell:ubuntu16.04 LABEL maintainer="PowerShell Team " \ @@ -15,10 +15,10 @@ LABEL maintainer="PowerShell Team " \ org.label-schema.vendor="PowerShell" \ org.label-schema.version=${POWERSHELL_VERSION} \ org.label-schema.schema-version="1.0" \ - org.label-schema.docker.cmd="docker run ${IMAGE_NAME} powershell -c '$psversiontable'" \ + org.label-schema.docker.cmd="docker run ${IMAGE_NAME} pwsh -c '$psversiontable'" \ org.label-schema.docker.cmd.devel="docker run ${IMAGE_NAME}" \ - org.label-schema.docker.cmd.test="docker run ${IMAGE_NAME} powershell -c Invoke-Pester" \ - org.label-schema.docker.cmd.help="docker run ${IMAGE_NAME} powershell -c Get-Help" + org.label-schema.docker.cmd.test="docker run ${IMAGE_NAME} pwsh -c Invoke-Pester" \ + org.label-schema.docker.cmd.help="docker run ${IMAGE_NAME} pwsh -c Get-Help" # TODO: addd LABEL org.label-schema.vcs-ref=${VCS_REF} @@ -39,7 +39,7 @@ RUN locale-gen $LANG && update-locale # Import the public repository GPG keys for Microsoft RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - - + # Register the Microsoft Ubuntu 16.04 repository RUN curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list | tee /etc/apt/sources.list.d/microsoft.list @@ -50,4 +50,4 @@ RUN apt-get update \ # Use PowerShell as the default shell # Use array to avoid Docker prepending /bin/sh -c -CMD [ "powershell" ] +CMD [ "pwsh" ] diff --git a/docker/release/windowsservercore/Dockerfile b/docker/release/windowsservercore/Dockerfile index c5c19780360..2f587c9c006 100644 --- a/docker/release/windowsservercore/Dockerfile +++ b/docker/release/windowsservercore/Dockerfile @@ -1,8 +1,8 @@ # escape=` FROM microsoft/windowsservercore:latest -ARG POWERSHELL_MSI=https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-beta.8/PowerShell-6.0.0-beta.8-win-x64.msi -ARG POWERSHELL_VERSION=6.0.0-beta.8 +ARG POWERSHELL_MSI=https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/PowerShell-6.0.2-win-x64.msi +ARG POWERSHELL_VERSION=6.0.2 ARG IMAGE_NAME=microsoft/powershell:windowsservercore LABEL maintainer="PowerShell Team " ` @@ -15,10 +15,10 @@ LABEL maintainer="PowerShell Team " ` org.label-schema.vendor="PowerShell" ` org.label-schema.version=${POWERSHELL_VERSION} ` org.label-schema.schema-version="1.0" ` - org.label-schema.docker.cmd="docker run ${IMAGE_NAME} powershell -c '$psversiontable'" ` + org.label-schema.docker.cmd="docker run ${IMAGE_NAME} pwsh -c '$psversiontable'" ` org.label-schema.docker.cmd.devel="docker run ${IMAGE_NAME}" ` - org.label-schema.docker.cmd.test="docker run ${IMAGE_NAME} powershell -c Invoke-Pester" ` - org.label-schema.docker.cmd.help="docker run ${IMAGE_NAME} powershell -c Get-Help" + org.label-schema.docker.cmd.test="docker run ${IMAGE_NAME} pwsh -c Invoke-Pester" ` + org.label-schema.docker.cmd.help="docker run ${IMAGE_NAME} pwsh -c Get-Help" # TODO: addd LABEL org.label-schema.vcs-ref=${VCS_REF} @@ -42,12 +42,12 @@ RUN $ErrorActionPreference='Stop'; ` $log=get-content -Path C:\PowerShell-win-x64.msi.log -Last 10 ; ` if ($log -match 'Installation success or error status: 0') { ` Remove-Item -Path $MsiFile ; ` - $psexe=Get-Item -Path $Env:ProgramFiles\PowerShell\*\powershell.exe ; ` + $psexe=Get-Item -Path $Env:ProgramFiles\PowerShell\*\pwsh.exe ; ` New-Item -Type SymbolicLink -Path $Env:ProgramFiles\PowerShell\ -Name latest -Value $psexe.DirectoryName ` } else { throw 'Installation failed! See c:\PowerShell-win-x64.msi.log' } ; -# Verify New Powershell.exe runs -SHELL ["C:\\Program Files\\PowerShell\\latest\\PowerShell.exe", "-command"] +# Verify New pwsh.exe runs +SHELL ["C:\\Program Files\\PowerShell\\latest\\pwsh.exe", "-command"] RUN Start-Transcript -path C:\Dockerfile.log -append -IncludeInvocationHeader ; ` $ErrorActionPreference='Stop'; ` Write-Output $PSVersionTable ; ` @@ -56,6 +56,6 @@ RUN Start-Transcript -path C:\Dockerfile.log -append -IncludeInvocationHeader ; } ; # Persist %PSCORE% ENV variable for user convenience -ENV PSCORE='"C:\Program Files\PowerShell\latest\PowerShell.exe"' +ENV PSCORE='"C:\Program Files\PowerShell\latest\pwsh.exe"' -CMD ["PowerShell.exe"] +CMD ["pwsh.exe"] diff --git a/docker/tests/Templates/centos7/Dockerfile b/docker/tests/Templates/centos7/Dockerfile new file mode 100644 index 00000000000..afb73c746e7 --- /dev/null +++ b/docker/tests/Templates/centos7/Dockerfile @@ -0,0 +1,23 @@ +FROM centos:7 + +ARG PSVERSIONSTUB=6.0.2 +ARG PSVERSIONSTUBRPM=6.0.2 +ARG PACKAGELOCATIONSTUB +ARG TESTLISTSTUB=/PowerShell/test/powershell/Modules/PackageManagement/PackageManagement.Tests.ps1,/PowerShell/test/powershell/engine/Module +ARG GITLOCATION=https://github.com/PowerShell/PowerShell.git + +# Install dependencies +RUN yum install -y \ + curl \ + glibc-locale-source \ + git + +# Setup the locale +ENV LANG en_US.UTF-8 +ENV LC_ALL $LANG +RUN localedef --charmap=UTF-8 --inputfile=en_US $LANG + +RUN curl -L -o powershell-$PSVERSIONSTUBRPM-1.rhel.7.x86_64.rpm $PACKAGELOCATIONSTUB/powershell-$PSVERSIONSTUBRPM-1.rhel.7.x86_64.rpm +RUN yum install -y powershell-$PSVERSIONSTUBRPM-1.rhel.7.x86_64.rpm +RUN git clone --recursive $GITLOCATION +RUN pwsh -c "Import-Module /PowerShell/build.psm1;\$dir='/usr/local/share/powershell/Modules';New-Item -Type Directory -Path \$dir -ErrorAction SilentlyContinue;Restore-PSPester -Destination \$dir;exit (Invoke-Pester $TESTLISTSTUB -PassThru).FailedCount" diff --git a/docker/tests/Templates/debian.8/Dockerfile b/docker/tests/Templates/debian.8/Dockerfile new file mode 100644 index 00000000000..8ae8f645f72 --- /dev/null +++ b/docker/tests/Templates/debian.8/Dockerfile @@ -0,0 +1,28 @@ +FROM debian:jessie + +ARG PSVERSIONSTUB=6.0.2 +ARG PSVERSIONSTUBRPM=6.0.2 +ARG PACKAGELOCATIONSTUB +ARG TESTLISTSTUB=/PowerShell/test/powershell/Modules/PackageManagement/PackageManagement.Tests.ps1,/PowerShell/test/powershell/engine/Module +ARG GITLOCATION=https://github.com/PowerShell/PowerShell.git + +# Install dependencies +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + apt-utils \ + ca-certificates \ + curl \ + apt-transport-https \ + locales \ + git + +# Setup the locale +ENV LANG en_US.UTF-8 +ENV LC_ALL $LANG +RUN locale-gen $LANG && update-locale + +RUN curl -L -o powershell_$PSVERSIONSTUB-1.debian.8_amd64.deb $PACKAGELOCATIONSTUB/powershell_$PSVERSIONSTUB-1.debian.8_amd64.deb +RUN dpkg -i powershell_$PSVERSIONSTUB-1.debian.8_amd64.deb || : +RUN apt-get install -y -f +RUN git clone --recursive $GITLOCATION +RUN pwsh -c "Import-Module /PowerShell/build.psm1;\$dir='/usr/local/share/powershell/Modules';New-Item -Type Directory -Path \$dir -ErrorAction SilentlyContinue;Restore-PSPester -Destination \$dir;exit (Invoke-Pester $TESTLISTSTUB -PassThru).FailedCount" diff --git a/docker/tests/Templates/debian.9/Dockerfile b/docker/tests/Templates/debian.9/Dockerfile new file mode 100644 index 00000000000..500f4665a02 --- /dev/null +++ b/docker/tests/Templates/debian.9/Dockerfile @@ -0,0 +1,28 @@ +FROM debian:stretch + +ARG PSVERSIONSTUB=6.0.2 +ARG PSVERSIONSTUBRPM=6.0.2 +ARG PACKAGELOCATIONSTUB +ARG TESTLISTSTUB=/PowerShell/test/powershell/Modules/PackageManagement/PackageManagement.Tests.ps1,/PowerShell/test/powershell/engine/Module +ARG GITLOCATION=https://github.com/PowerShell/PowerShell.git + +# Install dependencies +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + apt-utils \ + ca-certificates \ + curl \ + apt-transport-https \ + locales \ + git + +# Setup the locale +ENV LANG en_US.UTF-8 +ENV LC_ALL $LANG +RUN locale-gen $LANG && update-locale + +RUN curl -L -o powershell_$PSVERSIONSTUB-1.debian.9_amd64.deb $PACKAGELOCATIONSTUB/powershell_$PSVERSIONSTUB-1.debian.9_amd64.deb +RUN dpkg -i powershell_$PSVERSIONSTUB-1.debian.9_amd64.deb || : +RUN apt-get install -y -f +RUN git clone --recursive $GITLOCATION +RUN pwsh -c "Import-Module /PowerShell/build.psm1;\$dir='/usr/local/share/powershell/Modules';New-Item -Type Directory -Path \$dir -ErrorAction SilentlyContinue;Restore-PSPester -Destination \$dir;exit (Invoke-Pester $TESTLISTSTUB -PassThru).FailedCount" diff --git a/docker/tests/Templates/fedora26/Dockerfile b/docker/tests/Templates/fedora26/Dockerfile new file mode 100644 index 00000000000..906101d7f48 --- /dev/null +++ b/docker/tests/Templates/fedora26/Dockerfile @@ -0,0 +1,24 @@ +FROM fedora:26 + +ARG PSVERSIONSTUB=6.0.2 +ARG PSVERSIONSTUBRPM=6.0.2 +ARG PACKAGELOCATIONSTUB +ARG TESTLISTSTUB=/PowerShell/test/powershell/Modules/PackageManagement/PackageManagement.Tests.ps1,/PowerShell/test/powershell/engine/Module +ARG GITLOCATION=https://github.com/PowerShell/PowerShell.git + +# Install dependencies +RUN dnf install -y \ + curl \ + glibc-locale-source \ + compat-openssl10 \ + git + +# Setup the locale +ENV LANG en_US.UTF-8 +ENV LC_ALL $LANG +RUN localedef --charmap=UTF-8 --inputfile=en_US $LANG + +RUN curl -L -o powershell-$PSVERSIONSTUBRPM-1.rhel.7.x86_64.rpm $PACKAGELOCATIONSTUB/powershell-$PSVERSIONSTUBRPM-1.rhel.7.x86_64.rpm +RUN dnf install -y powershell-$PSVERSIONSTUBRPM-1.rhel.7.x86_64.rpm +RUN git clone --recursive $GITLOCATION +RUN pwsh -c "Import-Module /PowerShell/build.psm1;\$dir='/usr/local/share/powershell/Modules';New-Item -Type Directory -Path \$dir -ErrorAction SilentlyContinue;Restore-PSPester -Destination \$dir;exit (Invoke-Pester $TESTLISTSTUB -PassThru).FailedCount" diff --git a/docker/tests/Templates/fedora27/Dockerfile b/docker/tests/Templates/fedora27/Dockerfile new file mode 100644 index 00000000000..2e27dee63ad --- /dev/null +++ b/docker/tests/Templates/fedora27/Dockerfile @@ -0,0 +1,23 @@ +FROM fedora:27 + +ARG PSVERSIONSTUB=6.0.2 +ARG PSVERSIONSTUBRPM=6.0.2 +ARG PACKAGELOCATIONSTUB +ARG TESTLISTSTUB=/PowerShell/test/powershell/Modules/PackageManagement/PackageManagement.Tests.ps1,/PowerShell/test/powershell/engine/Module +ARG GITLOCATION=https://github.com/PowerShell/PowerShell.git + +# Install dependencies +RUN dnf install -y \ + curl \ + glibc-locale-source \ + git + +# Setup the locale +ENV LANG en_US.UTF-8 +ENV LC_ALL $LANG +RUN localedef --charmap=UTF-8 --inputfile=en_US $LANG + +RUN curl -L -o powershell-$PSVERSIONSTUBRPM-1.rhel.7.x86_64.rpm $PACKAGELOCATIONSTUB/powershell-$PSVERSIONSTUBRPM-1.rhel.7.x86_64.rpm +RUN dnf install -y powershell-$PSVERSIONSTUBRPM-1.rhel.7.x86_64.rpm +RUN git clone --recursive $GITLOCATION +RUN pwsh -c "Import-Module /PowerShell/build.psm1;\$dir='/usr/local/share/powershell/Modules';New-Item -Type Directory -Path \$dir -ErrorAction SilentlyContinue;Restore-PSPester -Destination \$dir;exit (Invoke-Pester $TESTLISTSTUB -PassThru).FailedCount" diff --git a/docker/tests/Templates/kalilinux/Dockerfile b/docker/tests/Templates/kalilinux/Dockerfile new file mode 100644 index 00000000000..58e447102e1 --- /dev/null +++ b/docker/tests/Templates/kalilinux/Dockerfile @@ -0,0 +1,30 @@ +FROM kalilinux/kali-linux-docker:latest + +ARG PSVERSIONSTUB=6.0.2 +ARG PSVERSIONSTUBRPM=6.0.2 +ARG PACKAGELOCATIONSTUB +ARG TESTLISTSTUB=/PowerShell/test/powershell/Modules/PackageManagement/PackageManagement.Tests.ps1,/PowerShell/test/powershell/engine/Module +ARG GITLOCATION=https://github.com/PowerShell/PowerShell.git + +# Install dependencies +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + apt-utils \ + ca-certificates \ + curl \ + apt-transport-https \ + locales \ + git + +# Setup the locale +ENV LANG en_US.UTF-8 +ENV LC_ALL $LANG +RUN locale-gen $LANG && update-locale + +RUN curl -L -o libssl1.0.0_1.0.1t-1+deb8u7_amd64.deb http://security.debian.org/debian-security/pool/updates/main/o/openssl/libssl1.0.0_1.0.1t-1+deb8u7_amd64.deb +RUN curl -L -o powershell_$PSVERSIONSTUB-1.ubuntu.16.04_amd64.deb $PACKAGELOCATIONSTUB/powershell_$PSVERSIONSTUB-1.ubuntu.16.04_amd64.deb +RUN dpkg -i libssl1.0.0_1.0.1t-1+deb8u7_amd64.deb || : +RUN dpkg -i powershell_$PSVERSIONSTUB-1.ubuntu.16.04_amd64.deb || : +RUN apt-get install -y -f +RUN git clone --recursive $GITLOCATION +RUN pwsh -c "Import-Module /PowerShell/build.psm1;\$dir='/usr/local/share/powershell/Modules';New-Item -Type Directory -Path \$dir -ErrorAction SilentlyContinue;Restore-PSPester -Destination \$dir;exit (Invoke-Pester $TESTLISTSTUB -PassThru).FailedCount" diff --git a/docker/tests/Templates/opensuse42.2/Dockerfile b/docker/tests/Templates/opensuse42.2/Dockerfile new file mode 100644 index 00000000000..33f38b310fb --- /dev/null +++ b/docker/tests/Templates/opensuse42.2/Dockerfile @@ -0,0 +1,39 @@ +FROM opensuse:42.2 + +ARG PSVERSIONSTUB=6.0.2 +ARG PSVERSIONSTUBRPM=6.0.2 +ARG PACKAGELOCATIONSTUB +ARG TESTLISTSTUB=/PowerShell/test/powershell/Modules/PackageManagement/PackageManagement.Tests.ps1,/PowerShell/test/powershell/engine/Module +ARG GITLOCATION=https://github.com/PowerShell/PowerShell.git + +ARG POWERSHELL_LINKFILE=/usr/bin/pwsh + +# Install dependencies +RUN zypper --non-interactive update --skip-interactive \ + && zypper --non-interactive install \ + glibc-locale \ + glibc-i18ndata \ + tar \ + curl \ + libunwind \ + libicu \ + openssl \ + git + +# Setup the locale +ENV LANG en_US.UTF-8 +ENV LC_ALL $LANG +RUN localedef --charmap=UTF-8 --inputfile=en_US $LANG + +RUN curl -L -o powershell-$PSVERSIONSTUB-linux-x64.tar.gz $PACKAGELOCATIONSTUB/powershell-$PSVERSIONSTUB-linux-x64.tar.gz + +# Create the target folder where powershell will be placed +RUN mkdir -p /opt/microsoft/powershell/$PSVERSIONSTUB +# Expand powershell to the target folder +RUN tar zxf powershell-$PSVERSIONSTUB-linux-x64.tar.gz -C /opt/microsoft/powershell/$PSVERSIONSTUB + +# Create the symbolic link that points to powershell +RUN ln -s /opt/microsoft/powershell/$PSVERSIONSTUB/pwsh $POWERSHELL_LINKFILE + +RUN git clone --recursive $GITLOCATION +RUN pwsh -c "Import-Module /PowerShell/build.psm1;\$dir='/usr/local/share/powershell/Modules';New-Item -Type Directory -Path \$dir -ErrorAction SilentlyContinue;Restore-PSPester -Destination \$dir;exit (Invoke-Pester $TESTLISTSTUB -PassThru).FailedCount" diff --git a/docker/tests/Templates/ubuntu14.04/Dockerfile b/docker/tests/Templates/ubuntu14.04/Dockerfile new file mode 100644 index 00000000000..5a5c54f6219 --- /dev/null +++ b/docker/tests/Templates/ubuntu14.04/Dockerfile @@ -0,0 +1,28 @@ +FROM ubuntu:trusty + +ARG PSVERSIONSTUB=6.0.2 +ARG PSVERSIONSTUBRPM=6.0.2 +ARG PACKAGELOCATIONSTUB +ARG TESTLISTSTUB=/PowerShell/test/powershell/Modules/PackageManagement/PackageManagement.Tests.ps1,/PowerShell/test/powershell/engine/Module +ARG GITLOCATION=https://github.com/PowerShell/PowerShell.git + +# Install dependencies +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + apt-utils \ + ca-certificates \ + curl \ + apt-transport-https \ + locales \ + git + +# Setup the locale +ENV LANG en_US.UTF-8 +ENV LC_ALL $LANG +RUN locale-gen $LANG && update-locale + +RUN curl -L -o powershell_$PSVERSIONSTUB-1.ubuntu.14.04_amd64.deb $PACKAGELOCATIONSTUB/powershell_$PSVERSIONSTUB-1.ubuntu.14.04_amd64.deb +RUN dpkg -i powershell_$PSVERSIONSTUB-1.ubuntu.14.04_amd64.deb || : +RUN apt-get install -y -f +RUN git clone --recursive $GITLOCATION +RUN pwsh -c "Import-Module /PowerShell/build.psm1;\$dir='/usr/local/share/powershell/Modules';New-Item -Type Directory -Path \$dir -ErrorAction SilentlyContinue;Restore-PSPester -Destination \$dir;exit (Invoke-Pester $TESTLISTSTUB -PassThru).FailedCount" diff --git a/docker/tests/Templates/ubuntu16.04/Dockerfile b/docker/tests/Templates/ubuntu16.04/Dockerfile new file mode 100644 index 00000000000..a20171a33f2 --- /dev/null +++ b/docker/tests/Templates/ubuntu16.04/Dockerfile @@ -0,0 +1,28 @@ +FROM ubuntu:xenial + +ARG PSVERSIONSTUB=6.0.2 +ARG PSVERSIONSTUBRPM=6.0.2 +ARG PACKAGELOCATIONSTUB +ARG TESTLISTSTUB=/PowerShell/test/powershell/Modules/PackageManagement/PackageManagement.Tests.ps1,/PowerShell/test/powershell/engine/Module +ARG GITLOCATION=https://github.com/PowerShell/PowerShell.git + +# Install dependencies +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + apt-utils \ + ca-certificates \ + curl \ + apt-transport-https \ + locales \ + git + +# Setup the locale +ENV LANG en_US.UTF-8 +ENV LC_ALL $LANG +RUN locale-gen $LANG && update-locale + +RUN curl -L -o powershell_$PSVERSIONSTUB-1.ubuntu.16.04_amd64.deb $PACKAGELOCATIONSTUB/powershell_$PSVERSIONSTUB-1.ubuntu.16.04_amd64.deb +RUN dpkg -i powershell_$PSVERSIONSTUB-1.ubuntu.16.04_amd64.deb || : +RUN apt-get install -y -f +RUN git clone --recursive $GITLOCATION +RUN pwsh -c "Import-Module /PowerShell/build.psm1;\$dir='/usr/local/share/powershell/Modules';New-Item -Type Directory -Path \$dir -ErrorAction SilentlyContinue;Restore-PSPester -Destination \$dir;exit (Invoke-Pester $TESTLISTSTUB -PassThru).FailedCount" diff --git a/docker/tests/Templates/ubuntu17.10/Dockerfile b/docker/tests/Templates/ubuntu17.10/Dockerfile new file mode 100644 index 00000000000..c698589e7cd --- /dev/null +++ b/docker/tests/Templates/ubuntu17.10/Dockerfile @@ -0,0 +1,28 @@ +FROM ubuntu:artful + +ARG PSVERSIONSTUB=6.0.2 +ARG PSVERSIONSTUBRPM=6.0.2 +ARG PACKAGELOCATIONSTUB +ARG TESTLISTSTUB=/PowerShell/test/powershell/Modules/PackageManagement/PackageManagement.Tests.ps1,/PowerShell/test/powershell/engine/Module +ARG GITLOCATION=https://github.com/PowerShell/PowerShell.git + +# Install dependencies +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + apt-utils \ + ca-certificates \ + curl \ + apt-transport-https \ + locales \ + git + +# Setup the locale +ENV LANG en_US.UTF-8 +ENV LC_ALL $LANG +RUN locale-gen $LANG && update-locale + +RUN curl -L -o powershell_$PSVERSIONSTUB-1.ubuntu.17.04_amd64.deb $PACKAGELOCATIONSTUB/powershell_$PSVERSIONSTUB-1.ubuntu.17.04_amd64.deb +RUN dpkg -i powershell_$PSVERSIONSTUB-1.ubuntu.17.04_amd64.deb || : +RUN apt-get install -y -f +RUN git clone --recursive $GITLOCATION +RUN pwsh -c "Import-Module /PowerShell/build.psm1;\$dir='/usr/local/share/powershell/Modules';New-Item -Type Directory -Path \$dir -ErrorAction SilentlyContinue;Restore-PSPester -Destination \$dir;exit (Invoke-Pester $TESTLISTSTUB -PassThru).FailedCount" diff --git a/docker/tests/container.tests.ps1 b/docker/tests/container.tests.ps1 index ea6a694bb74..f484fdab1c5 100644 --- a/docker/tests/container.tests.ps1 +++ b/docker/tests/container.tests.ps1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + Import-module -Name "$PSScriptRoot\containerTestCommon.psm1" -Force $script:linuxContainerTests = Get-LinuxContainer $script:windowsContainerTests = Get-WindowsContainer @@ -14,7 +17,7 @@ Describe "Build Linux Containers" -Tags 'Build', 'Linux' { [Parameter(Mandatory=$true)] [string] $name, - + [Parameter(Mandatory=$true)] [string] $path @@ -33,7 +36,7 @@ Describe "Build Windows Containers" -Tags 'Build', 'Windows' { [Parameter(Mandatory=$true)] [string] $name, - + [Parameter(Mandatory=$true)] [string] $path @@ -57,24 +60,23 @@ Describe "Linux Containers run PowerShell" -Tags 'Behavior', 'Linux' { # prune unused volumes $null=Invoke-Docker -Command 'volume', 'prune' -Params '--force' -SuppressHostOutput } - BeforeEach - { + BeforeEach { Remove-Item $testContext.resolvedXmlPath -ErrorAction SilentlyContinue Remove-Item $testContext.resolvedLogPath -ErrorAction SilentlyContinue } - + it "Get PSVersion table from $(Get-RepoName):" -TestCases $script:linuxContainerTests -Skip:$script:skipLinux { param( [Parameter(Mandatory=$true)] [string] $name, - + [Parameter(Mandatory=$true)] [string] $path ) - Get-ContainerPowerShellVersion -TestContext $testContext -Name $Name -RepoName (Get-RepoName) | should be '6.0.0-beta' + Get-ContainerPowerShellVersion -TestContext $testContext -Name $Name -RepoName (Get-RepoName) | should be '6.0.2' } } @@ -82,23 +84,22 @@ Describe "Windows Containers run PowerShell" -Tags 'Behavior', 'Windows' { BeforeAll{ $testContext = Get-TestContext -type Windows } - BeforeEach - { + BeforeEach { Remove-Item $testContext.resolvedXmlPath -ErrorAction SilentlyContinue Remove-Item $testContext.resolvedLogPath -ErrorAction SilentlyContinue } - + it "Get PSVersion table from $(Get-RepoName):" -TestCases $script:windowsContainerTests -skip:$script:skipWindows { param( [Parameter(Mandatory=$true)] [string] $name, - + [Parameter(Mandatory=$true)] [string] $path ) - Get-ContainerPowerShellVersion -TestContext $testContext -Name $Name -RepoName (Get-RepoName) | should be '6.0.0-beta' + Get-ContainerPowerShellVersion -TestContext $testContext -Name $Name -RepoName (Get-RepoName) | should be '6.0.2' } } diff --git a/docker/tests/containerTestCommon.psm1 b/docker/tests/containerTestCommon.psm1 index 5a548c16d19..bad8c4bfe4a 100644 --- a/docker/tests/containerTestCommon.psm1 +++ b/docker/tests/containerTestCommon.psm1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + $script:forcePull = $true # Get docker Engine OS function Get-DockerEngineOs @@ -5,7 +8,7 @@ function Get-DockerEngineOs docker info --format '{{ .OperatingSystem }}' } -# Call Docker with appropriate result checksfunction Invoke-Docker +# Call Docker with appropriate result checksfunction Invoke-Docker function Invoke-Docker { param( @@ -33,7 +36,7 @@ function Invoke-Docker { $result = docker $command $params 2>&1 } - else + else { &'docker' $command $params 2>&1 | Tee-Object -Variable result -ErrorAction SilentlyContinue | Out-String -Stream -ErrorAction SilentlyContinue | Write-Host -ErrorAction SilentlyContinue } @@ -58,21 +61,21 @@ function Invoke-Docker { return $false } - + return $true } # Return a list of Linux Container Test Cases function Get-LinuxContainer { - foreach($os in 'amazonlinux','centos7','opensuse42.2','ubuntu14.04','ubuntu16.04') + foreach($os in 'centos7','ubuntu14.04','ubuntu16.04') { Write-Output @{ Name = $os Path = "$psscriptroot/../release/$os" } } - + } # Return a list of Windows Container Test Cases @@ -87,7 +90,6 @@ function Get-WindowsContainer } } - $script:repoName = 'microsoft/powershell' function Get-RepoName { @@ -110,14 +112,34 @@ function Test-SkipWindows function Test-SkipLinux { - return !((Get-DockerEngineOs) -like 'Alpine Linux*') + $os = Get-DockerEngineOs + + switch -wildcard ($os) + { + '*Linux*' { + return $false + } + '*Mac' { + return $false + } + # Docker for Windows means we are running the linux kernel + 'Docker for Windows' { + return $false + } + 'Windows*' { + return $true + } + default { + throw "Unknow docker os '$os'" + } + } } function Get-TestContext { param( [ValidateSet('Linux','Windows','macOS')] - [string]$Type + [string]$Type ) $resultFileName = 'results.xml' @@ -151,7 +173,7 @@ function Get-ContainerPowerShellVersion [string] $RepoName, [string] $Name ) - + $imageTag = "${script:repoName}:${Name}" if($TestContext.ForcePull) @@ -178,7 +200,7 @@ function Get-ContainerPowerShellVersion } $runParams += $imageTag - $runParams += 'powershell' + $runParams += 'pwsh' $runParams += '-c' $runParams += ('$PSVersionTable.PSVersion.ToString() | out-string | out-file -encoding ascii -FilePath '+$testContext.containerLogPath) @@ -190,3 +212,74 @@ function Get-ContainerPowerShellVersion } return (Get-Content -Encoding Ascii $testContext.resolvedLogPath)[0] } + +# This function is used for basic validation of PS packages during a release; +# During the process Docker files are filled out and executed with Docker build; +# During the build PS packages are downloaded onto Docker containers, installed and selected Pester tests from PowerShell Github repo are executed. +# This function must be run on a Docker host machine in 'Linux containers' mode, such as Windows 10 server with Hyper-V role installed. +function Test-PSPackage +{ + param( + [string] + [Parameter(Mandatory=$true)] + $PSPackageLocation, # e.g. Azure storage + [string] + $PSVersion = "6.0.2", + [string] + $TestList = "/PowerShell/test/powershell/Modules/PackageManagement/PackageManagement.Tests.ps1,/PowerShell/test/powershell/engine/Module", + [string] + $GitLocation = "https://github.com/PowerShell/PowerShell.git" + ) + + $PSPackageLocation = $PSPackageLocation.TrimEnd('/','\') + Write-Verbose "Ensure that PowerShell packages of version $PSVersion exist at $PSPackageLocation" -Verbose + + $tempFolder = $env:Temp + if (-not $tempFolder) {$tempFolder = "~"} + $RootFolder = Join-Path $tempFolder 'PSPackageDockerValidation' + $SourceFolder = Join-Path $PSScriptRoot 'Templates' + + if (Test-Path $RootFolder) + { + Remove-Item $RootFolder -Recurse -Force + } + + Copy-Item -Recurse $SourceFolder $RootFolder + + $versionRpmStubName = 'PSVERSIONSTUBRPM' + $versionRpmStubValue = $PSVersion -replace '-','_' + $versionStubName = 'PSVERSIONSTUB' + $versionStubValue = $PSVersion + $testlistStubName = 'TESTLISTSTUB' + $testlistStubValue = $TestList + $packageLocationStubName = 'PACKAGELOCATIONSTUB' + $packageLocationStubValue = $PSPackageLocation + $GitLocationStubName = 'GITLOCATION' + $GitLocationStubValue = $GitLocation + + $results = @{} + $returnValue = $true + + # run builds sequentially, but don't block for errors so that configs after failed one can run + foreach($dir in Get-ChildItem -Path $RootFolder) + { + $buildArgs = @() + $buildArgs += "--build-arg","$versionRpmStubName=$versionRpmStubValue" + $buildArgs += "--build-arg","$versionStubName=$versionStubValue" + $buildArgs += "--build-arg","$testlistStubName=$testlistStubValue" + $buildArgs += "--build-arg","$packageLocationStubName=$packageLocationStubValue" + $buildArgs += "--build-arg","$GitLocationStubName=$GitLocationStubValue" + $buildArgs += "--no-cache" + $buildArgs += $dir.FullName + + $dockerResult = Invoke-Docker -Command 'build' -Params $buildArgs -FailureAction warning + $results.Add($dir.Name, $dockerResult) + if (-not $dockerResult) {$returnValue = $false} + } + + # in the end print results for all configurations + Write-Verbose "Package validation results:" -Verbose + $results + + return $returnValue +} diff --git a/docs/BREAKINGCHANGES.md b/docs/BREAKINGCHANGES.md new file mode 100644 index 00000000000..fe3d87b19bf --- /dev/null +++ b/docs/BREAKINGCHANGES.md @@ -0,0 +1,313 @@ +# Breaking Changes for PowerShell 6.0 + +## Features no longer available in PowerShell Core + +### PowerShell Workflow + +[PowerShell Workflow][workflow] is a feature in Windows PowerShell that builds on top of [Windows Workflow Foundation (WF)][workflow-foundation] that enables the creation of robust runbooks for long-running or parallelized tasks. + +Due to the lack of support for Windows Workflow Foundation in .NET Core, +we will not continue to support PowerShell Workflow in PowerShell Core. + +In the future, we would like to enable native parallelism/concurrency in the PowerShell language without the need for PowerShell Workflow. + +[workflow]: https://docs.microsoft.com/powershell/scripting/core-powershell/workflows-guide +[workflow-foundation]: https://docs.microsoft.com/dotnet/framework/windows-workflow-foundation/ + +### Custom snap-ins + +[PowerShell snap-ins][snapin] are a predecessor to PowerShell modules that do not have widespread adoption in the PowerShell community. + +Due to the complexity of supporting snap-ins and their lack of usage in the community, +we no longer support custom snap-ins in PowerShell Core. + +Today, this breaks the `ActiveDirectory` and `DnsClient` modules in Windows and Windows Server. + +[snapin]: https://docs.microsoft.com/powershell/module/microsoft.powershell.core/about/about_pssnapins + +### WMI v1 cmdlets + +Due to the complexity of supporting two sets of WMI-based modules, +we removed the WMI v1 cmdlets from PowerShell Core: + +* `Get-WmiObject` +* `Invoke-WmiMethod` +* `Register-WmiEvent` +* `Set-WmiInstance` + +Instead, we recommend that you the use the CIM (aka WMI v2) cmdlets which provide the same functionality with new functionality and a redesigned syntax: + +* `Get-CimAssociatedInstance` +* `Get-CimClass` +* `Get-CimInstance` +* `Get-CimSession` +* `Invoke-CimMethod` +* `New-CimInstance` +* `New-CimSession` +* `New-CimSessionOption` +* `Register-CimIndicationEvent` +* `Remove-CimInstance` +* `Remove-CimSession` +* `Set-CimInstance` + +### Microsoft.PowerShell.LocalAccounts + +Due to the use of unsupported APIs, +`Microsoft.PowerShell.LocalAccounts` has been removed from PowerShell Core until a better solution is found. + +### `*-Counter` cmdlets + +Due to the use of unsupported APIs, +the `*-Counter` has been removed from PowerShell Core until a better solution is found. + +## Engine/language changes + +### Rename `powershell.exe` to `pwsh.exe` [#5101](https://github.com/PowerShell/PowerShell/issues/5101) + +In order to give users a deterministic way to call PowerShell Core on Windows (as opposed to Windows PowerShell), +the PowerShell Core binary was changed to `pwsh.exe` on Windows and `pwsh` on non-Windows platforms. + +The shortened name is also consistent with naming of shells on non-Windows platforms. + +### Don't insert line breaks to output (except for tables) [#5193](https://github.com/PowerShell/PowerShell/issues/5193) + +Previously, output was aligned to the width of the console and line breaks were added at the end width of the console, +meaning the output didn't get reformatted as expected if the terminal was resized. +This change was not applied to tables, as the line breaks are necessary to keep the columns aligned. + +### Skip null-element check for collections with a value-type element type [#5432](https://github.com/PowerShell/PowerShell/issues/5432) + +For the `Mandatory` parameter and `ValidateNotNull` and `ValidateNotNullOrEmpty` attributes, skip the null-element check if the collection's element type is value type. + +### Change `$OutputEncoding` to use `UTF-8 NoBOM` encoding rather than ASCII [#5369](https://github.com/PowerShell/PowerShell/issues/5369) + +The previous encoding, ASCII (7-bit), would result in incorrect alteration of the output in some cases. This change is to make `UTF-8 NoBOM` default, which preserves Unicode output with an encoding supported by most tools and operating systems. + +### Remove `AllScope` from most default aliases [#5268](https://github.com/PowerShell/PowerShell/issues/5268) + +To speed up scope creation, `AllScope` was removed from most default aliases. +`AllScope` was left for a few frequently used aliases where the lookup was faster. + +### `-Verbose` and `-Debug` no longer overrides `$ErrorActionPreference` [#5113](https://github.com/PowerShell/PowerShell/issues/5113) + +Previously, if `-Verbose` or `-Debug` were specified, it overrode the behavior of `$ErrorActionPreference`. +With this change, `-Verbose` and `-Debug` no longer affect the behavior of `$ErrorActionPreference`. + +## Cmdlet changes + +### Invoke-RestMethod doesn't return useful info when no data is returned. [#5320](https://github.com/PowerShell/PowerShell/issues/5320) + +When an API returns just `null`, Invoke-RestMethod was serializing this as the string `"null"` instead of `$null`. This change fixes the logic in `Invoke-RestMethod` to properly serialize a valid single value JSON `null` literal as `$null`. + +### Remove `-ComputerName` from `*-Computer` cmdlets [#5277](https://github.com/PowerShell/PowerShell/issues/5277) + +Due to issues with RPC remoting in CoreFX (particularly on non-Windows platforms) and ensuring a consistent remoting experience in PowerShell, +the `-ComputerName` parameter was removed from the `\*-Computer` cmdlets. +Use `Invoke-Command` instead as the way to execute cmdlets remotely. + +### Remove `-ComputerName` from `*-Service` cmdlets [#5090](https://github.com/PowerShell/PowerShell/issues/5094) + +In order to encourage the consistent use of PSRP, the `-ComputerName` parameter was removed from `*-Service` cmdlets. + +### Fix `Get-Item -LiteralPath a*b` if `a*b` doesn't actually exist to return error [#5197](https://github.com/PowerShell/PowerShell/issues/5197) + +Previously, `-LiteralPath` given a wildcard would treat it the same as `-Path` and if the wildcard found no files, it would silently exit. +Correct behavior should be that `-LiteralPath` is literal so if the file doesn't exist, it should error. +Change is to treat wildcards used with `-Literal` as literal. + +### `Import-Csv` should apply `PSTypeNames` upon import when type information is present in the CSV [#5134](https://github.com/PowerShell/PowerShell/issues/5134) + +Previously, objects exported using `Export-CSV` with `TypeInformation` imported with `ConvertFrom-Csv` were not retaining the type information. +This change adds the type information to `PSTypeNames` member if available from the CSV file. + +### `-NoTypeInformation` should be default on `Export-Csv` [#5131](https://github.com/PowerShell/PowerShell/issues/5131) + +This change was made to address customer feedback on the default behavior of `Export-CSV` to include type information. + +Previously, the cmdlet would output a comment as the first line containing the type name of the object. +The change is to suppress this by default as it's not understood by most tools. +Use `-IncludeTypeInformation` to retain the previous behavior. + +### Web Cmdlets should warn when `-Credential` is sent over unencrypted connections [#5112](https://github.com/PowerShell/PowerShell/issues/5112) + +When using HTTP, content including passwords are sent as clear-text. +This change is to not allow this by default and return an error if credentials are being passed in an insecure manner. +Users can bypass this by using the `-AllowUnencryptedAuthentication` switch. + +## API changes + +### Remove `AddTypeCommandBase` class [#5407](https://github.com/PowerShell/PowerShell/issues/5407) + +The `AddTypeCommandBase` class was removed from `Add-Type` to improve performance. +This class is only used by the Add-Type cmdlet and should not impact users. + +### Unify cmdlets with parameter `-Encoding` to be of type `System.Text.Encoding` [#5080](https://github.com/PowerShell/PowerShell/issues/5080) + +The `-Encoding` value `Byte` has been removed from the filesystem provider cmdlets. +A new parameter, `-AsByteStream`, is now used to specify that a byte stream is required as input or that the output is a stream of bytes. + +### Add better error message for empty and null `-UFormat` parameter [#5055](https://github.com/PowerShell/PowerShell/issues/5055) + +Previously, when passing an empty format string to `-UFormat`, an unhelpful error message would appear. A more descriptive error has been added. + +### Clean up console code [#4995](https://github.com/PowerShell/PowerShell/issues/4995) + +The following features were removed as they are not supported in PowerShell Core, +and there are no plans to add support as they exist for legacy reasons for Windows PowerShell: +`-psconsolefile` switch and code, `-importsystemmodules` switch and code, and font changing code. + +### Removed `RunspaceConfiguration` support [#4942](https://github.com/PowerShell/PowerShell/issues/4942) + +Previously, when creating a PowerShell runspace programmatically using the API you could use the legacy [`RunspaceConfiguration`][runspaceconfig] +or the newer [`InitialSessionState`][iss]. +This change removed support for `RunspaceConfiguration` and only supports `InitialSessionState`. + +[runspaceconfig]: https://docs.microsoft.com/dotnet/api/system.management.automation.runspaces.runspaceconfiguration +[iss]: https://docs.microsoft.com/dotnet/api/system.management.automation.runspaces.initialsessionstate + +### `CommandInvocationIntrinsics.InvokeScript` bind arguments to `$input` instead of `$args` [#4923](https://github.com/PowerShell/PowerShell/issues/4923) + +An incorrect position of a parameter resulted in the args passed as input instead of as args. + +### Remove unsupported `-showwindow` switch from `Get-Help` [#4903](https://github.com/PowerShell/PowerShell/issues/4903) + +`-showwindow` relies on WPF, which is not supported on CoreCLR. + +### Allow * to be used in registry path for `Remove-Item` [#4866](https://github.com/PowerShell/PowerShell/issues/4866) + +Previously, `-LiteralPath` given a wildcard would treat it the same as `-Path` and if the wildcard found no files, it would silently exit. +Correct behavior should be that `-LiteralPath` is literal so if the file doesn't exist, it should error. +Change is to treat wildcards used with `-Literal` as literal. + +### Fix `Set-Service` failing test [#4802](https://github.com/PowerShell/PowerShell/issues/4802) + +Previously, if `New-Service -StartupType foo` was used, `foo` was ignored and the service was created with some default startup type. +This change is to explicitly throw an error for an invalid startup type. + +### Rename `$IsOSX` to `$IsMacOS` [#4700](https://github.com/PowerShell/PowerShell/issues/4700) + +The naming in PowerShell should be consistent with our naming and conform to Apple's use of macOS instead of OSX. +However, for readability and consistently we are staying with Pascal casing. + +### Make error message consistent when invalid script is passed to -File, better error when passed ambiguous argument [#4573](https://github.com/PowerShell/PowerShell/issues/4573) + +Change the exit codes of `pwsh.exe` to align with Unix conventions + +### Removal of `LocalAccount` and cmdlets from `Diagnostics` modules. [#4302](https://github.com/PowerShell/PowerShell/issues/4302) [#4303](https://github.com/PowerShell/PowerShell/issues/4303) + +Due to unsupported APIs, the `LocalAccounts` module and the `Counter` cmdlets in the `Diagnostics` module were removed until a better solution is found. + +### Executing powershell script with bool parameter does not work [#4036](https://github.com/PowerShell/PowerShell/issues/4036) + +Previously, using powershell.exe (now `pwsh.exe`) to execute a PowerShell script using `-File` provided no way to pass $true/$false as parameter values. +Support for $true/$false as parsed values to parameters was added. +Switch values are also supported as currently documented syntax doesn't work. + +### Remove `ClrVersion` property from `$PSVersionTable` [#4027](https://github.com/PowerShell/PowerShell/issues/4027) + +The `ClrVersion` property of `$PSVersionTable` is not useful with CoreCLR, end users should not be using that value to determine compatibility. + +### Change positional parameter for `powershell.exe` from `-Command` to `-File` [#4019](https://github.com/PowerShell/PowerShell/issues/4019) + +Enable shebang use of PowerShell on non-Windows platforms. This means on Unix based systems, +you can make a script executable that would invoke PowerShell automatically rather than explicitly invoking `pwsh`. +This also means that you can now do things like `powershell foo.ps1` or `powershell fooScript` without specifying `-File`. +However, this change now requires that you explicitly specify `-c` or `-Command` when trying to do things like `powershell.exe Get-Command`. + +### Implement Unicode escape parsing [#3958](https://github.com/PowerShell/PowerShell/issues/3958) + +`` `u#### `` or `` `u{####} `` is converted to the corresponding Unicode character. +To output a literal `` `u ``, +escape the backtick: ``` ``u ```. + +### Change `New-ModuleManifest` encoding to `UTF8NoBOM` on non-Windows platforms [#3940](https://github.com/PowerShell/PowerShell/issues/3940) + +Previously, `New-ModuleManifest` creates psd1 manifests in UTF-16 with BOM, creating a problem for Linux tools. +This breaking change changes the encoding of `New-ModuleManifest` to be UTF (no BOM) in non-Windows platforms. + +### Prevent `Get-ChildItem` from recursing into symlinks (#1875). [#3780](https://github.com/PowerShell/PowerShell/issues/3780) + +This change brings `Get-ChildItem` more in line with the Unix `ls -r` and the Windows `dir /s` native commands. +Like the mentioned commands, the cmdlet displays symbolic links to directories found during recursion, +but does not recurse into them. + +### Fix `Get-Content -Delimiter` to not include the delimiter in the returned lines [#3706](https://github.com/PowerShell/PowerShell/issues/3706) + +Previously, the output while using `Get-Content -Delimiter` was inconsistent and inconvenient as it required further processing of the data to remove the delimiter. +This change removes the delimiter in returned lines. + +### Implement Format-Hex in C# [#3320](https://github.com/PowerShell/PowerShell/issues/3320) + +The `-Raw` parameter is now a "no-op" (in that it does nothing). +Going forward all of the output will be displayed with a true representation of numbers that includes all of the bytes for its type +(what the `-Raw` parameter was formally doing prior to this change). + +### PowerShell as a default shell doesn't work with script command [#3319](https://github.com/PowerShell/PowerShell/issues/3319) + +On Unix, it is a convention for shells to accept `-i` for an interactive shell and many tools expect this behavior +(`script` for example, and when setting PowerShell as the default shell) +and calls the shell with the `-i` switch. +This change is breaking in that `-i` previously could be used as short hand to match `-inputformat`, +which now needs to be `-in`. + +### Typo fix in Get-ComputerInfo property name [#3167](https://github.com/PowerShell/PowerShell/issues/3167) + +`BiosSerialNumber` was misspelled as `BiosSeralNumber` and has been changed to the correct spelling. + +### Add `Get-StringHash` and `Get-FileHash` cmdlets [#3024](https://github.com/PowerShell/PowerShell/issues/3024) + +This change is that some hash algorithms are not supported by CoreFX, therefore they are no longer available: + +* `MACTripleDES` +* `RIPEMD160` + +### Add validation on `Get-*` cmdlets where passing $null returns all objects instead of error [#2672](https://github.com/PowerShell/PowerShell/issues/2672) + +Passing `$null` to any of the following now throws an error: + +* `Get-Credential -UserName` +* `Get-Event -SourceIdentifier` +* `Get-EventSubscriber -SourceIdentifier` +* `Get-Help -Name` +* `Get-PSBreakpoint -Script` +* `Get-PSProvider -PSProvider` +* `Get-PSSessionConfiguration -Name` +* `Get-PSSnapin -Name` +* `Get-Runspace -Name` +* `Get-RunspaceDebug -RunspaceName` +* `Get-Service -Name` +* `Get-TraceSource -Name` +* `Get-Variable -Name` +* `Get-WmiObject -Class` +* `Get-WmiObject -Property` + +### Add support W3C Extended Log File Format in `Import-Csv` [#2482](https://github.com/PowerShell/PowerShell/issues/2482) + +Previously, the `Import-Csv` cmdlet cannot be used to directly import the log files in W3C extended log format and additional action would be required. +With this change, W3C extended log format is supported. + +### Parameter binding problem with `ValueFromRemainingArguments` in PS functions [#2035](https://github.com/PowerShell/PowerShell/issues/2035) + +`ValueFromRemainingArguments` now returns the values as an array instead of a single value which itself is an array. + +### `BuildVersion` is removed from `$PSVersionTable` [#1415](https://github.com/PowerShell/PowerShell/issues/1415) + +Remove the `BuildVersion` property from `$PSVersionTable`. This property was tied to the Windows build version. +Instead, we recommend that you use `GitCommitId` to retrieve the exact build version of PowerShell Core. + +### Changes to Web Cmdlets + +The underlying .NET API of the Web Cmdlets has been changed to `System.Net.Http.HttpClient`. +This change provides many benefits. +However, this change along with a lack of interoperability with Internet Explorer have resulted in several breaking changes within `Invoke-WebRequest` and `Invoke-RestMethod`. + +* `Invoke-WebRequest` now supports basic HTML Parsing only. `Invoke-WebRequest` always returns a `BasicHtmlWebResponseObject` object. + The `ParsedHtml` and `Forms` properties have been removed. +* `BasicHtmlWebResponseObject.Headers` values are now `String[]` instead of `String`. +* `BasicHtmlWebResponseObject.BaseResponse` is now a `System.Net.Http.HttpResponseMessage` object. +* The `Response` property on Web Cmdlet exceptions is now a `System.Net.Http.HttpResponseMessage` object. +* Strict RFC header parsing is now default for the `-Headers` and `-UserAgent` parameter. This can be bypassed with `-SkipHeaderValidation`. +* `file://` and `ftp://` URI schemes are no longer supported. +* `System.Net.ServicePointManager` settings are no longer honored. +* There is currently no certificate based authentication available on macOS. +* Use of `-Credential` over an `http://` URI will result in an error. Use an `https://` URI or supply the `-AllowUnencryptedAuthentication` parameter to suppress the error. diff --git a/docs/FAQ.md b/docs/FAQ.md index e8bc134500e..34e9dc11460 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -43,17 +43,14 @@ Read [An Introduction To Error Handling in PowerShell][error] for more informati The SDK NuGet package `Microsoft.PowerShell.SDK` is provided for developers to write .NET Core C# code targeting PowerShell Core. PowerShell NuGet packages for releases starting from v6.0.0-alpha.9 will be published to the [powershell-core][] myget feed. -To use the `Microsoft.PowerShell.SDK` NuGet package, declare the `frameworks` section in your `project.json` file as follows: - -```json -"frameworks": { - "netstandard1.6": { - "imports": [ "dnxcore50", "portable-net45+win8" ], - "dependencies": { - "Microsoft.PowerShell.SDK": "6.0.0-alpha13" - } - } -} +To use the `Microsoft.PowerShell.SDK` NuGet package, declare `PackageReference` tags in your `.csproj` file as follows: + +```xml + + + + + ``` [powershell-core]: https://powershell.myget.org/gallery/powershell-core @@ -107,7 +104,7 @@ that new packages' binaries get stomped on by old packages' binaries. ## Why is my submodule empty? -If a submodule (such as `src/Modules/Pester`) is empty, that means it is +If a submodule (such as `src/libpsl-native/test/googletest`) is empty, that means it is uninitialized. If you've already cloned, you can do this with: @@ -125,14 +122,12 @@ git submodule status If they're initialized, it will look like this: ```output -f23641488f8d7bf8630ca3496e61562aa3a64009 src/Modules/Pester (f23641488) c99458533a9b4c743ed51537e25989ea55944908 src/libpsl-native/test/googletest (release-1.7.0) ``` If they're not, there will be minuses in front (and the folders will be empty): ```output --f23641488f8d7bf8630ca3496e61562aa3a64009 src/Modules/Pester (f23641488) -c99458533a9b4c743ed51537e25989ea55944908 src/libpsl-native/test/googletest (release-1.7.0) ``` diff --git a/docs/KNOWNISSUES.md b/docs/KNOWNISSUES.md index a6fd57bd9a1..004756ae3ba 100644 --- a/docs/KNOWNISSUES.md +++ b/docs/KNOWNISSUES.md @@ -84,7 +84,7 @@ We are working to support UTF-8 without a BOM and potentially changing the encod There is no job-control support in PowerShell on Linux/macOS. The `fg` and `bg` commands are not available. -For the time being, you can use [PowerShell jobs](https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/about/about_jobs) which do work across all platforms. +For the time being, you can use [PowerShell jobs](https://msdn.microsoft.com/powershell/reference/5.1/microsoft.powershell.core/about/about_jobs) which do work across all platforms. ### Remoting Support @@ -94,7 +94,7 @@ Currently, PowerShell Core supports PowerShell Remoting (PSRP) over WSMan with B The work for WSMan-based remoting is being done in the [psl-omi-provider](https://github.com/PowerShell/psl-omi-provider) repo. PowerShell Core also supports PowerShell Remoting (PSRP) over SSH on all platforms (Windows, macOS, and Linux). -While this is not currently supported in production, you can learn more about setting this up [here](https://github.com/PowerShell/PowerShell/tree/master/demos/SSHRemoting). +While this is not currently supported in production, you can learn more about setting this up [here](https://docs.microsoft.com/powershell/scripting/core-powershell/ssh-remoting-in-powershell-core). ### Just-Enough-Administration (JEA) Support diff --git a/docs/building/internals.md b/docs/building/internals.md index c05e267cffe..13cb3875451 100644 --- a/docs/building/internals.md +++ b/docs/building/internals.md @@ -16,7 +16,7 @@ We are calling `dotnet` tool build for `$Top` directory ### Dummy dependencies We use dummy dependencies between projects to leverage `dotnet` build functionality. -For example, `src\powershell-win-core\powershell-win-core.csproj` has dependency on `Microsoft.PowerShell.PSReadLine`, +For example, `src\powershell-win-core\powershell-win-core.csproj` has dependency on `Microsoft.PowerShell.Commands.Diagnostics.csproj`, but in reality, there is no build dependency. Dummy dependencies allows us to build just `$Top` folder, instead of building several folders. @@ -44,11 +44,10 @@ dotnet run Running the program does everything else: -- for each project, given a `resources` folder - - creates a `gen` folder - - for each `*.resx` file - - fills in a strongly typed C# class - - writes it out to the corresponding `*.cs` file +- For each project, given a `resources` folder, create a `gen` folder. +- For each `*.resx` file from the `resources` folder, + fill in a strongly typed C# class, + and write it out to the corresponding `*.cs` file in the `gen` folder. These files are *not* automatically updated on each build, as the project lacks the ability to detect changes. @@ -87,7 +86,7 @@ cat > $targetFile <<-"EOF" EOF -dotnet msbuild Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj /t:_GetDependencies "/property:DesignTimeBuild=true;_DependencyFile=$(pwd)/src/TypeCatalogGen/powershell.inc" /nologo +dotnet msbuild Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj /t:_GetDependencies "/property:DesignTimeBuild=true;_DependencyFile=$(pwd)/TypeCatalogGen/powershell.inc" /nologo ``` `powershell.inc` contains the resolved paths to the DLLs of each dependency of PowerShell, @@ -97,3 +96,137 @@ which generates a source file `CorePsTypeCatalog.cs` for the `Microsoft.PowerShe The error `The name 'InitializeTypeCatalog' does not exist in the current context` indicates that the `CorePsTypeCatalog.cs` source file does not exist, so follow the steps to generate it. + +## Native Components + +On Windows, PowerShell Core depends on the WinRM plugin `pwrshplugin.dll` to enable remoting over WinRM. +On Linux/macOS, PowerShell Core depends on the binary `libpsl-native.so/libpsl-native.dylib` to provide some necessary supports. + +Building those native components requires setting up additional dependencies, +which could be a burden to those who don't seek to make changes to the native components. +At the meantime, the native component code seldom changes, +so it doesn't make sense to always build them with `Start-PSBuild`. +Therefore, we decided to wrap the native components into NuGet packages, +so that we only need to build them once when changes are made, +and then reuse the produced binaries for many builds subsequently. + +The NuGet package for `pwrshplugin.dll` is `psrp.windows`, +and the NuGet package for `libpsl-native` is `libpsl`. + +### Windows packages: PSRP.Windows and PowerShell.Core.Instrumentation + +To build `pwrshplugin.dll` and `PowerShell.Core.Instrumentation.dll`, you need to install Visual Studio 2017 and run `Start-PSBootstrap -BuildWindowsNative` to install the prerequisites. + +Ensure the following individual components are selected: + +- [ ] VC++ 2017 v141 toolset (x86, x64) +- [ ] Visual C++ compilers and libraries for ARM +- [ ] Visual C++ compilers and libraries for ARM64 +- [ ] Visual C++ tools for CMake +- [ ] Visual C++ ATL Support +- [ ] Windows 10 SDK (10.0.16299.0) for Desktop C++ (ARM and ARM64) +- [ ] Windows 10 SDK (10.0.16299.0) for Desktop C++ (x86 and x64) + +Ensure [CMake](https://cmake.org/download/) 3.10.0 or newer is installed which supports VS2017 and ARM64 generator. + +Then run `Start-BuildNativeWindowsBinaries` to build the binary. +For example, the following builds the release flavor of the binary targeting arm64 architecture. + +```powershell +Start-BuildNativeWindowsBinaries -Configuration Release -Arch x64_arm64 +``` + +Be sure to build and test for all supported architectures: `x86`, `x64`, `x64_arm`, and `x64_arm64`. + +The `x64_arm` and `x64_arm64` architectures mean that the host system needs to be x64 to cross-compile to ARM. +When building for multiple architectures, be sure to use the `-clean` switch as cmake will cache the previous run and the wrong compiler will be used to generate the subsequent architectures. + +After that, the binary `pwrshplugin.dll`, its PDB file, and `powershell.core.instrumentation.dll` will be placed under 'src\powershell-win-core'. + +To create a new NuGet package for `pwrshplugin.dll`, first you need to get the `psrp.windows.nuspec` from an existing `psrp.windows` package. +You can find it at `~/.nuget/packages/psrp.windows` on your windows machine if you have recently built PowerShell on it. +Or you can download the existing package from [powershell-core feed](https://powershell.myget.org/feed/powershell-core/package/nuget/psrp.windows). +Once you get `psrp.windows.nuspec`, copy it to an empty folder and update the `` element. + +After building successfully, copy the produced files to the same folder, +and create the same layout of files as in the existing package. +The layout of files should look like this: + +```none +\---runtimes + +---win-x64 + | \---native + | pwrshplugin.dll + | pwrshplugin.pdb + | + +---win-x86 + | \---native + | pwrshplugin.dll + | pwrshplugin.pdb + +---win-arm + | \---native + | pwrshplugin.dll + | pwrshplugin.pdb + \---win-arm64 + \---native + pwrshplugin.dll + pwrshplugin.pdb +``` + +Have the DLLs signed with `authenticode dual` certificate and run `nuget pack` from the parent of the `runtimes` folder where `psrp.windows.nuspec` resides. +Be sure to use the latest recommended version of [nuget.exe](https://www.nuget.org/downloads). + +Publish latest nupkg to https://powershell.myget.org/feed/powershell-core/package/nuget/psrp.windows. + +`PowerShell.Core.Instrumentation.dll` NuGet package is created the same way, but in a separate directory following the same layout above. +To create a new NuGet package for `PowerShell.Core.Instrumentation.dll`, you will need the `PowerShell.Core.Instrumentation.nuspec` found in the repo under `src\PowerShell.Core.Instrumentation`. + +Publish latest nupkg to https://powershell.myget.org/feed/powershell-core/package/nuget/PowerShell.Core.Instrumentation. + +### libpsl + +For `linux-arm`, you need to run `Start-PSBootstrap -BuildLinuxArm` to install additional prerequisites to build `libpsl-native`. +Note that currently you can build `linux-arm` only on a Ubuntu machine. + +For `linux-x64` and macOS, the initial run of `Start-PSBootstrap` would be enough -- no additional prerequisite required. + +After making sure the prerequisites are met, run `Start-BuildNativeUnixBinaries` to build the binary: + +```powershell +## Build targeting linux-x64 or macOS +Start-BuildNativeUnixBinaries + +## Build targeting linux-arm +Start-BuildNativeUnixBinaries -BuildLinuxArm +``` + +After the build succeeds, the binary `libpsl-native.so` (`libpsl-native.dylib` on macOS) will be placed under `src/powershell-unix`. + +To create a new NuGet package for `libpsl-native`, first you need to get the `libpsl.nuspec` from an existing `libpsl` package. +You can find it at `~/.nuget/packages/libpsl` on your Linux or macOS machine if you have recently built PowerShell on it. +Or you can download the existing package from [powershell-core feed](https://powershell.myget.org/feed/powershell-core/package/nuget/libpsl). +Once you get `psrp.windows.nuspec`, copy it to an empty folder on your Windows machine. + +Then you need to build three binaries of `libpsl-native` targeting `linux-x64`, `linux-arm` and `osx` respectively. +**Please note that, in order for the `linux-x64` binary `libpsl-native.so` to be portable to all other Linux distributions, +the `linux-x64` binary needs to be built on CentOS 7** +(.NET Core Linux native binaries are also built on CentOS 7 to ensure that they don't depend on newer `glibc`). + +After building successfully, copy those three binaries to the same folder, +and create the same layout of files as in the existing package. +The layout of files should look like this: + +```none +└── runtimes + ├── linux-arm + │   └── native + │   └── libpsl-native.so + ├── linux-x64 + │   └── native + │   └── libpsl-native.so + └── osx + └── native + └── libpsl-native.dylib +``` + +Lastly, run `nuget pack .` from within the folder. Note that you may need the latest `nuget.exe`. diff --git a/docs/building/linux.md b/docs/building/linux.md index ef449d7e4b2..55870983860 100644 --- a/docs/building/linux.md +++ b/docs/building/linux.md @@ -1,17 +1,14 @@ -Build PowerShell on Linux -========================= +# Build PowerShell on Linux This guide will walk you through building PowerShell on Linux. We'll start by showing how to set up your environment from scratch. -Environment -=========== +## Environment These instructions are written assuming the Ubuntu 14.04 LTS, since that's the distro the team uses. The build module works on a best-effort basis for other distributions. -Git Setup ---------- +### Git Setup Using Git requires it to be set up correctly; refer to the [Working with the PowerShell Repository](../git/README.md), @@ -19,37 +16,26 @@ refer to the [Working with the PowerShell Repository](../git/README.md), **This guide assumes that you have recursively cloned the PowerShell repository and `cd`ed into it.** -Toolchain Setup ---------------- +### Toolchain Setup We use the [.NET Command-Line Interface][dotnet-cli] (`dotnet`) to build the managed components, and [CMake][] to build the native components. -Install the following packages for the toolchain: - -- `dotnet`: Must be installed from the `Start-PSBootstrap` module as described below. -- `cmake` -- `make` -- `g++` - -Unfortunately, the `apt-get` feed for `dotnet` has been deprecated, -and the latest version is only distributed in the form of three separate packages, -which require manual dependency resolution. Installing the toolchain is as easy as running `Start-PSBootstrap` in PowerShell. Of course, this requires a self-hosted copy of PowerShell on Linux. Fortunately, this is as easy as [downloading and installing the package](../installation/linux.md). -The `./tools/download.sh` script will also install the PowerShell package. +The `./tools/install-powershell.sh` script will also install the PowerShell package. In Bash: ```sh -./tools/download.sh +./tools/install-powershell.sh -powershell +pwsh ``` -You should now be in a `powershell` console host that is installed separately from any development copy you're about to build. +You should now be in a PowerShell console host that is installed. Just import our module, bootstrap the dependencies, and build! In PowerShell: @@ -64,94 +50,28 @@ The `Start-PSBootstrap` function does the following: - Adds the LLVM package feed - Installs our dependencies combined with the dependencies of the .NET CLI toolchain via `apt-get` - Uninstalls any prior versions of .NET CLI -- Downloads and installs the latest .NET Core SDK 1.0.1 to `~/.dotnet` +- Downloads and installs the .NET Core SDK 2.0.0 to `~/.dotnet` If you want to use `dotnet` outside of `Start-PSBuild`, add `~/.dotnet` to your `PATH` environment variable. [dotnet-cli]: https://github.com/dotnet/cli [CMake]: https://cmake.org/cmake/help/v2.8.12/cmake.html -.NET CLI --------- - -If you have any problems installing `dotnet`, please see their [documentation][cli-docs]. - -The version of .NET CLI is very important; the version we are currently using is `1.0.1`. - -Previous installations of DNX, `dnvm`, or older installations of .NET CLI can cause odd failures when running. -Please check your version and uninstall prior any prior versions. - -[cli-docs]: https://www.microsoft.com/net/core - -Build using our module -====================== +## Build using our module We maintain a [PowerShell module](../../build.psm1) with the function `Start-PSBuild` to build PowerShell. Since this is PowerShell code, it requires self-hosting. -If you have followed the toolchain setup section above, you should have `powershell` installed. - -> If you cannot or do not want to self-host, `Start-PSBuild` is just a -> convenience; you can execute each step of the build process yourself -> in Bash; see [Build manually](#build-manually) below. +If you have followed the toolchain setup section above, you should have PowerShell Core installed. ```powershell Import-Module ./build.psm1 Start-PSBuild ``` + Congratulations! If everything went right, PowerShell is now built. The `Start-PSBuild` script will output the location of the executable: -`./src/powershell-unix/bin/Linux/netcoreapp1.1/ubuntu.14.04-x64/powershell`. +`./src/powershell-unix/bin/Linux/netcoreapp2.0/linux-x64/publish/pwsh`. -You should now be running the `powershell` that you just built, if your run the above executable. +You should now be running the PowerShell Core that you just built, if your run the above executable. You can run our cross-platform Pester tests with `Start-PSPester`, and our xUnit tests with `Start-PSxUnit`. - -Build manually -============== - -The following goes into detail about what `Start-PSBuild` does. - -There are two preliminary steps that apply to all operating systems, -the [ResGen](internals.md#resgen) and [type catalog generation](internals.md#type-catalog), -documented in [internals of build process](internals.md#preliminary-steps). - -Build the native library ------------------------- - -The `libpsl-native.so` library consists of native functions that `CorePsPlatform.cs` P/Invokes. - -```sh -pushd src/libpsl-native -cmake -DCMAKE_BUILD_TYPE=Debug . -make -j -make test -popd -``` - -This library will be emitted in the `src/powershell-unix` project, -where `dotnet` consumes it as "content" and thus automatically deploys it. - -Build the managed projects --------------------------- - -The `powershell` project is the .NET Core PowerShell host. -It is the top level project, so `dotnet build` transitively builds all its dependencies, and emits a `powershell` executable. -The `--configuration Linux` flag is necessary to ensure that the preprocessor definition `LINUX` is defined (see [issue #673][]). - -```sh -dotnet restore -cd src/powershell-unix -dotnet build --configuration Linux -``` - -The executable will be in `./bin/[configuration]/[framework]/[rid]/publish/[binary name]`, -where our configuration is `Linux`, framework is `netcoreapp2.0`, -runtime identifier is `linux-x64`, and binary name is `powershell`. -The function `Get-PSOutput` will return the path to the executable; -thus you can execute the development copy via `& (Get-PSOutput)`. - -For deploying PowerShell, `dotnet publish` will emit a `publish` directory that contains a flat list of every dependency required for -PowerShell. -This can be copied to, for example, `/usr/local/share/powershell` or packaged. - -[issue #673]: https://github.com/PowerShell/PowerShell/issues/673 diff --git a/docs/building/macos.md b/docs/building/macos.md index 980c622548e..235f9ebfaa6 100644 --- a/docs/building/macos.md +++ b/docs/building/macos.md @@ -3,14 +3,14 @@ This guide supplements the [Linux instructions](./linux.md), as building on macOS is almost identical. -.NET Core 2.0 (and by transitivity, us) only supports macOS 10.12. +.NET Core 2.0 (and by transitivity, us) only supports macOS 10.12+. ## Environment You will want [Homebrew](http://brew.sh/), the missing package manager for macOS. Once installed, follow the same instructions to download and -install a self-hosted copy of PowerShell on your macOS machine, -and use`Start-PSBootstrap` to install the dependencies. +install a self-hosted copy of PowerShell on your macOS machine. +From `pwsh.exe`, run `Import-Module ./build.psm1` and use `Start-PSBootstrap` to install the dependencies. The `Start-PSBootstrap` function does the following: @@ -34,9 +34,7 @@ We cannot do this for you in the build module due to #[847][]. ## Build using our module -Instead of installing the Ubuntu package of PowerShell, -download the `pkg` from our GitHub releases page using your browser, complete the wizard, -start a `powershell` session, and use `Start-PSBuild` from the module. +Start a PowerShell session by running `pwsh`, and then use `Start-PSBuild` from the module. After building, PowerShell will be at `./src/powershell-unix/bin/Linux/netcoreapp2.0/osx.10.12-x64/publish/powershell`. -Note that configuration is still `Linux` because it would be silly to make yet another separate configuration when it's used solely to work-around a CLI issue. +Note that configuration is still `Linux`. diff --git a/docs/building/windows-core.md b/docs/building/windows-core.md index 76c8ae583b8..54d0a099b17 100644 --- a/docs/building/windows-core.md +++ b/docs/building/windows-core.md @@ -1,17 +1,14 @@ -Build PowerShell on Windows for .NET Core -========================================= +# Build PowerShell on Windows for .NET Core This guide will walk you through building PowerShell on Windows, targeting .NET Core. We'll start by showing how to set up your environment from scratch. -Environment -=========== +## Environment These instructions are tested on Windows 10 and Windows Server 2012 R2, though they should work anywhere the dependencies work. -Git Setup ---------- +### Git Setup Using Git requires it to be setup correctly; refer to the [README](../../README.md) and @@ -19,17 +16,20 @@ Using Git requires it to be setup correctly; refer to the This guide assumes that you have recursively cloned the PowerShell repository and `cd`ed into it. -Visual Studio ----------------- +### Visual Studio You will need to install an edition of Visual Studio 2015 (Community, Enterprise, or Professional) with the optional feature 'Common Tools for Visual C++' installed. The free Community edition of Visual Studio 2015 can be downloaded [here](https://www.visualstudio.com/visual-studio-community-vs/). -.NET CLI --------- +### Visual Studio Code + +Building PowerShell using [Visual Studio Code](https://code.visualstudio.com/) depends on the PowerShell executable to be called `pwsh` which means +that you must have PowerShell Core 6 Beta.9 (or newer) installed to successfully build this project (typically for the purpose of debugging). + +### .NET CLI We use the [.NET Command Line Interface][dotnet-cli] (`dotnet`) to build PowerShell. -The version we are currently using is `2.0.0-preview2-006502`. +The version we are currently using is `2.0.0`. The `Start-PSBootstrap` function will automatically install it and add it to your path: ```powershell @@ -37,26 +37,19 @@ Import-Module ./build.psm1 Start-PSBootstrap ``` -The `Start-PSBootstrap` function calls `Install-Dotnet`: - -```powershell -Install-Dotnet -Channel preview -Version 2.0.0-preview2-006502 -``` - -It removes the previously installed version of .NET CLI from `$env:LOCALAPPDATA\Microsoft\dotnet` and then does exactly this: +Or you can call `Install-Dotnet` directly: ```powershell -Invoke-WebRequest -Uri https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain/dotnet-install.ps1 -OutFile dotnet-install.ps1 -./dotnet-install.ps1 -Channel preview -Version 2.0.0-preview2-006502 +Install-Dotnet ``` +It removes the previously installed version of .NET CLI and install the version that PowerShell Core depends on. If you have any problems installing `dotnet`, please see their [documentation][cli-docs]. [dotnet-cli]: https://github.com/dotnet/cli [cli-docs]: https://www.microsoft.com/net/core#windowscmd -Build using our module -====================== +## Build using our module We maintain a [PowerShell module](../../build.psm1) with the function `Start-PSBuild` to build PowerShell. @@ -65,24 +58,22 @@ Import-Module ./build.psm1 Start-PSBuild ``` -Congratulations! If everything went right, PowerShell is now built and executable as `./src/powershell-win-core/bin/Debug/netcoreapp2.0/win10-x64/powershell`. +Congratulations! If everything went right, PowerShell is now built and executable as `./src/powershell-win-core/bin/Debug/netcoreapp2.0/win7-x64/publish/pwsh`. -This location is of the form `./[project]/bin/[configuration]/[framework]/[rid]/[binary name]`, +This location is of the form `./[project]/bin/[configuration]/[framework]/[rid]/publish/[binary name]`, and our project is `powershell`, configuration is `Debug` by default, -framework is `netcoreapp2.0`, runtime identifier is **probably** `win10-x64` -(but will depend on your operating system; -don't worry, `dotnet --info` will tell you what it was), and binary name is `powershell`. +framework is `netcoreapp2.0`, runtime identifier is `win7-x64` by default, +and binary name is `pwsh`. The function `Get-PSOutput` will return the path to the executable; thus you can execute the development copy via `& (Get-PSOutput)`. The `powershell` project is the .NET Core PowerShell host. It is the top level project, so `dotnet build` transitively builds all its dependencies, -and emits a `powershell` executable. +and emits a `pwsh` executable. The cross-platform host has built-in documentation via `--help`. You can run our cross-platform Pester tests with `Start-PSPester`. -Building in Visual Studio -------------------------- +## Building in Visual Studio We currently have the issue [#3400](https://github.com/PowerShell/PowerShell/issues/3400) tracking this task. diff --git a/docs/cmdlet-example/Images/Std21.png b/docs/cmdlet-example/Images/Std21.png new file mode 100644 index 00000000000..2c3d83858bd Binary files /dev/null and b/docs/cmdlet-example/Images/Std21.png differ diff --git a/docs/cmdlet-example/Images/Std22.png b/docs/cmdlet-example/Images/Std22.png new file mode 100644 index 00000000000..9406f4a9fff Binary files /dev/null and b/docs/cmdlet-example/Images/Std22.png differ diff --git a/docs/cmdlet-example/Images/Std3.png b/docs/cmdlet-example/Images/Std3.png new file mode 100644 index 00000000000..ec70d176d14 Binary files /dev/null and b/docs/cmdlet-example/Images/Std3.png differ diff --git a/docs/cmdlet-example/Images/Std4.png b/docs/cmdlet-example/Images/Std4.png new file mode 100644 index 00000000000..fb883d97ecf Binary files /dev/null and b/docs/cmdlet-example/Images/Std4.png differ diff --git a/docs/cmdlet-example/Images/Std5.png b/docs/cmdlet-example/Images/Std5.png new file mode 100644 index 00000000000..e70bdf8d244 Binary files /dev/null and b/docs/cmdlet-example/Images/Std5.png differ diff --git a/docs/cmdlet-example/Images/Std61.png b/docs/cmdlet-example/Images/Std61.png new file mode 100644 index 00000000000..e9211e4910b Binary files /dev/null and b/docs/cmdlet-example/Images/Std61.png differ diff --git a/docs/cmdlet-example/Images/Std62.png b/docs/cmdlet-example/Images/Std62.png new file mode 100644 index 00000000000..69996460f28 Binary files /dev/null and b/docs/cmdlet-example/Images/Std62.png differ diff --git a/docs/cmdlet-example/Images/Std63.png b/docs/cmdlet-example/Images/Std63.png new file mode 100644 index 00000000000..cce343e6191 Binary files /dev/null and b/docs/cmdlet-example/Images/Std63.png differ diff --git a/docs/cmdlet-example/Images/Step1.png b/docs/cmdlet-example/Images/Step1.png new file mode 100644 index 00000000000..aa63140a3fd Binary files /dev/null and b/docs/cmdlet-example/Images/Step1.png differ diff --git a/docs/cmdlet-example/Images/Step2.png b/docs/cmdlet-example/Images/Step2.png new file mode 100644 index 00000000000..3b84716f7c5 Binary files /dev/null and b/docs/cmdlet-example/Images/Step2.png differ diff --git a/docs/cmdlet-example/Images/Step3.png b/docs/cmdlet-example/Images/Step3.png new file mode 100644 index 00000000000..ed13cf8929d Binary files /dev/null and b/docs/cmdlet-example/Images/Step3.png differ diff --git a/docs/cmdlet-example/Images/Step4.png b/docs/cmdlet-example/Images/Step4.png new file mode 100644 index 00000000000..a9644edd655 Binary files /dev/null and b/docs/cmdlet-example/Images/Step4.png differ diff --git a/docs/cmdlet-example/Images/Step5.png b/docs/cmdlet-example/Images/Step5.png new file mode 100644 index 00000000000..0cf0384a300 Binary files /dev/null and b/docs/cmdlet-example/Images/Step5.png differ diff --git a/docs/cmdlet-example/Images/Step6.png b/docs/cmdlet-example/Images/Step6.png new file mode 100644 index 00000000000..b57deb6aad2 Binary files /dev/null and b/docs/cmdlet-example/Images/Step6.png differ diff --git a/docs/cmdlet-example/Images/Step7.png b/docs/cmdlet-example/Images/Step7.png new file mode 100644 index 00000000000..644eebce516 Binary files /dev/null and b/docs/cmdlet-example/Images/Step7.png differ diff --git a/docs/cmdlet-example/Images/Step8.png b/docs/cmdlet-example/Images/Step8.png new file mode 100644 index 00000000000..155e8c3d359 Binary files /dev/null and b/docs/cmdlet-example/Images/Step8.png differ diff --git a/docs/cmdlet-example/command-line-simple-example.md b/docs/cmdlet-example/command-line-simple-example.md new file mode 100644 index 00000000000..0a2682413bd --- /dev/null +++ b/docs/cmdlet-example/command-line-simple-example.md @@ -0,0 +1,227 @@ +# Creating a cross-platform binary module with the .NET Core command-line interface tools + +This example uses the [.NET Core command-line interface tools][dotnet-cli] (aka +`dotnet` CLI) to demonstrate how to create a binary module that is portable across operating +systems supported by **PowerShell Core** as well as **Windows PowerShell** version 3 and higher. + +Because the binary module's assembly will be created as a .NET Standard 2.0 class library, +the same assembly can be imported into both PowerShell Core and Windows PowerShell. +This means you do not have to build and distribute separate assemblies that target these two +different implementations of PowerShell. + +## Prerequisites + +* PowerShell Core and/or Windows PowerShell + + For this example, you can use any operating system that is supported by PowerShell Core. + To see if your operating system is supported and to get instructions on how to install + PowerShell Core on your operating system, see the [Get PowerShell][pscore-os] topic in + the PowerShell repo's [README.md][readme] file. + + Note: On Windows 10 Anniversary Update or higher, you can use the [Windows Subsystem for + Linux][wsl] (WSL) console to build the module. In order to import and use the module, you'll need + to install PowerShell Core for the distribution and version of Linux you're running. + You can get that version info by running the command `lsb_release -a` from the WSL console. + +* .NET Core 2.0 SDK + + Download and install the [.NET Core 2.0 SDK][net-core-sdk] for your operating system. + It is recommended that you use a package manager to install the SDK on Linux. + See these [instructions][linux-install] on how to install the SDK on Linux. + Be sure to pick your distribution of Linux e.g. RHEL, Debian, etc to get the + appropriate instructions for your platform. + +## Create the .NET Standard 2.0 Binary Module + +1. Verify you are running the 2.0.0 version of the `dotnet` CLI. + + ```powershell + dotnet --version + ``` + + This should output `2.0.0` or higher. If it returns a major version of 1, make sure you have + installed the .NET Core 2.0 SDK and have restarted your shell to get the newer version of + the SDK tools. + +1. Use the `dotnet` CLI to create a starter `classlib` project based on .NET Standard 2.0 + (the default for classlib projects). + + ```powershell + dotnet new classlib --name MyModule + ``` + +1. Add a `global.json` file that specifies that the project requires the `2.0.0` version of + the .NET Core SDK. This is necessary to prevent issues if you have more than one + version of the .NET Core SDK installed. + + ```powershell + cd MyModule + dotnet new globaljson --sdk-version 2.0.0 + ``` + +1. Add the [PowerShell Standard Library][ps-stdlib] package to the project file. + This package provides the `System.Management.Automation` assembly. + + Note: As newer versions of this library are released, update the version number + in this command to match the latest version. + + ```powershell + dotnet add package PowerShellStandard.Library --version 3.0.0-preview-01 + ``` + +1. Add source code for a simple PowerShell command to the `Class1.cs` file by opening + that file in an editor and replacing the existing code with the following code. + + ```csharp + using System; + using System.Management.Automation; + + namespace MyModule + { + [Cmdlet(VerbsCommunications.Write, "TimestampedMessage")] + public class WriteTimestampedMessageCommand : PSCmdlet + { + [Parameter(Position=1)] + public string Message { get; set; } = string.Empty; + + protected override void EndProcessing() + { + string timestamp = DateTime.Now.ToString("u"); + this.WriteObject($"[{timestamp}] - {this.Message}"); + base.EndProcessing(); + } + } + } + ``` + +1. Build the project. + + ```powershell + dotnet build + ``` + +1. Import the binary module and invoke the new command. + + Note: The previous steps could have been performed in a different shell such as + Bash if you're on Linux. For this step, make sure you are running PowerShell Core. + + ```powershell + cd 'bin/Debug/netstandard2.0' + Import-Module ./MyModule.dll + Write-TimestampedMessage "Test message." + ``` + +## Using a .NET Standard 2.0 based binary module in Windows PowerShell + +You may have heard that a .NET assembly compiled as a .NET Standard 2.0 class library +will load into both .NET Core 2.0 applications such as PowerShell Core and +.NET Framework 4.6.1 (or higher) applications such as Windows PowerShell. +This allows you to build a single, cross-platform binary module. + +Unfortunately, this works best when the .NET Framework application, in this case +Windows PowerShell, has either been compiled against a .NET Standard 2.0 library or with +support declared for .NET Standard libraries. In which case, the build system can provide the +appropriate binding redirects and facade and shim assemblies so that the .NET Standard 2.0 +library can find the .NET Framework types it needs within the context of the running +application. + +Fortunately, this has been fixed in .NET Framework 4.7.1 and in the Windows 10 Fall +Creators Update. This version of the .NET Framework allows existing applications to +"just work" without the need to modify and/or re-compile them. On these systems, a +.NET Standard 2.0 based binary module will work in Windows PowerShell. + +However, for Windows systems that have not been updated to .NET Framework 4.7.1 such a +binary module will not run correctly in Windows PowerShell. + +Let's see what happens when you attempt use this module in **Windows PowerShell** on +Windows 10 CU (1703 or lower) without .NET Framework 4.7.1 installed. + +1. Copy `MyModule.dll` to a folder on a Windows machine. + +1. Import the module. + + ```powershell + Import-Module .\MyModule.dll + ``` + + Note: The module should import without errors. + +1. Execute the `Write-TimestampedMessage` command. + + ```powershell + Write-TimestampedMessage "Test message." + ``` + + This will result in the following error: + + ```text + Write-TimestampedMessage : Could not load file or assembly 'netstandard, Version=2.0.0.0, Culture=neutral, + PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The system cannot find the file specified. + At line:1 char:1 + + Write-TimestampedMessage "Test message." + + ~~~~~~~~~~~~~~~~~~~~~~~~ + + CategoryInfo : NotSpecified: (:) [], FileNotFoundException + + FullyQualifiedErrorId : System.IO.FileNotFoundException + ``` + +If the command worked, congratulations! Your system was probably updated to +.NET Framework 4.7.1. Otherwise, this error indicates that the `MyModule.dll` assembly +can't find the `netstandard.dll` "implementation" assembly for the version of the +.NET Framework that Windows PowerShell is using. + +### The fix for missing netstandard.dll + +If you install (or already have) the .NET Core 2.0 SDK for Windows, you can +find the `netstandard.dll` implementation assembly for .NET 4.6.1 in the following directory: +`C:\Program Files\dotnet\sdk\2.0.0\Microsoft\Microsoft.NET.Build.Extensions\net461\lib`. + +If you copy `netstandard.dll` from this directory to the directory containing +`MyModule.dll`, the `Write-TimestampedMessage` command will work. Let's try that. + +1. Install the [.NET Core SDK 2.0 for Windows][net-core-sdk], if it isn't already installed. + +1. Start a new Windows PowerShell console. Remember that once a binary assembly is + loaded into PowerShell it can't be unloaded. Restarting PowerShell is necessary to + get it to reload `MyModule.dll`. + +1. Copy the `netstandard.dll` implementation assembly for .NET 4.6.1 to the module's directory. + ```powershell + cd 'path-to-where-you-copied-module.dll' + Copy-Item 'C:\Program Files\dotnet\sdk\2.0.0\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\netstandard.dll' . + ``` + +1. Import the module and execute the command: + ```powershell + Import-Module .\MyModule.dll + Write-TimestampedMessage "Test message." + ``` + Now the command should succeed. + + Note: If it fails, restart Windows PowerShell to make sure + you don't have a previously loaded version of the assembly in the session and repeat + step 4. + +If you use additional libraries there may be more work involved. This approach has +been successfully tested using types from `System.Xml` and `System.Web`. + +## Wrap-up + +In a few steps, we have built a PowerShell binary module using a .NET Standard 2.0 +class library that will run in PowerShell Core on multiple operating systems. +It will also run in Windows PowerShell on Windows systems that have been updated to +.NET Framework 4.7.1 as well as the Windows 10 Fall Creators Update which comes with that +version pre-installed. Furthermore, this binary module can be built on Linux +and macOS as well as Windows using the .NET Core 2.0 SDK command-line tools. + +For more information on .NET Standard, check out the [documentation][net-std-docs] +and the [.NET Standard YouTube channel][net-std-chan]. + +[dotnet-cli]: https://docs.microsoft.com/en-us/dotnet/core/tools/?tabs=netcore2x +[net-core-sdk]: https://www.microsoft.com/net/download/core +[net-std-docs]: https://docs.microsoft.com/en-us/dotnet/standard/net-standard +[net-std-chan]: https://www.youtube.com/playlist?list=PLRAdsfhKI4OWx321A_pr-7HhRNk7wOLLY +[pscore-os]: https://github.com/powershell/powershell#get-powershell +[readme]: ../../README.md +[linux-install]: https://www.microsoft.com/net/core#linuxubuntu +[ps-stdlib]: https://www.nuget.org/packages/PowerShellStandard.Library/ +[wsl]: https://msdn.microsoft.com/commandline/wsl/about diff --git a/docs/cmdlet-example/visual-studio-simple-example.md b/docs/cmdlet-example/visual-studio-simple-example.md new file mode 100644 index 00000000000..6f91d064a3e --- /dev/null +++ b/docs/cmdlet-example/visual-studio-simple-example.md @@ -0,0 +1,131 @@ +# Building a C# Cmdlet with Visual Studio + +This document describes steps for building a C# Cmdlet with Visual Studio in 2 ways: + +* [Building a C# Cmdlet for PowerShell Core](#building-a-c-cmdlet-for-powershell-core-with-visual-studio) +* [Building a C# Cmdlet for PowerShell Standard 3.0](#building-a-c-cmdlet-for-powershell-standard-30-with-visual-studio) + +## Building a C# Cmdlet for PowerShell Core with Visual Studio + +This demonstrates how to build your own C# cmdlet for PowerShell Core with Visual Studio. +Targeting for PowerShell Core means that the cmdlet may not work against Windows PowerShell if you take dependencies on new APIs introduced in PowerShell Core. + +We will use the free [Visual Studio Community 2017](https://www.visualstudio.com/downloads). + +1. When installing Visual Studio 2017 select `.NET Core cross-platform development` under `Other Toolsets` + ![Step1](./Images/Step1.png) + +1. Create new C# project `SendGreeting` of type `Class Library (.NET Core)` + ![Step2](./Images/Step2.png) + +1. Now we need to setup PowerShell Core reference assemblies. + In `Solution Explorer` right click on project `Dependencies` and select `Manage NuGet Packages...` +In the top-right corner of the package manager click on the small `Settings` sprocket icon that is to the right from `Package source` dropdown. +By default, there will be only `nuget.org` package source in `Available package sources` list. +Add another package source with name `powershell-core` and source `https://powershell.myget.org/F/powershell-core/api/v3/index.json` +![Step3](./Images/Step3.png) + +1. In the package manager select new `powershell-core` in `Package source` dropdown, select `Browse` tab, type in `System.Management.Automation` in the search and select `Include prerelease`. + It should find `System.Management.Automation` package, select it and it will show package details; install it using `Install` button. +![Step4](./Images/Step4.png) + +1. Add the code of cmdlet: + ```CSharp + using System.Management.Automation; // PowerShell namespace. + + namespace SendGreeting + { + // Declare the class as a cmdlet and specify and + // appropriate verb and noun for the cmdlet name. + [Cmdlet(VerbsCommunications.Send, "Greeting")] + public class SendGreetingCommand : Cmdlet + { + // Declare the parameters for the cmdlet. + [Parameter(Mandatory = true)] + public string Name { get; set; } + + // Overide the ProcessRecord method to process + // the supplied user name and write out a + // greeting to the user by calling the WriteObject + // method. + protected override void ProcessRecord() + { + WriteObject("Hello " + Name + "!"); + } + } + } + ``` + At this point everything should look like this: + ![Step5](./Images/Step5.png) + +1. Build solution (F6); The `Output` window will print the location of generated cmdlet DLL: + ![Step6](./Images/Step6.png) + +1. Start PowerShell Core, run `Import-Module` on DLL path from previous step and run cmdlet: + ![Step7](./Images/Step7.png) +You can also run the same cmdlet on Linux and other systems that PowerShell Core supports: +![Step8](./Images/Step8.png) + +## Building a C# Cmdlet for PowerShell Standard 3.0 with Visual Studio + +Steps below show how to build your own C# cmdlet for PowerShell Standard 3.0 with Visual Studio. +Targeting PowerShell Standard 3.0 means that the same module will work against PowerShell Core as well as Windows PowerShell v3 and newer, +however, you are limited to a subset of the available PowerShell APIs. + +We will use the free [Visual Studio Community 2017](https://www.visualstudio.com/downloads). + +1. When installing Visual Studio 2017 select `.NET Core cross-platform development` under `Other Toolsets` + ![StdImage1](./Images/Step1.png) + +1. Create new C# project `SendGreetingStd` of type `Class Library (.NET Standard)` + ![StdImage21](./Images/Std21.png) + +1. On project properties verify that `Target framework` is `.NET Standard 2.0`:
+ ![StdImage22](./Images/Std22.png) + +1. Now we need to setup reference assemblies. + In `Solution Explorer` right click on project `Dependencies` and select `Manage NuGet Packages...` +In the top-right corner of the package manager select `nuget.org` package source, select `Browse` tab, type in `PowerShellStandard.Library` in the search and select `Include prerelease`. +It should find `PowerShellStandard.Library` package, select it and it will show package details; install it using `Install` button. +![StdImage3](./Images/Std3.png) + +1. Add the code of cmdlet: + ```CSharp + using System.Management.Automation; // PowerShell namespace. + + namespace SendGreeting + { + // Declare the class as a cmdlet and specify and + // appropriate verb and noun for the cmdlet name. + [Cmdlet(VerbsCommunications.Send, "Greeting")] + public class SendGreetingCommand : Cmdlet + { + // Declare the parameters for the cmdlet. + [Parameter(Mandatory = true)] + public string Name { get; set; } + + // Overide the ProcessRecord method to process + // the supplied user name and write out a + // greeting to the user by calling the WriteObject + // method. + protected override void ProcessRecord() + { + WriteObject("Hello " + Name + "!"); + } + } + } + ``` + At this point everything should look like this: + ![StdImage4](./Images/Std4.png) + +1. Build solution (F6); The `Output` window will print the location of generated cmdlet DLL: + ![StdImage5](./Images/Std5.png) + +1. Now cmdlet can be run on systems supported by PowerShell Standard;
+ For example:
+ On PowerShell Core on Windows: +![StdImage61](./Images/Std61.png) +On PowerShell Core on Linux: +![StdImage62](./Images/Std62.png) +On Windows PowerShell on Windows (this requires [.NET Framework 4.7.1](https://github.com/Microsoft/dotnet-framework-early-access/blob/master/instructions.md)): +![StdImage63](./Images/Std63.png) \ No newline at end of file diff --git a/docs/community/governance.md b/docs/community/governance.md index da9381396f8..6ab6d54629e 100644 --- a/docs/community/governance.md +++ b/docs/community/governance.md @@ -3,8 +3,6 @@ ## Terms * [**PowerShell Committee**](#powershell-committee): A committee of project owners who are responsible for design decisions, approving [RFCs][RFC-repo], and approving new maintainers/committee members -* **Project Leads**: Project Leads support the PowerShell Committee, engineering teams, and community by working across Microsoft teams and leadership, and working through industry issues with other companies. -They also have optional votes on the PowerShell Committee when they choose to invoke them. The initial Project Leads for PowerShell are Angel Calvo ([AngelCalvo](https://github.com/AngelCalvo)) and Kenneth Hansen ([khansen00](https://github.com/khansen00)). * [**Repository maintainer**](#repository-maintainers): An individual responsible for merging pull requests (PRs) into `master` when all requirements are met (code review, tests, docs, and RFC approval as applicable). Repository Maintainers are the only people with write permissions into `master`. * [**Area experts**](#area-experts): People who are experts for specific components (e.g. PSReadline, the parser) or technologies (e.g. security, performance). @@ -24,10 +22,12 @@ The PowerShell Committee and its members (aka Committee Members) are the primary ### Current Committee Members * Bruce Payette ([BrucePay](https://github.com/BrucePay)) -* Jason Shirk ([lzybkr](https://github.com/lzybkr)) -* Steve Lee ([SteveL-MSFT](https://github.com/SteveL-MSFT)) +* Dongbo Wang ([daxian-dbw](https://github.com/daxian-dbw)) * Hemant Mahawar ([HemantMahawar](https://github.com/HemantMahawar)) +* Jim Truher ([JamesWTruher](https://github.com/JamesWTruher)) * Joey Aiello ([joeyaiello](https://github.com/joeyaiello)) +* Kenneth Hansen ([khansen00](https://github.com/khansen00)) +* Steve Lee ([SteveL-MSFT](https://github.com/SteveL-MSFT)) ### Committee Member Responsibilities @@ -131,6 +131,6 @@ See our [Pull Request Process][pull-request-process] [ci-system]: ../testing-guidelines/testing-guidelines.md#ci-system [breaking-changes]: ../dev-process/breaking-change-contract.md [issue-process]: ../maintainers/issue-management.md -[pull-request-process]: ../maintainers/pull-request-process.md +[pull-request-process]: ../../.github/CONTRIBUTING.md#lifecycle-of-a-pull-request [docs-contributing]: https://github.com/PowerShell/PowerShell-Docs/blob/staging/CONTRIBUTING.md [maintainers]: ../maintainers/README.md diff --git a/docs/git/submodules.md b/docs/git/submodules.md index 7464a1ef86c..52acc6ad5f5 100644 --- a/docs/git/submodules.md +++ b/docs/git/submodules.md @@ -1,20 +1,16 @@ -Submodules -========== +# Submodules While most developers will not have to deal with submodules on a regular basis, those who do should read this information. The submodules currently in this project are: -- `src/Modules/Pester`: The Pester testing framework for PowerShell - - `src/libpsl-native/test/googletest`: The GoogleTest framework for Linux native code [submodules]: https://www.git-scm.com/book/en/v2/Git-Tools-Submodules -Rebase and Fast-Forward Merge Pull Requests in Submodules -========================================================= +## Rebase and Fast-Forward Merge Pull Requests in Submodules -*This is not necessary in the superproject, only submodules!* +Note: *This is not necessary in the superproject, only submodules!* **DO NOT** commit updates unless absolutely necessary. When submodules must be updated, a separate Pull Request must be submitted, reviewed, and merged before updating the superproject. diff --git a/docs/host-powershell/README.md b/docs/host-powershell/README.md index 0b09af9dd06..506d5b71d8c 100644 --- a/docs/host-powershell/README.md +++ b/docs/host-powershell/README.md @@ -1,5 +1,11 @@ # Host PowerShell Core in .NET Core Applications +## PowerShell Core v6.0.1 and Later + +The runtime assemblies for Windows, Linux and OSX are now published in NuGet package version 6.0.1.1 and above. + +Please see the [.NET Core Sample Application](#net-core-sample-application) section for an example that uses PowerShell Core `6.0.1.1` NuGet packages. + ## PowerShell Core v6.0.0-beta.3 and Later PowerShell Core is refactored in v6.0.0-beta.3 to remove the dependency on a customized `AssemblyLoadContext`. @@ -138,6 +144,7 @@ namespace Application.Test .NET Core SDK `2.0.0-preview1-005952` or higher is required. - [sample-dotnet2.0-powershell.beta.3](./sample-dotnet2.0-powershell.beta.3) - .NET Core `2.0.0` + PowerShell Core `beta.3` NuGet packages. .NET Core SDK `2.0.0-preview1-005952` or higher is required. +- [sample-dotnet2.0-powershell-crossplatform](./sample-dotnet2.0-powershell-crossplatform) - .Net Core `2.0.0` + PowerShell Core `6.0.1.1` NuGet packages. You can find the sample application project `"MyApp"` in each of the above 3 sample folders. To build the sample project, run the following commands (make sure the required .NET Core SDK is in use): @@ -147,6 +154,9 @@ dotnet restore .\MyApp\MyApp.csproj dotnet publish .\MyApp -c release -r win10-x64 ``` +For cross platform project there is no need to specify `-r win10-x64`. +The runtime for the build machine's platform will automatically be selected. + Then you can run `MyApp.exe` from the publish folder and see the results: ```none @@ -161,9 +171,3 @@ Evaluating '([S.M.A.ActionPreference], [S.M.A.AliasAttribute]).FullName' in PS C System.Management.Automation.ActionPreference System.Management.Automation.AliasAttribute ``` - -## Remaining Issue - -PowerShell Core builds separately for Windows and Unix, so the assemblies are different between Windows and Unix platforms. -Unfortunately, all PowerShell NuGet packages that have been published so far only contain PowerShell assemblies built specifically for Windows. -The issue [#3417](https://github.com/PowerShell/PowerShell/issues/3417) was opened to track publishing PowerShell NuGet packages for Unix platforms. diff --git a/docs/host-powershell/sample-dotnet1.1/Logic/UseRunspace.cs b/docs/host-powershell/sample-dotnet1.1/Logic/UseRunspace.cs index b13a08c244a..e126fd28a3a 100644 --- a/docs/host-powershell/sample-dotnet1.1/Logic/UseRunspace.cs +++ b/docs/host-powershell/sample-dotnet1.1/Logic/UseRunspace.cs @@ -1,6 +1,6 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.Management.Automation; using System.Management.Automation.Runspaces; diff --git a/docs/host-powershell/sample-dotnet1.1/MyApp/Program.cs b/docs/host-powershell/sample-dotnet1.1/MyApp/Program.cs index f0fa6b5fedf..27e082c3653 100644 --- a/docs/host-powershell/sample-dotnet1.1/MyApp/Program.cs +++ b/docs/host-powershell/sample-dotnet1.1/MyApp/Program.cs @@ -1,13 +1,12 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; using System.Reflection; namespace Application.Test { - public class Program + public class Program { /// /// Managed entry point shim, which starts the actual program @@ -15,10 +14,10 @@ public class Program public static int Main(string[] args) { // Application needs to use PowerShell AssemblyLoadContext if it needs to create powershell runspace - // PowerShell engine depends on PS ALC to provide the necessary assembly loading/searching support that is missing from .NET Core + // PowerShell engine depends on PS ALC to provide the necessary assembly loading/searching support that is missing from .NET Core string appBase = System.IO.Path.GetDirectoryName(typeof(Program).GetTypeInfo().Assembly.Location); System.Console.WriteLine("\nappBase: {0}", appBase); - + // Initialize the PS ALC and let it load 'Logic.dll' and start the execution return (int)PowerShellAssemblyLoadContextInitializer. InitializeAndCallEntryMethod( diff --git a/docs/host-powershell/sample-dotnet2.0-powershell-crossplatform/MyApp/MyApp.csproj b/docs/host-powershell/sample-dotnet2.0-powershell-crossplatform/MyApp/MyApp.csproj new file mode 100644 index 00000000000..5ff345cbbdc --- /dev/null +++ b/docs/host-powershell/sample-dotnet2.0-powershell-crossplatform/MyApp/MyApp.csproj @@ -0,0 +1,13 @@ + + + + netcoreapp2.0 + MyApp + Exe + win10-x64;linux-x64;osx.10.12-x64 + + + + + + diff --git a/docs/host-powershell/sample-dotnet2.0-powershell-crossplatform/MyApp/Program.cs b/docs/host-powershell/sample-dotnet2.0-powershell-crossplatform/MyApp/Program.cs new file mode 100644 index 00000000000..74676efba24 --- /dev/null +++ b/docs/host-powershell/sample-dotnet2.0-powershell-crossplatform/MyApp/Program.cs @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Management.Automation; + +namespace Application.Test +{ + public class Program + { + /// + /// Managed entry point shim, which starts the actual program + /// + public static int Main(string[] args) + { + using (PowerShell ps = PowerShell.Create()) + { + Console.WriteLine("\nEvaluating 'Get-Command Write-Output' in PS Core Runspace\n"); + var results = ps.AddScript("Get-Command Write-Output").Invoke(); + Console.WriteLine(results[0].ToString()); + } + return 0; + } + } +} diff --git a/docs/host-powershell/sample-dotnet2.0-powershell-crossplatform/NuGet.config b/docs/host-powershell/sample-dotnet2.0-powershell-crossplatform/NuGet.config new file mode 100644 index 00000000000..58f8d2c9b6d --- /dev/null +++ b/docs/host-powershell/sample-dotnet2.0-powershell-crossplatform/NuGet.config @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/docs/host-powershell/sample-dotnet2.0-powershell.beta.1/Logic/UseRunspace.cs b/docs/host-powershell/sample-dotnet2.0-powershell.beta.1/Logic/UseRunspace.cs index b13a08c244a..e126fd28a3a 100644 --- a/docs/host-powershell/sample-dotnet2.0-powershell.beta.1/Logic/UseRunspace.cs +++ b/docs/host-powershell/sample-dotnet2.0-powershell.beta.1/Logic/UseRunspace.cs @@ -1,6 +1,6 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.Management.Automation; using System.Management.Automation.Runspaces; diff --git a/docs/host-powershell/sample-dotnet2.0-powershell.beta.1/MyApp/Program.cs b/docs/host-powershell/sample-dotnet2.0-powershell.beta.1/MyApp/Program.cs index f0fa6b5fedf..27e082c3653 100644 --- a/docs/host-powershell/sample-dotnet2.0-powershell.beta.1/MyApp/Program.cs +++ b/docs/host-powershell/sample-dotnet2.0-powershell.beta.1/MyApp/Program.cs @@ -1,13 +1,12 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; using System.Reflection; namespace Application.Test { - public class Program + public class Program { /// /// Managed entry point shim, which starts the actual program @@ -15,10 +14,10 @@ public class Program public static int Main(string[] args) { // Application needs to use PowerShell AssemblyLoadContext if it needs to create powershell runspace - // PowerShell engine depends on PS ALC to provide the necessary assembly loading/searching support that is missing from .NET Core + // PowerShell engine depends on PS ALC to provide the necessary assembly loading/searching support that is missing from .NET Core string appBase = System.IO.Path.GetDirectoryName(typeof(Program).GetTypeInfo().Assembly.Location); System.Console.WriteLine("\nappBase: {0}", appBase); - + // Initialize the PS ALC and let it load 'Logic.dll' and start the execution return (int)PowerShellAssemblyLoadContextInitializer. InitializeAndCallEntryMethod( diff --git a/docs/host-powershell/sample-dotnet2.0-powershell.beta.3/MyApp/Program.cs b/docs/host-powershell/sample-dotnet2.0-powershell.beta.3/MyApp/Program.cs index 207028a2d1a..ec88a87b6e4 100644 --- a/docs/host-powershell/sample-dotnet2.0-powershell.beta.3/MyApp/Program.cs +++ b/docs/host-powershell/sample-dotnet2.0-powershell.beta.3/MyApp/Program.cs @@ -1,13 +1,12 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; namespace Application.Test { - public class Program + public class Program { /// /// Managed entry point shim, which starts the actual program diff --git a/docs/installation/linux.md b/docs/installation/linux.md index 3782f78a940..1551e08c3b0 100644 --- a/docs/installation/linux.md +++ b/docs/installation/linux.md @@ -1,20 +1,16 @@ -# Package installation instructions +# Package Installation Instructions Supports [Ubuntu 14.04][u14], [Ubuntu 16.04][u16], [Ubuntu 17.04][u17], [Debian 8][deb8], [Debian 9][deb9], [CentOS 7][cos], [Red Hat Enterprise Linux (RHEL) 7][rhel7], [OpenSUSE 42.2][opensuse], [Fedora 25][fed25], -[Fedora 26][fed26], [Arch Linux][arch], [many Linux distributions (AppImage)][lai], and [macOS 10.12][mac]. -All packages are available on our GitHub [releases][] page. - -All of these steps can be done automatically by the [`download.sh`][download] script. -You should *never* run a script without reading it first! +[Fedora 26][fed26], and [Arch Linux][arch]. -Please **read the [download][] script first**, and then if you want to run it, use: +For Linux distributions that are not officially supported, +you can try using the [PowerShell AppImage][lai]. +You can also try deploying PowerShell binaries directly using the Linux [`tar.gz` archive][tar], +but you would need to set up the necessary dependencies based on the OS in separate steps. -```sh -bash <(curl -fsSL https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/download.sh) -``` - -Once the package is installed, run `powershell` from a terminal. +All packages are available on our GitHub [releases][] page. +Once the package is installed, run `pwsh` from a terminal. [u14]: #ubuntu-1404 [u16]: #ubuntu-1604 @@ -29,7 +25,7 @@ Once the package is installed, run `powershell` from a terminal. [arch]: #arch-linux [lai]: #linux-appimage [mac]: #macos-1012 -[download]: https://github.com/PowerShell/PowerShell/blob/master/tools/download.sh +[tar]: #binary-archives ## Ubuntu 14.04 @@ -43,7 +39,7 @@ This is the preferred method. curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add - # Register the Microsoft Ubuntu repository -curl https://packages.microsoft.com/config/ubuntu/14.04/prod.list | sudo tee /etc/apt/sources.list.d/microsoft.list +sudo curl -o /etc/apt/sources.list.d/microsoft.list https://packages.microsoft.com/config/ubuntu/14.04/prod.list # Update the list of products sudo apt-get update @@ -52,7 +48,7 @@ sudo apt-get update sudo apt-get install -y powershell # Start PowerShell -powershell +pwsh ``` After registering the Microsoft repository once as superuser, @@ -61,13 +57,13 @@ from then on, you just need to use `sudo apt-get upgrade powershell` to update i ### Installation via Direct Download - Ubuntu 14.04 Download the Debian package -`powershell_6.0.0-beta.8-1.ubuntu.14.04_amd64.deb` +`powershell_6.0.2-1.ubuntu.14.04_amd64.deb` from the [releases][] page onto the Ubuntu machine. Then execute the following in the terminal: ```sh -sudo dpkg -i powershell_6.0.0-beta.8-1.ubuntu.14.04_amd64.deb +sudo dpkg -i powershell_6.0.2-1.ubuntu.14.04_amd64.deb sudo apt-get install -f ``` @@ -93,7 +89,7 @@ This is the preferred method. curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add - # Register the Microsoft Ubuntu repository -curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list | sudo tee /etc/apt/sources.list.d/microsoft.list +sudo curl -o /etc/apt/sources.list.d/microsoft.list https://packages.microsoft.com/config/ubuntu/16.04/prod.list # Update the list of products sudo apt-get update @@ -102,7 +98,7 @@ sudo apt-get update sudo apt-get install -y powershell # Start PowerShell -powershell +pwsh ``` After registering the Microsoft repository once as superuser, @@ -111,13 +107,13 @@ from then on, you just need to use `sudo apt-get upgrade powershell` to update i ### Installation via Direct Download - Ubuntu 16.04 Download the Debian package -`powershell_6.0.0-beta.8-1.ubuntu.16.04_amd64.deb` +`powershell_6.0.2-1.ubuntu.16.04_amd64.deb` from the [releases][] page onto the Ubuntu machine. Then execute the following in the terminal: ```sh -sudo dpkg -i powershell_6.0.0-beta.8-1.ubuntu.16.04_amd64.deb +sudo dpkg -i powershell_6.0.2-1.ubuntu.16.04_amd64.deb sudo apt-get install -f ``` @@ -143,7 +139,7 @@ This is the preferred method. curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add - # Register the Microsoft Ubuntu repository -curl https://packages.microsoft.com/config/ubuntu/17.04/prod.list | sudo tee /etc/apt/sources.list.d/microsoft.list +sudo curl -o /etc/apt/sources.list.d/microsoft.list https://packages.microsoft.com/config/ubuntu/17.04/prod.list # Update the list of products sudo apt-get update @@ -152,7 +148,7 @@ sudo apt-get update sudo apt-get install -y powershell # Start PowerShell -powershell +pwsh ``` After registering the Microsoft repository once as superuser, @@ -161,13 +157,13 @@ from then on, you just need to use `sudo apt-get upgrade powershell` to update i ### Installation via Direct Download - Ubuntu 17.04 Download the Debian package -`powershell_6.0.0-beta.8-1.ubuntu.17.04_amd64.deb` +`powershell_6.0.2-1.ubuntu.17.04_amd64.deb` from the [releases][] page onto the Ubuntu machine. Then execute the following in the terminal: ```sh -sudo dpkg -i powershell_6.0.0-beta.8-1.ubuntu.17.04_amd64.deb +sudo dpkg -i powershell_6.0.2-1.ubuntu.17.04_amd64.deb sudo apt-get install -f ``` @@ -206,7 +202,7 @@ sudo apt-get update sudo apt-get install -y powershell # Start PowerShell -powershell +pwsh ``` After registering the Microsoft repository once as superuser, @@ -215,13 +211,13 @@ from then on, you just need to use `sudo apt-get upgrade powershell` to update i ### Installation via Direct Download - Debian 8 Download the Debian package -`powershell_6.0.0-beta.8-1.debian.8_amd64.deb` +`powershell_6.0.2-1.debian.8_amd64.deb` from the [releases][] page onto the Debian machine. Then execute the following in the terminal: ```sh -sudo dpkg -i powershell_6.0.0-beta.8-1.debian.8_amd64.deb +sudo dpkg -i powershell_6.0.2-1.debian.8_amd64.deb sudo apt-get install -f ``` @@ -260,7 +256,7 @@ sudo apt-get update sudo apt-get install -y powershell # Start PowerShell -powershell +pwsh ``` After registering the Microsoft repository once as superuser, @@ -269,13 +265,13 @@ from then on, you just need to use `sudo apt-get upgrade powershell` to update i ### Installation via Direct Download - Debian 9 Download the Debian package -`powershell_6.0.0-beta.8-1.debian.9_amd64.deb` +`powershell_6.0.2-1.debian.9_amd64.deb` from the [releases][] page onto the Debian machine. Then execute the following in the terminal: ```sh -sudo dpkg -i powershell_6.0.0-beta.8-1.debian.9_amd64.deb +sudo dpkg -i powershell_6.0.2-1.debian.9_amd64.deb sudo apt-get install -f ``` @@ -305,7 +301,7 @@ curl https://packages.microsoft.com/config/rhel/7/prod.repo | sudo tee /etc/yum. sudo yum install -y powershell # Start PowerShell -powershell +pwsh ``` After registering the Microsoft repository once as superuser, @@ -314,19 +310,19 @@ you just need to use `sudo yum update powershell` to update PowerShell. ### Installation via Direct Download - CentOS 7 Using [CentOS 7][], download the RPM package -`powershell-6.0.0_beta.8-1.rhel.7.x86_64.rpm` +`powershell-6.0.2-1.rhel.7.x86_64.rpm` from the [releases][] page onto the CentOS machine. Then execute the following in the terminal: ```sh -sudo yum install powershell-6.0.0_beta.8-1.rhel.7.x86_64.rpm +sudo yum install powershell-6.0.2-1.rhel.7.x86_64.rpm ``` You can also install the RPM without the intermediate step of downloading it: ```sh -sudo yum install https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-beta.8/powershell-6.0.0_beta.8-1.rhel.7.x86_64.rpm +sudo yum install https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/powershell-6.0.2-1.rhel.7.x86_64.rpm ``` ### Uninstallation - CentOS 7 @@ -351,7 +347,7 @@ curl https://packages.microsoft.com/config/rhel/7/prod.repo | sudo tee /etc/yum. sudo yum install -y powershell # Start PowerShell -powershell +pwsh ``` After registering the Microsoft repository once as superuser, @@ -360,19 +356,19 @@ you just need to use `sudo yum update powershell` to update PowerShell. ### Installation via Direct Download - Red Hat Enterprise Linux (RHEL) 7 Download the RPM package -`powershell-6.0.0_beta.8-1.rhel.7.x86_64.rpm` +`powershell-6.0.2-1.rhel.7.x86_64.rpm` from the [releases][] page onto the Red Hat Enterprise Linux machine. Then execute the following in the terminal: ```sh -sudo yum install powershell-6.0.0_beta.8-1.rhel.7.x86_64.rpm +sudo yum install powershell-6.0.2-1.rhel.7.x86_64.rpm ``` You can also install the RPM without the intermediate step of downloading it: ```sh -sudo yum install https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-beta.8/powershell-6.0.0_beta.8-1.rhel.7.x86_64.rpm +sudo yum install https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/powershell-6.0.2-1.rhel.7.x86_64.rpm ``` ### Uninstallation - Red Hat Enterprise Linux (RHEL) 7 @@ -383,9 +379,9 @@ sudo yum remove powershell ## OpenSUSE 42.2 -> **Note:** When installing PowerShell Core, OpenSUSE may report that nothing provides libcurl. -libcurl should already be installed on supported versions of OpenSUSE. -Run zypper search libcurl to confirm. +> **Note:** When installing PowerShell Core, OpenSUSE may report that nothing provides `libcurl`. +`libcurl` should already be installed on supported versions of OpenSUSE. +Run `zypper search libcurl` to confirm. The error will present 2 'solutions'. Choose 'Solution 2' to continue installing PowerShell Core. ### Installation via Package Repository (preferred) - OpenSUSE 42.2 @@ -406,24 +402,24 @@ sudo zypper update sudo zypper install powershell # Start PowerShell -powershell +pwsh ``` ### Installation via Direct Download - OpenSUSE 42.2 -Download the RPM package `powershell-6.0.0_beta.8-1.rhel.7.x86_64.rpm` +Download the RPM package `powershell-6.0.2-1.rhel.7.x86_64.rpm` from the [releases][] page onto the OpenSUSE machine. ```sh sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc -sudo zypper install powershell-6.0.0_beta.8-1.rhel.7.x86_64.rpm +sudo zypper install powershell-6.0.2-1.rhel.7.x86_64.rpm ``` You can also install the RPM without the intermediate step of downloading it: ```sh sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc -sudo zypper install https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-beta.8/powershell-6.0.0_beta.8-1.rhel.7.x86_64.rpm +sudo zypper install https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/powershell-6.0.2-1.rhel.7.x86_64.rpm ``` ### Uninstallation - OpenSUSE 42.2 @@ -452,25 +448,25 @@ sudo dnf update sudo dnf install -y powershell # Start PowerShell -powershell +pwsh ``` ### Installation via Direct Download - Fedora 25 Download the RPM package -`powershell-6.0.0_beta.8-1.rhel.7.x86_64.rpm` -from the [releases][] page onto the Red Hat Enterprise Linux machine. +`powershell-6.0.2-1.rhel.7.x86_64.rpm` +from the [releases][] page onto the Fedora machine. Then execute the following in the terminal: ```sh -sudo dnf install powershell-6.0.0_beta.8-1.rhel.7.x86_64.rpm +sudo dnf install powershell-6.0.2-1.rhel.7.x86_64.rpm ``` You can also install the RPM without the intermediate step of downloading it: ```sh -sudo dnf install https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-beta.8/powershell-6.0.0_beta.8-1.rhel.7.x86_64.rpm +sudo dnf install https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/powershell-6.0.2-1.rhel.7.x86_64.rpm ``` ### Uninstallation - Fedora 25 @@ -502,21 +498,21 @@ sudo dnf install compat-openssl10 sudo dnf install -y powershell # Start PowerShell -powershell +pwsh ``` ### Installation via Direct Download - Fedora 26 Download the RPM package -`powershell-6.0.0_beta.8-1.rhel.7.x86_64.rpm` -from the [releases][] page onto the Red Hat Enterprise Linux machine. +`powershell-6.0.2-1.rhel.7.x86_64.rpm` +from the [releases][] page onto the Fedora machine. Then execute the following in the terminal: ```sh sudo dnf update sudo dnf install compat-openssl10 -sudo dnf install powershell-6.0.0_beta.8-1.rhel.7.x86_64.rpm +sudo dnf install powershell-6.0.2-1.rhel.7.x86_64.rpm ``` You can also install the RPM without the intermediate step of downloading it: @@ -524,7 +520,7 @@ You can also install the RPM without the intermediate step of downloading it: ```sh sudo dnf update sudo dnf install compat-openssl10 -sudo dnf install https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-beta.8/powershell-6.0.0_beta.8-1.rhel.7.x86_64.rpm +sudo dnf install https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/powershell-6.0.2-1.rhel.7.x86_64.rpm ``` ### Uninstallation - Fedora 26 @@ -553,14 +549,14 @@ For more information on installing packages from the AUR, see the [Arch Linux wi ## Linux AppImage Using a recent Linux distribution, -download the AppImage `PowerShell-6.0.0-beta.8-x86_64.AppImage` +download the AppImage `powershell-6.0.1-x86_64.AppImage` from the [releases][] page onto the Linux machine. Then execute the following in the terminal: ```bash -chmod a+x PowerShell-6.0.0-beta.8-x86_64.AppImage -./PowerShell-6.0.0-beta.8-x86_64.AppImage +chmod a+x powershell-6.0.1-x86_64.AppImage +./powershell-6.0.1-x86_64.AppImage ``` The [AppImage][] lets you run PowerShell without installing it. @@ -571,158 +567,146 @@ and is a single binary. [appimage]: http://appimage.org/ -## macOS 10.12 +## Kali -### Installation via Homebrew (preferred) - macOS 10.12 +### Installation -[Homebrew][brew] is the missing package manager for macOS. -If the `brew` command is not found, -you need to install Homebrew following [their instructions][brew]. +```sh +# Install prerequisites +apt-get install libunwind8 libicu55 +wget http://security.debian.org/debian-security/pool/updates/main/o/openssl/libssl1.0.0_1.0.1t-1+deb8u6_amd64.deb +dpkg -i libssl1.0.0_1.0.1t-1+deb8u6_amd64.deb -Once you've installed Homebrew, installing PowerShell is easy. -First, install [Homebrew-Cask][cask], so you can install more packages: +# Install PowerShell +dpkg -i powershell_6.0.2-1.ubuntu.16.04_amd64.deb -```sh -brew tap caskroom/cask +# Start PowerShell +pwsh ``` -Now, you can install PowerShell: +### Run PowerShell in latest Kali (Kali GNU/Linux Rolling) without installing it ```sh -brew cask install powershell +# Grab the latest App Image +wget https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/powershell-6.0.2-x86_64.AppImage + +# Make executable +chmod a+x powershell-6.0.2-x86_64.AppImage + +# Start PowerShell +./powershell-6.0.2-x86_64.AppImage ``` -When new versions of PowerShell are released, -simply update Homebrew's formulae and upgrade PowerShell: +### Uninstallation - Kali ```sh -brew update -brew cask reinstall powershell +dpkg -r powershell_6.0.2-1.ubuntu.16.04_amd64.deb ``` -> Note: because of [this issue in Cask](https://github.com/caskroom/homebrew-cask/issues/29301), you currently have to do a reinstall to upgrade. +## Raspbian -[brew]: http://brew.sh/ -[cask]: https://caskroom.github.io/ +Currently, PowerShell is only supported on Raspbian Stretch. -### Installation via Direct Download - macOS 10.12 +Also CoreCLR (and thus PowerShell Core) will only work on Pi 2 and Pi 3 devices as other devices like [Pi Zero](https://github.com/dotnet/coreclr/issues/10605) have an unsupported processor. -Using macOS 10.12, download the PKG package -`powershell-6.0.0-beta.8-osx.10.12-x64.pkg` -from the [releases][] page onto the macOS machine. +Download [Raspbian Stretch](https://www.raspberrypi.org/downloads/raspbian/) and follow the [installation instructions](https://www.raspberrypi.org/documentation/installation/installing-images/README.md) to get it onto your Pi. -Either double-click the file and follow the prompts, -or install it from the terminal: +### Installation ```sh -sudo installer -pkg powershell-6.0.0-beta.8-osx.10.12-x64.pkg -target / -``` +# Install prerequisites +sudo apt-get install libunwind8 -### Uninstallation - macOS 10.12 +# Grab the latest tar.gz +wget https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/powershell-6.0.2-linux-arm32.tar.gz -If you installed PowerShell with Homebrew, uninstallation is easy: +# Make folder to put powershell +mkdir ~/powershell -```sh -brew cask uninstall powershell +# Unpack the tar.gz file +tar -xvf ./powershell-6.0.2-linux-arm32.tar.gz -C ~/powershell + +# Start PowerShell +~/powershell/pwsh ``` -If you installed PowerShell via direct download, -PowerShell must be removed manually: +Optionally you can create a symbolic link to be able to start PowerShell without specifying path to the "pwsh" binary ```sh -sudo rm -rf /usr/local/bin/powershell /usr/local/microsoft/powershell -``` +# Start PowerShell from bash with sudo to create a symbolic link +sudo ~/powershell/pwsh -c New-Item -ItemType SymbolicLink -Path "/usr/bin/pwsh" -Target "\$PSHOME/pwsh" -Force -To uninstall the additional PowerShell paths (such as the user profile path) -please see the [paths][paths] section below in this document -and remove the desired the paths with `sudo rm`. -(Note: this is not necessary if you installed with Homebrew.) +# alternatively you can run following to create a symbolic link +# sudo ln -s ~/powershell/pwsh /usr/bin/pwsh -[paths]:#paths +# Now to start PowerShell you can just run "pwsh" +``` -### OpenSSL on macOS +### Uninstallation - Raspbian -On macOS, .NET Core requires Homebrew's OpenSSL -because the "OpenSSL" system libraries on macOS are not OpenSSL, -as Apple deprecated OpenSSL in favor of their own libraries. -This requirement is not a hard requirement for all of PowerShell. -However, most networking functions (such as `Invoke-WebRequest`) -do require OpenSSL to work properly. +```sh +rm -rf ~/powershell +``` -The PowerShell formula for Homebrew includes this OpenSSL as a dependency, -so you if you installed via Homebrew, you shouldn't run into these problems. +## Binary Archives -If you installed via direct download (or through some means other than Homebrew), -the easiest fix for these issues is to install [Homebrew's OpenSSL][openssl]: +PowerShell binary `tar.gz` archives are provided for macOS and Linux platforms to enable advanced deployment scenarios. -```bash -brew install openssl -brew install curl --with-openssl -``` +### Dependencies -**Please ignore** .NET Core's installation instructions to manually link the OpenSSL libraries. -This is **not** required for PowerShell as we patch .NET Core's cryptography libraries to find Homebrew's OpenSSL in its installed location. -Again, **do not** run `brew link --force` nor `ln -s` for OpenSSL, regardless of other instructions. +For Linux, PowerShell builds portable binaries for all Linux distributions. +But .NET Core runtime requires different dependencies on different distributions, +and hence PowerShell does the same. -Homebrew previously allowed OpenSSL libraries to be linked to the system library location; -however, this created major security holes and is [no longer allowed][homebrew-patch]. -Because .NET Core's 1.0.0 release libraries still look in the prior system location for OpenSSL, -they will fail to work unless the libraries are manually placed there (security risk), -or their libraries are patched (which we do). -To patch .NET Core's cryptography libraries, we use `install_name_tool`: +The following chart shows the .NET Core 2.0 dependencies on different Linux distributions that are officially supported. -```bash -find ~/.nuget -name System.Security.Cryptography.Native.dylib | xargs sudo install_name_tool -add_rpath /usr/local/opt/openssl/lib -find ~/.nuget -name System.Net.Http.Native.dylib | xargs sudo install_name_tool -change /usr/lib/libcurl.4.dylib /usr/local/opt/curl/lib/libcurl.4.dylib -``` +| OS | Dependencies | +| ------------------ | ------------ | +| Ubuntu 14.04 | libc6, libgcc1, libgssapi-krb5-2, liblttng-ust0, libstdc++6,
libcurl3, libunwind8, libuuid1, zlib1g, libssl1.0.0, libicu52 | +| Ubuntu 16.04 | libc6, libgcc1, libgssapi-krb5-2, liblttng-ust0, libstdc++6,
libcurl3, libunwind8, libuuid1, zlib1g, libssl1.0.0, libicu55 | +| Ubuntu 17.04 | libc6, libgcc1, libgssapi-krb5-2, liblttng-ust0, libstdc++6,
libcurl3, libunwind8, libuuid1, zlib1g, libssl1.0.0, libicu57 | +| Debian 8 (Jessie) | libc6, libgcc1, libgssapi-krb5-2, liblttng-ust0, libstdc++6,
libcurl3, libunwind8, libuuid1, zlib1g, libssl1.0.0, libicu52 | +| Debian 9 (Stretch) | libc6, libgcc1, libgssapi-krb5-2, liblttng-ust0, libstdc++6,
libcurl3, libunwind8, libuuid1, zlib1g, libssl1.0.2, libicu57 | +| CentOS 7
Oracle Linux 7
RHEL 7
OpenSUSE 42.2
Fedora 25 | libunwind, libcurl, openssl-libs, libicu | +| Fedora 26 | libunwind, libcurl, openssl-libs, libicu, compat-openssl10 | -This updates .NET Core's library to look in Homebrew's OpenSSL installation location instead of the system library location. -The PowerShell macOS package come with the necessary libraries patched, -and the build script patches the libraries on-the-fly when building from source. -You *can* run this command manually if you're having trouble with .NET Core's cryptography libraries. +In order to deploy PowerShell binaries on Linux distributions that are not officially supported, +you would need to install the necessary dependencies for the target OS in separate steps. +For example, our [Amazon Linux dockerfile][amazon-dockerfile] installs dependencies first, +and then extracts the Linux `tar.gz` archive. -[openssl]: https://github.com/Homebrew/homebrew-core/blob/master/Formula/openssl.rb -[homebrew-patch]: https://github.com/Homebrew/brew/pull/597 +[amazon-dockerfile]: https://github.com/PowerShell/PowerShell/blob/master/docker/community/amazonlinux/Dockerfile -## Kali +### Installation - Binary Archives -### Installation +#### Linux ```sh -# Install prerequisites -apt-get install libunwind8 libicu55 -wget http://security.debian.org/debian-security/pool/updates/main/o/openssl/libssl1.0.0_1.0.1t-1+deb8u6_amd64.deb -dpkg -i libssl1.0.0_1.0.1t-1+deb8u6_amd64.deb - -# Install PowerShell -dpkg -i powershell_6.0.0-beta.8-1.ubuntu.16.04_amd64.deb - -# Start PowerShell -powershell -``` +# Download the powershell '.tar.gz' archive +curl -L -o /tmp/powershell.tar.gz https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/powershell-6.0.2-linux-x64.tar.gz -### Run PowerShell in latest Kali (Kali GNU/Linux Rolling) without installing it +# Create the target folder where powershell will be placed +sudo mkdir -p /opt/microsoft/powershell/6.0.2 -```sh -# Grab the latest App Image -wget https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-beta.8/PowerShell-6.0.0-beta.8-x86_64.AppImage +# Expand powershell to the target folder +sudo tar zxf /tmp/powershell.tar.gz -C /opt/microsoft/powershell/6.0.2 -# Make executable -chmod a+x PowerShell-6.0.0-beta.8-x86_64.AppImage +# Set execute permissions +sudo chmod +x /opt/microsoft/powershell/6.0.2/pwsh -# Start PowerShell -./PowerShell-6.0.0-beta.8-x86_64.AppImage +# Create the symbolic link that points to pwsh +sudo ln -s /opt/microsoft/powershell/6.0.2/pwsh /usr/bin/pwsh ``` -### Uninstallation - Kali +### Uninstallation - Binary Archives ```sh -dpkg -r powershell_6.0.0-beta.8-1.ubuntu.16.04_amd64.deb +sudo rm -rf /usr/bin/pwsh /opt/microsoft/powershell ``` ## Paths -* `$PSHOME` is `/opt/microsoft/powershell/6.0.0-beta.8/` +* `$PSHOME` is `/opt/microsoft/powershell/6.0.2/` * User profiles will be read from `~/.config/powershell/profile.ps1` * Default profiles will be read from `$PSHOME/profile.ps1` * User modules will be read from `~/.local/share/powershell/Modules` @@ -737,8 +721,8 @@ On Linux and macOS, the [XDG Base Directory Specification][xdg-bds] is respected Note that because macOS is a derivation of BSD, instead of `/opt`, the prefix used is `/usr/local`. -Thus, `$PSHOME` is `/usr/local/microsoft/powershell/6.0.0-beta.8/`, -and the symlink is placed at `/usr/local/bin/powershell`. +Thus, `$PSHOME` is `/usr/local/microsoft/powershell/6.0.2/`, +and the symlink is placed at `/usr/local/bin/pwsh`. [releases]: https://github.com/PowerShell/PowerShell/releases/latest [xdg-bds]: https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html diff --git a/docs/installation/macos.md b/docs/installation/macos.md new file mode 100644 index 00000000000..4163699b46e --- /dev/null +++ b/docs/installation/macos.md @@ -0,0 +1,102 @@ +# Package Installation Instructions + +## macOS 10.12+ + +### Installation via Homebrew (preferred) + +[Homebrew][brew] is the missing package manager for macOS. +If the `brew` command is not found, +you need to install Homebrew following [their instructions][brew]. + +Once you've installed Homebrew, installing PowerShell is easy. +First, install [Homebrew-Cask][cask], so you can install more packages: + +```sh +brew tap caskroom/cask +``` + +Now, you can install PowerShell: + +```sh +brew cask install powershell +``` + +Finally, verify that your install is working properly: + +```sh +pwsh +``` + +When new versions of PowerShell are released, +simply update Homebrew's formulae and upgrade PowerShell: + +```sh +brew update +brew cask upgrade powershell +``` + +[brew]: http://brew.sh/ +[cask]: https://caskroom.github.io/ + +### Installation via Direct Download + +Using macOS 10.12+, download the PKG package +`powershell-6.0.2-osx.10.12-x64.pkg` +from the [releases][] page onto the macOS machine. + +Either double-click the file and follow the prompts, +or install it from the terminal: + +```sh +sudo installer -pkg powershell-6.0.2-osx.10.12-x64.pkg -target / +``` + +[releases]: https://github.com/PowerShell/PowerShell/releases + +### Installation via Binary Archive + +```sh +# Download the powershell '.tar.gz' archive +curl -L -o /tmp/powershell.tar.gz https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/powershell-6.0.2-osx-x64.tar.gz + +# Create the target folder where powershell will be placed +sudo mkdir -p /usr/local/microsoft/powershell/6.0.2 + +# Expand powershell to the target folder +sudo tar zxf /tmp/powershell.tar.gz -C /usr/local/microsoft/powershell/6.0.2 + +# Set execute permissions +sudo chmod +x /usr/local/microsoft/powershell/6.0.2/pwsh + +# Create the symbolic link that points to pwsh +sudo ln -s /usr/local/microsoft/powershell/6.0.2/pwsh /usr/local/bin/pwsh +``` + +### Uninstallation + +If you installed PowerShell with Homebrew, uninstallation is easy: + +```sh +brew cask uninstall powershell +``` + +If you installed PowerShell via direct download, +PowerShell must be removed manually: + +```sh +sudo rm -rf /usr/local/microsoft /Applications/PowerShell.app +sudo rm -f /usr/local/bin/pwsh /usr/local/share/man/man1/pwsh.1.gz +sudo pkgutil --forget com.microsoft.powershell +``` + +If you installed PowerShell via binary archive, PowerShell must be removed manually. + +```sh +sudo rm -rf /usr/local/microsoft +sudo rm -f /usr/local/bin/pwsh +``` + +To uninstall the additional PowerShell paths (such as the user profile path) +please see the [paths](linux.md#path) section below in this document +and remove the desired the paths with `sudo rm`. +(Note: this is not necessary if you installed with Homebrew.) diff --git a/docs/installation/windows.md b/docs/installation/windows.md index 47a307aae88..660f8a1c9e1 100644 --- a/docs/installation/windows.md +++ b/docs/installation/windows.md @@ -3,14 +3,14 @@ ## MSI To install PowerShell on Windows Full SKU (works on Windows 7 SP1 and later), download either the MSI from [AppVeyor][] for a nightly build, -or a released package from our GitHub [releases][] page. The MSI file looks like this - `PowerShell-6.0.0...msi` +or a released package from our GitHub [releases][] page. Once downloaded, double-click the installer and follow the prompts. There is a shortcut placed in the Start Menu upon installation. * By default the package is installed to `$env:ProgramFiles\PowerShell\` -* You can launch PowerShell via the Start Menu or `$env:ProgramFiles\PowerShell\powershell.exe` +* You can launch PowerShell via the Start Menu or `pwsh` from a new command prompt. ### Prerequisites @@ -23,6 +23,55 @@ To enable PowerShell remoting over WinRM, the following prerequisites need to be or newer ([5.0](https://www.microsoft.com/download/details.aspx?id=50395), [5.1](https://www.microsoft.com/download/details.aspx?id=54616)) on Windows 7. +## ZIP + +PowerShell binary ZIP archives are provided to enable advanced deployment scenarios. +Be noted that when using the ZIP archive, you won't get the prerequisites check as in the MSI package. +So in order for remoting over WinRM to work properly on Windows versions prior to Windows 10, +you need to make sure the [prerequisites](#prerequisites) are met. + +## Deploying on Windows IoT + +Windows IoT already comes with Windows PowerShell which we will use to deploy PowerShell Core 6. + +* Create `PSSession` to target device + +```powershell +$s = New-PSSession -ComputerName -Credential Administrator +``` + +* Copy the zip package to the device + +```powershell +# change the destination to however you had partitioned it with sufficient space for the zip and the unzipped contents +# the path should be local to the device +Copy-Item .\PowerShell-6.0.2-win-arm32.zip -Destination u:\users\administrator\Downloads -ToSession $s +``` + +* Connect to the device and expand the archive + +```powershell +Enter-PSSession $s +cd u:\users\administrator\downloads +Expand-Archive .\PowerShell-6.0.2-win-arm32.zip +``` + +* Setup remoting to PowerShell Core 6 + +```powershell +cd .\PowerShell-6.0.2-win-arm32 +# Be sure to use the -PowerShellHome parameter otherwise it'll try to create a new endpoint with Windows PowerShell 5.1 +.\Install-PowerShellRemoting.ps1 -PowerShellHome . +# You'll get an error message and will be disconnected from the device because it has to restart WinRM +``` + +* Connect to PowerShell Core 6 endpoint on device + +```powershell +# Be sure to use the -Configuration parameter. If you omit it, you will connect to Windows PowerShell 5.1 +Enter-PSSession -ComputerName -Credential Administrator -Configuration powershell.6.0.2 +``` + ## Deploying on Nano Server These instructions assume that Windows PowerShell is running on the Nano Server image and that it has been generated by the [Nano Server Image Builder](https://technet.microsoft.com/windows-server-docs/get-started/deploy-nano-server). @@ -106,13 +155,13 @@ Install-PowerShellRemoting.ps1 #### Executed by another instance of PowerShell on behalf of the instance that it will register ``` powershell -\Install-PowerShellRemoting.ps1 -PowerShellHome "" -PowerShellVersion "" +\Install-PowerShellRemoting.ps1 -PowerShellHome "" ``` For Example: ``` powershell -C:\Program Files\PowerShell\6.0.0.9\Install-PowerShellRemoting.ps1 -PowerShellHome "C:\Program Files\PowerShell\6.0.0.9\" -PowerShellVersion "6.0.0-alpha.9" +& 'C:\Program Files\PowerShell\6.0.2\Install-PowerShellRemoting.ps1' -PowerShellHome 'C:\Program Files\PowerShell\6.0.2\' ``` **NOTE:** The remoting registration script will restart WinRM, so all existing PSRP sessions will terminate immediately after the script is run. If run during a remote session, this will terminate the connection. @@ -122,8 +171,8 @@ C:\Program Files\PowerShell\6.0.0.9\Install-PowerShellRemoting.ps1 -PowerShellHo Create a PowerShell session to the new PowerShell endpoint by specifying `-ConfigurationName "some endpoint name"`. To connect to the PowerShell instance from the example above, use either: ``` powershell -New-PSSession ... -ConfigurationName "powershell.6.0.0-alpha.9" -Enter-PSSession ... -ConfigurationName "powershell.6.0.0-alpha.9" +New-PSSession ... -ConfigurationName "powershell.6.0.2" +Enter-PSSession ... -ConfigurationName "powershell.6.0.2" ``` Note that `New-PSSession` and `Enter-PSSession` invocations that do not specify `-ConfigurationName` will target the default PowerShell endpoint, `microsoft.powershell`. @@ -142,4 +191,4 @@ We publish an archive with CoreCLR bits on every CI build with [AppVeyor][]. * Unblock zip file: right-click in File Explorer -> Properties -> check 'Unblock' box -> apply * Extract zip file to `bin` directory -* `./bin/powershell.exe` +* `./bin/pwsh.exe` diff --git a/docs/learning-powershell/README.md b/docs/learning-powershell/README.md index 526dffbd833..6b59e21ce85 100644 --- a/docs/learning-powershell/README.md +++ b/docs/learning-powershell/README.md @@ -31,7 +31,7 @@ At the end of this exercise, you should be able to launch the PowerShell session [inst-linux]: ../installation/linux.md [inst-win]: ../installation/windows.md -[inst-macos]: ../installation/linux.md#os-x-1011 +[inst-macos]: ../installation/macos.md Getting Started with PowerShell ---- diff --git a/docs/learning-powershell/using-vscode.md b/docs/learning-powershell/using-vscode.md index 0441a53fbab..3623039153d 100644 --- a/docs/learning-powershell/using-vscode.md +++ b/docs/learning-powershell/using-vscode.md @@ -59,13 +59,13 @@ If you wish to use a specific installation of PowerShell with Visual Studio Code ```json // On Windows: - "powershell.powerShellExePath": "c:/Program Files/PowerShell//powershell.exe" + "powershell.powerShellExePath": "c:/Program Files/PowerShell//pwsh.exe" // On Linux: - "powershell.powerShellExePath": "/opt/microsoft/powershell//powershell" + "powershell.powerShellExePath": "/opt/microsoft/powershell//pwsh" // On macOS: - "powershell.powerShellExePath": "/usr/local/microsoft/powershell//powershell" + "powershell.powerShellExePath": "/usr/local/microsoft/powershell//pwsh" ``` 3. Replace the setting with the path to the desired PowerShell executable diff --git a/docs/maintainers/issue-management.md b/docs/maintainers/issue-management.md index 71c547ee332..ddb816126e6 100644 --- a/docs/maintainers/issue-management.md +++ b/docs/maintainers/issue-management.md @@ -1,12 +1,19 @@ # Issue Management +## Security Vulnerabilities + +If you believe that there is a security vulnerability in PowerShell Core, +it **must** be reported to [secure@microsoft.com](https://technet.microsoft.com/en-us/security/ff852094.aspx) to allow for [Coordinated Vulnerability Disclosure](https://technet.microsoft.com/en-us/security/dn467923). +**Only** file an issue, if secure@microsoft.com has confirmed filing an issue is appropriate. + ## Long-living issue labels -======= -## Issue and PR Labels + +### Issue and PR Labels Issues are opened for many different reasons. We use the following labels for issue classifications: +* `Issue-Announcement`: the issue is for discussing an [Announcement](https://github.com/PowerShell/Announcements) * `Issue-Bug`: the issue is reporting a bug * `Issue-Code Cleanup`: the issue is for cleaning up the code with no impact on functionality * `Issue-Discussion`: the issue may not have a clear classification yet. @@ -61,6 +68,7 @@ These labels describe what feature area of PowerShell that an issue affects: ### Operating Systems These are for issues that are specific to certain Operating Systems: + * `OS-Linux` * `OS-macOS` * `OS-Windows` @@ -78,15 +86,19 @@ The following labels are used on PRs: ### Miscellaneous labels -* `Committee-Reviewed` : The PR/Issue has been reviewed by the [powershell-committee](../community/governance.md#powershell-committee) -* `Up-for-Grabs`: We've acknowledged the issue but have no immediate plans to address it. - If you're looking for a way to contribute, these issues can be a good place to start. -* `Blocked`: an issue cannot be addressed due to external factors, +* `Blocked` : An issue cannot be addressed due to external factors, but should not be closed because those external factors are temporary. -* `BVT/DRT`: an issue affecting or exposed by tests that have not been open sourced. -* `Porting`: an issue that affects a feature not yet ported to other platforms. -* `Usability`: this label is used to help us filter issues that might be higher priority - because they more directly affect the usability of a particular feature or area. -* `Changelog Needed`: The PR requires an addition to the changelog, +* `BVT/DRT` : An issue affecting or exposed by tests that have not been open sourced. +* `Changelog Needed` : The PR requires an addition to the changelog, and should be removed when it has been added. +* `Committee-Reviewed` : The PR/Issue has been reviewed by the [powershell-committee](../community/governance.md#powershell-committee) +* `Compliance` : Issues with the compliance label are required to be fixed either in the long term or short term for + Microsoft to continue to sign and release packages from the project as official Microsoft packages. + The time frame in which it needs to be fixed should be identified in the issue. * `Documentation Needed` : The PR has changes that require a documentation change or new documentation added to [PowerShell-Docs](http://github.com/powershell/powershell-docs) +* `Porting` : An issue that affects a feature not yet ported to other platforms. +* `Up-for-Grabs` : We've acknowledged the issue but have no immediate plans to address it. + If you're looking for a way to contribute, these issues can be a good place to start. +* `Usability` : This label is used to help us filter issues that might be higher priority + because they more directly affect the usability of a particular feature or area. +* `Waiting - DotNetCore` : An issue waiting on a fix/change in DotNetCore. diff --git a/docs/maintainers/releasing.md b/docs/maintainers/releasing.md index 28ab288ea55..267f04b5015 100644 --- a/docs/maintainers/releasing.md +++ b/docs/maintainers/releasing.md @@ -14,7 +14,7 @@ This is to help track the release preparation work. > Note: Step 2, 3 and 4 can be done in parallel. -1. Create a branch named `release` in `PowerShell/PowerShell` repository. +1. Create a branch named `release-` in our private repository. All release related changes should happen in this branch. 1. Prepare packages - [Build release packages](#building-packages). @@ -28,7 +28,7 @@ This is to help track the release preparation work. 1. [Create NuGet packages](#nuget-packages) and publish them to [powershell-core feed][ps-core-feed]. 1. [Create the release tag](#release-tag) and push the tag to `PowerShell/PowerShell` repository. 1. Create the draft and publish the release in Github. -1. Merge the `release` branch to `master` and delete the `release` branch. +1. Merge the `release-` branch to `master` in `powershell/powershell` and delete the `release-` branch. 1. Publish Linux packages to Microsoft YUM/APT repositories. 1. Trigger the release docker builds for Linux and Windows container images. - Linux: push a branch named `docker` to `powershell/powershell` repository to trigger the build at [powershell docker hub](https://hub.docker.com/r/microsoft/powershell/builds/). @@ -80,7 +80,7 @@ The `Start-PSPackage` function delegates to `New-UnixPackage`. It relies on the [Effing Package Management][fpm] project, which makes building packages for any (non-Windows) platform a breeze. Similarly, the PowerShell man-page is generated from the Markdown-like file -[`assets/powershell.1.ronn`][man] using [Ronn][]. +[`assets/pwsh.1.ronn`][man] using [Ronn][]. The function `Start-PSBootstrap -Package` will install both these tools. To modify any property of the packages, edit the `New-UnixPackage` function. @@ -94,7 +94,7 @@ license, category, dependencies, and file layout). To support side-by-side Unix packages, we use the following design: We will maintain a `powershell` package -which owns the `/usr/bin/powershell` symlink, +which owns the `/usr/bin/pwsh` symlink, is the latest version, and is upgradeable. This is the only package named `powershell` and similarly is the only package owning any symlinks, @@ -136,7 +136,7 @@ Without `-Name` specified, the primary `powershell` package will instead be created. [fpm]: https://github.com/jordansissel/fpm -[man]: ../../assets/powershell.1.ronn +[man]: ../../assets/pwsh.1.ronn [ronn]: https://github.com/rtomayko/ronn ### Build and Packaging Examples @@ -173,19 +173,9 @@ Start-PSPackage -Type zip -ReleaseTag v6.0.0-beta.1 -WindowsRuntime 'win7-x64' ## NuGet Packages -In the `release` branch, run `Publish-NuGetFeed` to generate PowerShell NuGet packages: - -```powershell -# Assume the to-be-used release tag is 'v6.0.0-beta.1' -$VersionSuffix = ("v6.0.0-beta.1" -split '-')[-1] - -# Generate NuGet packages -Publish-NuGetFeed -VersionSuffix $VersionSuffix -``` - -PowerShell NuGet packages and the corresponding symbol packages will be generated at `PowerShell/nuget-artifacts` by default. -Currently the NuGet packages published to [powershell-core feed][ps-core-feed] only contain assemblies built for Windows. -Maintainers are working on including the assemblies built for non-Windows platforms. +The NuGet packages for hosting PowerShell for Windows and non-Windows are being built in our release build pipeline. +The assemblies from the individual Windows and Linux builds are consumed and packed into NuGet packages. +These are then released to [powershell-core feed][ps-core-feed]. [ps-core-feed]: https://powershell.myget.org/gallery/powershell-core diff --git a/docs/testing-guidelines/CodeCoverageAnalysis.md b/docs/testing-guidelines/CodeCoverageAnalysis.md index 3766827c575..d9b92440ea4 100644 --- a/docs/testing-guidelines/CodeCoverageAnalysis.md +++ b/docs/testing-guidelines/CodeCoverageAnalysis.md @@ -1,6 +1,6 @@ # Code coverage analysis for commit [2ae5d07](https://codecov.io/gh/PowerShell/PowerShell/tree/c7b959bd6e5356fbbd395f22ba0c6cba49f354f6/src) -Code coverage runs are enabled on daily Windows builds for PowerShell Core 6.0. +Code coverage runs are enabled on daily Windows builds for PowerShell Core 6. The results of the latest build are available at: [CodeCov.io](https://codecov.io/gh/PowerShell/PowerShell) The goal of this analysis is to find the hot spots of missing coverage. diff --git a/docs/testing-guidelines/Images/AppVeyor-Github.png b/docs/testing-guidelines/Images/AppVeyor-Github.png index e467d28accf..4afb37d9a4f 100644 Binary files a/docs/testing-guidelines/Images/AppVeyor-Github.png and b/docs/testing-guidelines/Images/AppVeyor-Github.png differ diff --git a/docs/testing-guidelines/WritingPesterTests.md b/docs/testing-guidelines/WritingPesterTests.md index df0ea928f06..7610653a518 100755 --- a/docs/testing-guidelines/WritingPesterTests.md +++ b/docs/testing-guidelines/WritingPesterTests.md @@ -1,7 +1,11 @@ ### Writing Pester Tests -Note that this document does not replace the documents found in the [Pester](https://github.com/pester/pester "Pester") project. This is just -some quick tips and suggestions for creating Pester tests for this project. The Pester community is vibrant and active, if you have questions -about Pester or creating tests, the [Pester Wiki](https://github.com/pester/pester/wiki) has a lot of great information. +Note that this document does not replace the documents found in the [Pester](https://github.com/pester/pester "Pester") project. +This is just some quick tips and suggestions for creating Pester tests for this project. +The Pester community is vibrant and active, if you have questions about Pester or creating tests, the [Pester Wiki](https://github.com/pester/pester/wiki) has a lot of great information. +As of January 2018, PowerShell Core is using Pester version 4 which has some changes from earlier versions. +See [Migrating from Pester 3 to Pester 4](https://github.com/pester/Pester/wiki/Migrating-from-Pester-3-to-Pester-4) for more information. + + When creating tests, keep the following in mind: * Tests should not be overly complicated and test too many things @@ -16,7 +20,7 @@ Here's the simplest of tests Describe "A variable can be assigned and retrieved" { It "Create a variable and make sure its value is correct" { $a = 1 - $a | Should be 1 + $a | Should Be 1 } } ``` @@ -27,7 +31,7 @@ If you need to do type checking, that can be done as well Describe "One is really one" { It "Compare 1 to 1" { $a = 1 - $a | Should be 1 + $a | Should Be 1 } It "1 is really an int" { $i = 1 @@ -42,7 +46,7 @@ alternatively, you could do the following: Describe "One is really one" { It "Compare 1 to 1" { $a = 1 - $a | Should be 1 + $a | Should Be 1 } It "1 is really an int" { $i = 1 @@ -96,6 +100,12 @@ In the AppVeyor CI, we run two different passes: In each case, tests are executed with appropriate privileges. +Tests that need to be run with sudo **on Unix systems** should be additionally marked with 'RequireSudoOnUnix' Pester tag. +'RequireSudoOnUnix' tag is mutually exclusive to all other tags like 'CI', 'Feature' etc. (which are now ignored when 'RequireSudoOnUnix' is present) and is treated as 'CI'. +Similarly as above, we run the tests in Travis CI in two passes: +- With sudo only tests with 'RequireSudoOnUnix' tag +- Without sudo all tests excluding those with 'RequireSudoOnUnix' tag. + ### Selected Features #### Test Drive @@ -136,7 +146,7 @@ $testCases = @( Describe "A test" { It " -xor should be " -testcase $testcases { param ($a, $b, $ExpectedResult) - $a -xor $b | Should be $ExpectedResult + $a -xor $b | Should Be $ExpectedResult } } ``` @@ -151,7 +161,7 @@ The following example illustrates simple use: Context "Get-Random is not random" { Mock Get-Random { return 3 } It "Get-Random returns 3" { - Get-Random | Should be 3 + Get-Random | Should Be 3 } } ``` diff --git a/docs/testing-guidelines/testing-guidelines.md b/docs/testing-guidelines/testing-guidelines.md index e8c46ad41bf..92072071e94 100755 --- a/docs/testing-guidelines/testing-guidelines.md +++ b/docs/testing-guidelines/testing-guidelines.md @@ -1,10 +1,10 @@ - # Testing Guidelines Testing is a critical and required part of the PowerShell project. The Microsoft PowerShell team created nearly 100,000 tests over the last 12 years which we run as part of the release process for Windows PowerShell. -Having all of those tests available for the initial release of PowerShell was not feasible, and we have targeted those tests which we believe will provide us the ability to catch regressions in the areas which have had the largest changes for PowerShell. +Having all of those tests available for the initial release of PowerShell was not feasible, +and we have targeted those tests which we believe will provide us the ability to catch regressions in the areas which have had the largest changes for PowerShell. It is our intent to continue to release more and more of our tests until we have the coverage we need. For creating new tests, please review the [documents](https://github.com/PowerShell/PowerShell/tree/master/docs/testing-guidelines) on how to create tests for PowerShell. @@ -69,7 +69,8 @@ The Pester framework allows `Describe` blocks to be tagged, and our CI system re One of the following tags must be used: * `CI` - this tag indicates that the tests in the `Describe` block will be executed as part of the CI/PR process -* `Feature` - tests with this tag will not be executed as part of the CI/PR process, but they will be executed on a daily basis as part of a `cron` driven build. They indicate that the test will be validating more behavior, or will be using remote network resources (ex: package management tests) +* `Feature` - tests with this tag will not be executed as part of the CI/PR process, but they will be executed on a daily basis as part of a `cron` driven build. + They indicate that the test will be validating more behavior, or will be using remote network resources (ex: package management tests) * `Scenario` - this tag indicates a larger scale test interacting with multiple areas of functionality and/or remote resources, these tests are also run daily. Additionally, the tag: @@ -78,13 +79,25 @@ Additionally, the tag: #### Requesting additional tests for a PR -In our CI systems, we normally run only run tests tagged with `CI`. If in the first line of the last (most recent) commit description you add `[Feature]`, -we will ensure that we will also run the tests tagged with `Feature`. When you would want to do this: +In our CI systems, we normally run only run tests tagged with `CI`. +If in the first line of the last (most recent) commit description you add `[Feature]`, +we will ensure that we will also run the tests tagged with `Feature`. +When you would want to do this: - You have added or changed a `Feature` test. - A maintainer asks you to run the `Feature` tests. - Based on experience, you are confident that a maintainer will ask you to run the `Feature` tests. +#### Validating packaging changes for a PR + +By default, our CI system does a build and run tests for a PR and does not exercise code to create a package. +If your PR includes changes to packaging, you can have the CI system exercise the packaging code by +using `[Package]` as the first line in the commit message. +When you would want to do this: + +- You made change to PowerShell Core packaging +- A maintainer asks you to run as `[Package]` + ### xUnit For those tests which are not easily run via Pester, we have decided to use [xUnit](https://xunit.github.io/) as the test framework. @@ -93,38 +106,35 @@ Currently, we have a minuscule number of tests which are run by using xUnit. ## Running tests outside of CI When working on new features or fixes, it is natural to want to run those tests locally before making a PR. -Two helper functions are part of the build.psm1 module to help with that: +Three helper functions are part of the build.psm1 module to help with that: +* `Restore-PSPester` will restore Pester, which is needed to run `Start-PSPester` * `Start-PSPester` will execute all Pester tests which are run by the CI system * `Start-PSxUnit` will execute the available xUnit tests run by the CI system Our CI system runs these as well; there should be no difference between running these on your dev system, versus in CI. -Make sure that the git submodules have been loaded into your project before running `Start-PSPester`, or it will fail to run. If you did not clone the project with the `--recursive` flag, you can load the submodules by running: - -``` -git submodule update --init -``` +Make sure that you run `Restore-PSPester` before running `Start-PSPester`, or it will fail to run. When running tests in this way, be sure that you have started PowerShell with `-noprofile` as some tests will fail if the environment is not the default or has any customization. For example, to run all the Pester tests for CI (assuming you are at the root of the PowerShell repo): -``` +```PowerShell Import-Module ./build.psm1 Start-PSPester ``` If you wish to run specific tests, that is possible as well: -``` +```PowerShell Start-PSPester -Path test/powershell/engine/Api ``` Or a specific Pester test file: -``` +```PowerShell Start-PSPester -Path test/powershell/engine/Api/XmlAdapter.Tests.ps1 ``` @@ -135,8 +145,6 @@ in Microsoft's internal test frameworks. The tests that you created for your change and the library of historical tests will be run to determine if any regressions are present. If these tests find regressions, you'll be notified that your PR is not ready, and provided with enough information to investigate why the failure happened. - - ## Test Layout We have taken a functional approach to the layout of our Pester tests and you should place new tests in their appropriate location. diff --git a/global.json b/global.json new file mode 100644 index 00000000000..815be4bfb90 --- /dev/null +++ b/global.json @@ -0,0 +1,5 @@ +{ + "sdk": { + "version": "2.1.4" + } +} diff --git a/license_thirdparty_proprietary.txt b/license_thirdparty_proprietary.txt index 86d445c8930..911a40b8dcd 100644 --- a/license_thirdparty_proprietary.txt +++ b/license_thirdparty_proprietary.txt @@ -1,69 +1,69 @@ PowerShell 6.0 -Copyright (c) Microsoft Corporation -All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. +All rights reserved. MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this -software and associated documentation files (the "Software"), to deal in the Software -without restriction, including without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to the following +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all copies +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF -CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -IMPORTANT NOTICE: THE SOFTWARE ALSO CONTAINS THIRD PARTY AND OTHER -PROPRIETARY SOFTWARE THAT ARE GOVERNED BY SEPARATE LICENSE TERMS. BY ACCEPTING -THE LICENSE TERMS ABOVE, YOU ALSO ACCEPT THE LICENSE TERMS GOVERNING THE +IMPORTANT NOTICE: THE SOFTWARE ALSO CONTAINS THIRD PARTY AND OTHER +PROPRIETARY SOFTWARE THAT ARE GOVERNED BY SEPARATE LICENSE TERMS. BY ACCEPTING +THE LICENSE TERMS ABOVE, YOU ALSO ACCEPT THE LICENSE TERMS GOVERNING THE THIRD PARTY AND OTHER SOFTWARE, WHICH ARE SET FORTH BELOW: -The following components listed are governed by the license terms that follow the -component(s) name: +The following components listed are governed by the license terms that follow the +component(s) name: ------------------------------------------------------ Libmi.so ------------------------------------------------------ -Copyright (c) Microsoft Corporation -All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. +All rights reserved. MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this -software and associated documentation files (the "Software"), to deal in the Software -without restriction, including without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to the following +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all copies +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF -CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -The following components are governed by the MIT license, a copy of which appears -below the list of components: +The following components are governed by the MIT license, a copy of which appears +below the list of components: ------------------------------------------------------ Newtonsoft.Json ------------------------------------------------------ Copyright (c) 2007 James Newton-King -All rights reserved. +All rights reserved. MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this -software and associated documentation files (the "Software"), to deal in the Software -without restriction, including without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to the following +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all copies +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF -CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- Libuv v.1.9.0 @@ -71,7 +71,7 @@ Libuv v.1.9.0 https://raw.githubusercontent.com/aspnet/libuv-package/dev/content/License.txt -This software is licensed to you by Microsoft Corporation under the original terms of +This software is licensed to you by Microsoft Corporation under the original terms of the copyright holder provided below: ========================================= @@ -111,7 +111,7 @@ The externally maintained libraries used by libuv are: - tree.h (from FreeBSD), copyright Niels Provos. Two clause BSD license. - inet_pton and inet_ntop implementations, contained in src/inet.c, are -copyright the Internet Systems Consortium, Inc., and licensed under the ISC +copyright the Internet Systems Consortium, Inc., and licensed under the ISC license. - stdint-msvc2008.h (from msinttypes), copyright Alexander Chemeris. Three @@ -120,7 +120,7 @@ license. - pthread-fixes.h, pthread-fixes.c, copyright Google Inc. and Sony Mobile Communications AB. Three clause BSD license. - - android-ifaddrs.h, android-ifaddrs.c, copyright Berkeley Software Design Inc, + - android-ifaddrs.h, android-ifaddrs.c, copyright Berkeley Software Design Inc, Kenneth MacKay and Emergya (Cloud4all, FP7/2007-2013, grant agreement n° 289016). Three clause BSD license. @@ -414,135 +414,135 @@ limitations under the License. • System.Xml.XPath.XmlDocument ------------------------------------------------------- -MICROSOFT SOFTWARE LICENSE TERMS -MICROSOFT .NET LIBRARY -These license terms are an agreement between Microsoft Corporation (or based on where you -live, one of its affiliates) and you. Please read them. They apply to the software named above, -which includes the media on which you received it, if any. The terms also apply to any Microsoft -• updates, -• supplements, -• Internet-based services, and -• support services -for this software, unless other terms accompany those items. If so, those terms apply. -BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS. IF YOU DO NOT ACCEPT THEM, DO NOT -USE THE SOFTWARE. -IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE PERPETUAL RIGHTS BELOW. -1. INSTALLATION AND USE RIGHTS. -a. Installation and Use. You may install and use any number of copies of the software to design, -develop and test your programs. -b. Third Party Programs. The software may include third party programs that Microsoft, not the -third party, licenses to you under this agreement. Notices, if any, for the third party program are -included for your information only. -2. DATA. The software may collect information about you and your use of the software, and send that -to Microsoft. Microsoft may use this information to improve our products and services. You can learn -more about data collection and use in the help documentation and the privacy statement -at https://go.microsoft.com/fwlink/?LinkId=528096 . Your use of the software operates as your -consent to these practices. -3. ADDITIONAL LICENSING REQUIREMENTS AND/OR USE RIGHTS. -a. DISTRIBUTABLE CODE. The software is comprised of Distributable Code. “Distributable -Code†is code that you are permitted to distribute in programs you develop if you comply with -the terms below. -i . Right to Use and Distribute. -• You may copy and distribute the object code form of the software. -• Third Party Distribution. You may permit distributors of your programs to copy and -distribute the Distributable Code as part of those programs. -ii. Distribution Requirements. For any Distributable Code you distribute, you must -• add significant primary functionality to it in your programs; -• require distributors and external end users to agree to terms that protect it at least as -much as this agreement; -• display your valid copyright notice on your programs; and -• indemnify, defend, and hold harmless Microsoft from any claims, including attorneys’ -fees, related to the distribution or use of your programs. -iii. Distribution Restrictions. You may not -• alter any copyright, trademark or patent notice in the Distributable Code; -• use Microsoft’s trademarks in your programs’ names or in a way that suggests your -programs come from or are endorsed by Microsoft; -• include Distributable Code in malicious, deceptive or unlawful programs; or -• modify or distribute the source code of any Distributable Code so that any part of it -becomes subject to an Excluded License. An Excluded License is one that requires, as a -condition of use, modification or distribution, that -• the code be disclosed or distributed in source code form; or -• others have the right to modify it. -4. SCOPE OF LICENSE. The software is licensed, not sold. This agreement only gives you some rights to -use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite -this limitation, you may use the software only as expressly permitted in this agreement. In doing so, you -must comply with any technical limitations in the software that only allow you to use it in certain ways. -You may not -• work around any technical limitations in the software; -• reverse engineer, decompile or disassemble the software, except and only to the extent that -applicable law expressly permits, despite this limitation; -• publish the software for others to copy; -• rent, lease or lend the software; -• transfer the software or this agreement to any third party; or -• use the software for commercial software hosting services. -5. BACKUP COPY. You may make one backup copy of the software. You may use it only to reinstall the -software. -6. DOCUMENTATION. Any person that has valid access to your computer or internal network may copy -and use the documentation for your internal, reference purposes. -7. EXPORT RESTRICTIONS. The software is subject to United States export laws and regulations. You -must comply with all domestic and international export laws and regulations that apply to the software. -These laws include restrictions on destinations, end users and end use. For additional information, -see www.microsoft.com/exporting. -8. SUPPORT SERVICES. Because this software is “as is,†we may not provide support services for it. -9. ENTIRE AGREEMENT. This agreement, and the terms for supplements, updates, Internet-based -services and support services that you use, are the entire agreement for the software and support -services. -10. APPLICABLE LAW. -a. United States. If you acquired the software in the United States, Washington state law governs the -interpretation of this agreement and applies to claims for breach of it, regardless of conflict of laws -principles. The laws of the state where you live govern all other claims, including claims under state -consumer protection laws, unfair competition laws, and in tort. -b. Outside the United States. If you acquired the software in any other country, the laws of -that country apply. -11. LEGAL EFFECT. This agreement describes certain legal rights. You may have other rights under the -laws of your country. You may also have rights with respect to the party from whom you acquired the -software. This agreement does not change your rights under the laws of your country if the laws of your -country do not permit it to do so. -12. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS-IS.†YOU BEAR THE RISK OF -USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. -YOU MAY HAVE ADDITIONAL CONSUMER RIGHTS OR STATUTORY GUARANTEES UNDER YOUR -LOCAL LAWS WHICH THIS AGREEMENT CANNOT CHANGE. TO THE EXTENT PERMITTED -UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. -FOR AUSTRALIA – YOU HAVE STATUTORY GUARANTEES UNDER THE AUSTRALIAN CONSUMER -LAW AND NOTHING IN THESE TERMS IS INTENDED TO AFFECT THOSE RIGHTS. -13. LIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES. YOU CAN RECOVER FROM -MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT -RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, -INDIRECT OR INCIDENTAL DAMAGES. -This limitation applies to -• anything related to the software, services, content (including code) on third party Internet sites, or -third party programs; and -• claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, -or other tort to the extent permitted by applicable law. -It also applies even if Microsoft knew or should have known about the possibility of the damages. The above -limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of -incidental, consequential or other damages. -Please note: As this software is distributed in Quebec, Canada, some of the clauses in this agreement are -provided below in French. -Remarque : Ce logiciel étant distribué au Québec, Canada, certaines des clauses dans ce contrat sont fournies -ci-dessous en français. -EXONÉRATION DE GARANTIE. Le logiciel visé par une licence est offert « tel quel ». Toute utilisation de ce -logiciel est à votre seule risque et péril. Microsoft n’accorde aucune autre garantie expresse. Vous pouvez -bénéficier de droits additionnels en vertu du droit local sur la protection des consommateurs, que ce contrat ne -peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualité marchande, -d’adéquation à un usage particulier et d’absence de contrefaçon sont exclues. -LIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES -DOMMAGES. Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de -dommages directs uniquement à hauteur de 5,00 $ US. Vous ne pouvez prétendre à aucune indemnisation -pour les autres dommages, y compris les dommages spéciaux, indirects ou accessoires et pertes de bénéfices. -Cette limitationconcerne: -• tout ce qui est relié au logiciel, aux services ou au contenu (y compris le code) figurant sur des -sites Internet tiers ou dans des programmes tiers ; et -• les réclamations au titre de violation de contrat ou de garantie, ou au titre de responsabilité -stricte, de négligence ou d’une autre faute dans la limite autorisée par la loi en vigueur. -Elle s’applique également, même si Microsoft connaissait ou devrait connaître l’éventualité d’un tel dommage. -Si votre pays n’autorise pas l’exclusion ou la limitation de responsabilité pour les dommages indirects, -accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l’exclusion ci-dessus ne -s’appliquera pas à votre égard. -EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous pourriez avoir d’autres droits -prévus par les lois de votre pays. Le présent contrat ne modifie pas les droits que vous confèrent les lois de -votre pays si celles-ci ne le permettent pas. +MICROSOFT SOFTWARE LICENSE TERMS +MICROSOFT .NET LIBRARY +These license terms are an agreement between Microsoft Corporation (or based on where you +live, one of its affiliates) and you. Please read them. They apply to the software named above, +which includes the media on which you received it, if any. The terms also apply to any Microsoft +• updates, +• supplements, +• Internet-based services, and +• support services +for this software, unless other terms accompany those items. If so, those terms apply. +BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS. IF YOU DO NOT ACCEPT THEM, DO NOT +USE THE SOFTWARE. +IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE PERPETUAL RIGHTS BELOW. +1. INSTALLATION AND USE RIGHTS. +a. Installation and Use. You may install and use any number of copies of the software to design, +develop and test your programs. +b. Third Party Programs. The software may include third party programs that Microsoft, not the +third party, licenses to you under this agreement. Notices, if any, for the third party program are +included for your information only. +2. DATA. The software may collect information about you and your use of the software, and send that +to Microsoft. Microsoft may use this information to improve our products and services. You can learn +more about data collection and use in the help documentation and the privacy statement +at https://go.microsoft.com/fwlink/?LinkId=528096 . Your use of the software operates as your +consent to these practices. +3. ADDITIONAL LICENSING REQUIREMENTS AND/OR USE RIGHTS. +a. DISTRIBUTABLE CODE. The software is comprised of Distributable Code. “Distributable +Code†is code that you are permitted to distribute in programs you develop if you comply with +the terms below. +i . Right to Use and Distribute. +• You may copy and distribute the object code form of the software. +• Third Party Distribution. You may permit distributors of your programs to copy and +distribute the Distributable Code as part of those programs. +ii. Distribution Requirements. For any Distributable Code you distribute, you must +• add significant primary functionality to it in your programs; +• require distributors and external end users to agree to terms that protect it at least as +much as this agreement; +• display your valid copyright notice on your programs; and +• indemnify, defend, and hold harmless Microsoft from any claims, including attorneys’ +fees, related to the distribution or use of your programs. +iii. Distribution Restrictions. You may not +• alter any copyright, trademark or patent notice in the Distributable Code; +• use Microsoft’s trademarks in your programs’ names or in a way that suggests your +programs come from or are endorsed by Microsoft; +• include Distributable Code in malicious, deceptive or unlawful programs; or +• modify or distribute the source code of any Distributable Code so that any part of it +becomes subject to an Excluded License. An Excluded License is one that requires, as a +condition of use, modification or distribution, that +• the code be disclosed or distributed in source code form; or +• others have the right to modify it. +4. SCOPE OF LICENSE. The software is licensed, not sold. This agreement only gives you some rights to +use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite +this limitation, you may use the software only as expressly permitted in this agreement. In doing so, you +must comply with any technical limitations in the software that only allow you to use it in certain ways. +You may not +• work around any technical limitations in the software; +• reverse engineer, decompile or disassemble the software, except and only to the extent that +applicable law expressly permits, despite this limitation; +• publish the software for others to copy; +• rent, lease or lend the software; +• transfer the software or this agreement to any third party; or +• use the software for commercial software hosting services. +5. BACKUP COPY. You may make one backup copy of the software. You may use it only to reinstall the +software. +6. DOCUMENTATION. Any person that has valid access to your computer or internal network may copy +and use the documentation for your internal, reference purposes. +7. EXPORT RESTRICTIONS. The software is subject to United States export laws and regulations. You +must comply with all domestic and international export laws and regulations that apply to the software. +These laws include restrictions on destinations, end users and end use. For additional information, +see www.microsoft.com/exporting. +8. SUPPORT SERVICES. Because this software is “as is,†we may not provide support services for it. +9. ENTIRE AGREEMENT. This agreement, and the terms for supplements, updates, Internet-based +services and support services that you use, are the entire agreement for the software and support +services. +10. APPLICABLE LAW. +a. United States. If you acquired the software in the United States, Washington state law governs the +interpretation of this agreement and applies to claims for breach of it, regardless of conflict of laws +principles. The laws of the state where you live govern all other claims, including claims under state +consumer protection laws, unfair competition laws, and in tort. +b. Outside the United States. If you acquired the software in any other country, the laws of +that country apply. +11. LEGAL EFFECT. This agreement describes certain legal rights. You may have other rights under the +laws of your country. You may also have rights with respect to the party from whom you acquired the +software. This agreement does not change your rights under the laws of your country if the laws of your +country do not permit it to do so. +12. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS-IS.†YOU BEAR THE RISK OF +USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. +YOU MAY HAVE ADDITIONAL CONSUMER RIGHTS OR STATUTORY GUARANTEES UNDER YOUR +LOCAL LAWS WHICH THIS AGREEMENT CANNOT CHANGE. TO THE EXTENT PERMITTED +UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +FOR AUSTRALIA – YOU HAVE STATUTORY GUARANTEES UNDER THE AUSTRALIAN CONSUMER +LAW AND NOTHING IN THESE TERMS IS INTENDED TO AFFECT THOSE RIGHTS. +13. LIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES. YOU CAN RECOVER FROM +MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT +RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, +INDIRECT OR INCIDENTAL DAMAGES. +This limitation applies to +• anything related to the software, services, content (including code) on third party Internet sites, or +third party programs; and +• claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, +or other tort to the extent permitted by applicable law. +It also applies even if Microsoft knew or should have known about the possibility of the damages. The above +limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of +incidental, consequential or other damages. +Please note: As this software is distributed in Quebec, Canada, some of the clauses in this agreement are +provided below in French. +Remarque : Ce logiciel étant distribué au Québec, Canada, certaines des clauses dans ce contrat sont fournies +ci-dessous en français. +EXONÉRATION DE GARANTIE. Le logiciel visé par une licence est offert « tel quel ». Toute utilisation de ce +logiciel est à votre seule risque et péril. Microsoft n’accorde aucune autre garantie expresse. Vous pouvez +bénéficier de droits additionnels en vertu du droit local sur la protection des consommateurs, que ce contrat ne +peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualité marchande, +d’adéquation à un usage particulier et d’absence de contrefaçon sont exclues. +LIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES +DOMMAGES. Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de +dommages directs uniquement à hauteur de 5,00 $ US. Vous ne pouvez prétendre à aucune indemnisation +pour les autres dommages, y compris les dommages spéciaux, indirects ou accessoires et pertes de bénéfices. +Cette limitationconcerne: +• tout ce qui est relié au logiciel, aux services ou au contenu (y compris le code) figurant sur des +sites Internet tiers ou dans des programmes tiers ; et +• les réclamations au titre de violation de contrat ou de garantie, ou au titre de responsabilité +stricte, de négligence ou d’une autre faute dans la limite autorisée par la loi en vigueur. +Elle s’applique également, même si Microsoft connaissait ou devrait connaître l’éventualité d’un tel dommage. +Si votre pays n’autorise pas l’exclusion ou la limitation de responsabilité pour les dommages indirects, +accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l’exclusion ci-dessus ne +s’appliquera pas à votre égard. +EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous pourriez avoir d’autres droits +prévus par les lois de votre pays. Le présent contrat ne modifie pas les droits que vous confèrent les lois de +votre pays si celles-ci ne le permettent pas. -------------------------------------------------------- @@ -582,165 +582,165 @@ specific language governing permissions and limitations under the License. • Microsoft.Management.Infrastructure.Unmanaged.dll ---------------------------------------------------------- MICROSOFT SOFTWARE LICENSE TERMS -MANAGEMENT.INFRASTRUCTURE.DLL -MANAGEMENT.INFRASTRUCTURE.NATIVE.DLL +MANAGEMENT.INFRASTRUCTURE.DLL +MANAGEMENT.INFRASTRUCTURE.NATIVE.DLL MANAGEMENT.INFRASTRUCTURE.UNMANAGED.DLL - -These license terms are an agreement between you and Microsoft Corporation (or one of its affiliates). They -apply to the software named above and any Microsoft services or software updates (except to the extent such -services or updates are accompanied by new or additional terms, in which case those different terms apply -prospectively and do not alter your or Microsoft’s rights relating to pre-updated software or services). IF YOU -COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW. BY USING THE SOFTWARE, YOU + +These license terms are an agreement between you and Microsoft Corporation (or one of its affiliates). They +apply to the software named above and any Microsoft services or software updates (except to the extent such +services or updates are accompanied by new or additional terms, in which case those different terms apply +prospectively and do not alter your or Microsoft’s rights relating to pre-updated software or services). IF YOU +COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW. BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS. 1. INSTALLATION AND USE RIGHTS a) General. You may install and use any number of copies of the software on your devices. -b) Included Microsoft Applications. The software may include other Microsoft applications. These -license terms apply to those included applications, if any, unless other license terms are provided with +b) Included Microsoft Applications. The software may include other Microsoft applications. These +license terms apply to those included applications, if any, unless other license terms are provided with the other Microsoft applications. -c) Third Party Software. The software may include third party applications that are licensed to you -under this agreement or under their own terms. License terms, notices, and acknowledgements, if any, -for the third party applications may be accessible online at http://aka.ms/thirdpartynotices or in an -accompanying notices file. Even if such applications are governed by other agreements, the disclaimer, +c) Third Party Software. The software may include third party applications that are licensed to you +under this agreement or under their own terms. License terms, notices, and acknowledgements, if any, +for the third party applications may be accessible online at http://aka.ms/thirdpartynotices or in an +accompanying notices file. Even if such applications are governed by other agreements, the disclaimer, limitations on, and exclusions of damages below also apply to the extent allowed by applicable law. 2. TIME-SENSITIVE SOFTWARE a) Period. The software is time-sensitive and may stop running on a date that is defined in the software. b) Notice. You may receive periodic reminder notices of this date through the software. c) Access to data. You may not be able to access data used in the software when it stops running. -3. PRE-RELEASE SOFTWARE. The software is a pre-release version. It may not operate correctly. It may be +3. PRE-RELEASE SOFTWARE. The software is a pre-release version. It may not operate correctly. It may be different from the commercially released version. -4. FEEDBACK. If you give feedback about the software to Microsoft, you give to Microsoft, without charge, -the right to use, share and commercialize your feedback in any way and for any purpose. You will not give -feedback that is subject to a license that requires Microsoft to license its software or documentation to +4. FEEDBACK. If you give feedback about the software to Microsoft, you give to Microsoft, without charge, +the right to use, share and commercialize your feedback in any way and for any purpose. You will not give +feedback that is subject to a license that requires Microsoft to license its software or documentation to third parties because Microsoft includes your feedback in them. These rights survive this agreement. -5. DATA COLLECTION. The software may collect information about you and your use of the software and -send that to Microsoft. Microsoft may use this information to provide services and improve Microsoft’s -products and services. Your opt-out rights, if any, are described in the product documentation. Some -features in the software may enable collection of data from users of your applications that access or use the -software. If you use these features to enable data collection in your applications, you must comply with -applicable law, including getting any required user consent, and maintain a prominent privacy policy that -accurately informs users about how you use, collect, and share their data. You can learn more about -Microsoft’s data collection and use in the product documentation and the Microsoft Privacy Statement at -https://go.microsoft.com/fwlink/?LinkId=521839. You agree to comply with all applicable provisions of the +5. DATA COLLECTION. The software may collect information about you and your use of the software and +send that to Microsoft. Microsoft may use this information to provide services and improve Microsoft’s +products and services. Your opt-out rights, if any, are described in the product documentation. Some +features in the software may enable collection of data from users of your applications that access or use the +software. If you use these features to enable data collection in your applications, you must comply with +applicable law, including getting any required user consent, and maintain a prominent privacy policy that +accurately informs users about how you use, collect, and share their data. You can learn more about +Microsoft’s data collection and use in the product documentation and the Microsoft Privacy Statement at +https://go.microsoft.com/fwlink/?LinkId=521839. You agree to comply with all applicable provisions of the Microsoft Privacy Statement. -6. FONTS. While the software is running, you may use its fonts to display and print content. You may only (i) -embed fonts in content as permitted by the embedding restrictions in the fonts; and (ii) temporarily +6. FONTS. While the software is running, you may use its fonts to display and print content. You may only (i) +embed fonts in content as permitted by the embedding restrictions in the fonts; and (ii) temporarily download them to a printer or other output device to help print content. -7. SCOPE OF LICENSE. The software is licensed, not sold. Microsoft reserves all other rights. Unless applicable +7. SCOPE OF LICENSE. The software is licensed, not sold. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you will not (and have no right to): a) work around any technical limitations in the software that only allow you to use it in certain ways; b) reverse engineer, decompile or disassemble the software; c) remove, minimize, block, or modify any notices of Microsoft or its suppliers in the software; d) use the software in any way that is against the law or to create or propagate malware; or -e) share, publish, distribute, or lend the software, provide the software as a stand-alone hosted solution +e) share, publish, distribute, or lend the software, provide the software as a stand-alone hosted solution for others to use, or transfer the software or this agreement to any third party. -8. EXPORT RESTRICTIONS. You must comply with all domestic and international export laws and regulations -that apply to the software, which include restrictions on destinations, end users, and end use. For further +8. EXPORT RESTRICTIONS. You must comply with all domestic and international export laws and regulations +that apply to the software, which include restrictions on destinations, end users, and end use. For further information on export restrictions, visit http://aka.ms/exporting. -9. SUPPORT SERVICES. Microsoft is not obligated under this agreement to provide any support services for +9. SUPPORT SERVICES. Microsoft is not obligated under this agreement to provide any support services for the software. Any support provided is “as isâ€, “with all faultsâ€, and without warranty of any kind. -10. UPDATES. The software may periodically check for updates, and download and install them for you. You -may obtain updates only from Microsoft or authorized sources. Microsoft may need to update your system -to provide you with updates. You agree to receive these automatic updates without any additional notice. +10. UPDATES. The software may periodically check for updates, and download and install them for you. You +may obtain updates only from Microsoft or authorized sources. Microsoft may need to update your system +to provide you with updates. You agree to receive these automatic updates without any additional notice. Updates may not include or support all existing software features, services, or peripheral devices. -11. ENTIRE AGREEMENT. This agreement, and any other terms Microsoft may provide for supplements, +11. ENTIRE AGREEMENT. This agreement, and any other terms Microsoft may provide for supplements, updates, or third-party applications, is the entire agreement for the software. -12. APPLICABLE LAW AND PLACE TO RESOLVE DISPUTES. If you acquired the software in the United States -or Canada, the laws of the state or province where you live (or, if a business, where your principal place of -business is located) govern the interpretation of this agreement, claims for its breach, and all other claims -(including consumer protection, unfair competition, and tort claims), regardless of conflict of laws -principles. If you acquired the software in any other country, its laws apply. If U.S. federal jurisdiction exists, -you and Microsoft consent to exclusive jurisdiction and venue in the federal court in King County, -Washington for all disputes heard in court. If not, you and Microsoft consent to exclusive jurisdiction and +12. APPLICABLE LAW AND PLACE TO RESOLVE DISPUTES. If you acquired the software in the United States +or Canada, the laws of the state or province where you live (or, if a business, where your principal place of +business is located) govern the interpretation of this agreement, claims for its breach, and all other claims +(including consumer protection, unfair competition, and tort claims), regardless of conflict of laws +principles. If you acquired the software in any other country, its laws apply. If U.S. federal jurisdiction exists, +you and Microsoft consent to exclusive jurisdiction and venue in the federal court in King County, +Washington for all disputes heard in court. If not, you and Microsoft consent to exclusive jurisdiction and venue in the Superior Court of King County, Washington for all disputes heard in court. -13. CONSUMER RIGHTS; REGIONAL VARIATIONS. This agreement describes certain legal rights. You may -have other rights, including consumer rights, under the laws of your state, province, or country. Separate -and apart from your relationship with Microsoft, you may also have rights with respect to the party from -which you acquired the software. This agreement does not change those other rights if the laws of your -state, province, or country do not permit it to do so. For example, if you acquired the software in one of the +13. CONSUMER RIGHTS; REGIONAL VARIATIONS. This agreement describes certain legal rights. You may +have other rights, including consumer rights, under the laws of your state, province, or country. Separate +and apart from your relationship with Microsoft, you may also have rights with respect to the party from +which you acquired the software. This agreement does not change those other rights if the laws of your +state, province, or country do not permit it to do so. For example, if you acquired the software in one of the below regions, or mandatory country law applies, then the following provisions apply to you: -a) Australia. You have statutory guarantees under the Australian Consumer Law and nothing in this +a) Australia. You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is intended to affect those rights. -b) Canada. If you acquired this software in Canada, you may stop receiving updates by turning off the -automatic update feature, disconnecting your device from the Internet (if and when you re-connect to -the Internet, however, the software will resume checking for and installing updates), or uninstalling the -software. The product documentation, if any, may also specify how to turn off updates for your specific +b) Canada. If you acquired this software in Canada, you may stop receiving updates by turning off the +automatic update feature, disconnecting your device from the Internet (if and when you re-connect to +the Internet, however, the software will resume checking for and installing updates), or uninstalling the +software. The product documentation, if any, may also specify how to turn off updates for your specific device or software. c) Germany and Austria. -i. Warranty. The properly licensed software will perform substantially as described in -any Microsoft materials that accompany the software. However, Microsoft gives no +i. Warranty. The properly licensed software will perform substantially as described in +any Microsoft materials that accompany the software. However, Microsoft gives no contractual guarantee in relation to the licensed software. -ii. Limitation of Liability. In case of intentional conduct, gross negligence, claims based -on the Product Liability Act, as well as, in case of death or personal or physical injury, +ii. Limitation of Liability. In case of intentional conduct, gross negligence, claims based +on the Product Liability Act, as well as, in case of death or personal or physical injury, Microsoft is liable according to the statutory law. -Subject to the foregoing clause ii., Microsoft will only be liable for slight negligence if Microsoft is in -breach of such material contractual obligations, the fulfillment of which facilitate the due performance -of this agreement, the breach of which would endanger the purpose of this agreement and the -compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases +Subject to the foregoing clause ii., Microsoft will only be liable for slight negligence if Microsoft is in +breach of such material contractual obligations, the fulfillment of which facilitate the due performance +of this agreement, the breach of which would endanger the purpose of this agreement and the +compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence. -14. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS IS.†YOU BEAR THE RISK OF USING -IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES, OR CONDITIONS. TO THE EXTENT -PERMITTED UNDER APPLICABLE LAWS, MICROSOFT EXCLUDES ALL IMPLIED WARRANTIES, +14. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS IS.†YOU BEAR THE RISK OF USING +IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES, OR CONDITIONS. TO THE EXTENT +PERMITTED UNDER APPLICABLE LAWS, MICROSOFT EXCLUDES ALL IMPLIED WARRANTIES, INCLUDING MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. -15. LIMITATION ON AND EXCLUSION OF DAMAGES. IF YOU HAVE ANY BASIS FOR RECOVERING -DAMAGES DESPITE THE PRECEDING DISCLAIMER OF WARRANTY, YOU CAN RECOVER FROM -MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER -ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR +15. LIMITATION ON AND EXCLUSION OF DAMAGES. IF YOU HAVE ANY BASIS FOR RECOVERING +DAMAGES DESPITE THE PRECEDING DISCLAIMER OF WARRANTY, YOU CAN RECOVER FROM +MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER +ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES. -This limitation applies to (a) anything related to the software, services, content (including code) on -third party Internet sites, or third party applications; and (b) claims for breach of contract, warranty, -guarantee, or condition; strict liability, negligence, or other tort; or any other claim; in each case to +This limitation applies to (a) anything related to the software, services, content (including code) on +third party Internet sites, or third party applications; and (b) claims for breach of contract, warranty, +guarantee, or condition; strict liability, negligence, or other tort; or any other claim; in each case to the extent permitted by applicable law. -It also applies even if Microsoft knew or should have known about the possibility of the damages. -The above limitation or exclusion may not apply to you because your state, province, or country +It also applies even if Microsoft knew or should have known about the possibility of the damages. +The above limitation or exclusion may not apply to you because your state, province, or country may not allow the exclusion or limitation of incidental, consequential, or other damages. -Please note: As this software is distributed in Canada, some of the clauses in this agreement are +Please note: As this software is distributed in Canada, some of the clauses in this agreement are provided below in French. Remarque: Ce logiciel étant distribué au Canada, certaines des clauses dans ce contrat sont fournies ci- dessous en français. -EXONÉRATION DE GARANTIE. Le logiciel visé par une licence est offert « tel quel ». Toute utilisation de -ce logiciel est à votre seule risque et péril. Microsoft n’accorde aucune autre garantie expresse. Vous -pouvez bénéficier de droits additionnels en vertu du droit local sur la protection des consommateurs, -que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de +EXONÉRATION DE GARANTIE. Le logiciel visé par une licence est offert « tel quel ». Toute utilisation de +ce logiciel est à votre seule risque et péril. Microsoft n’accorde aucune autre garantie expresse. Vous +pouvez bénéficier de droits additionnels en vertu du droit local sur la protection des consommateurs, +que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualité marchande, d’adéquation à un usage particulier et d’absence de contrefaçon sont exclues. -LIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES DOMMAGES. -Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de dommages directs -uniquement à hauteur de 5,00 $ US. Vous ne pouvez prétendre à aucune indemnisation pour les autres +LIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES DOMMAGES. +Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de dommages directs +uniquement à hauteur de 5,00 $ US. Vous ne pouvez prétendre à aucune indemnisation pour les autres dommages, y compris les dommages spéciaux, indirects ou accessoires et pertes de bénéfices. Cette limitation concerne: -• tout ce qui est relié au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites +• tout ce qui est relié au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers; et -• les réclamations au titre de violation de contrat ou de garantie, ou au titre de responsabilité stricte, +• les réclamations au titre de violation de contrat ou de garantie, ou au titre de responsabilité stricte, de négligence ou d’une autre faute dans la limite autorisée par la loi en vigueur. -Elle s’applique également, même si Microsoft connaissait ou devrait connaître l’éventualité d’un tel -dommage. Si votre pays n’autorise pas l’exclusion ou la limitation de responsabilité pour les dommages +Elle s’applique également, même si Microsoft connaissait ou devrait connaître l’éventualité d’un tel +dommage. Si votre pays n’autorise pas l’exclusion ou la limitation de responsabilité pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l’exclusion ci- dessus ne s’appliquera pas à votre égard. -EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous pourriez avoir d’autres droits -prévus par les lois de votre pays. Le présent contrat ne modifie pas les droits que vous confèrent les lois +EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous pourriez avoir d’autres droits +prévus par les lois de votre pays. Le présent contrat ne modifie pas les droits que vous confèrent les lois de votre pays si celles-ci ne le permettent pas. -The following components are governed by the MIT license, a copy of which appears -below the list of components: +The following components are governed by the MIT license, a copy of which appears +below the list of components: ------------------------------------------------------ tools/appimage.sh ------------------------------------------------------ Copyright (c) 2016 Simon Peter -All rights reserved. +All rights reserved. MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this -software and associated documentation files (the "Software"), to deal in the Software -without restriction, including without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to the following +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all copies +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF -CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------- DotNet/CoreFX diff --git a/nuget.config b/nuget.config index ca674f6c218..74cb0168d2f 100644 --- a/nuget.config +++ b/nuget.config @@ -5,5 +5,6 @@ + diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/AssemblyInfo.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/AssemblyInfo.cs index 92e660ae73c..eeb950a6394 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/AssemblyInfo.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/AssemblyInfo.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Diagnostics; using System.Reflection; diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimAsyncOperation.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimAsyncOperation.cs index 4cb2c7ab200..8e575e235a9 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimAsyncOperation.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimAsyncOperation.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimBaseAction.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimBaseAction.cs index 829152def7b..fad68f72b47 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimBaseAction.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimBaseAction.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimCmdletModuleInitialize.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimCmdletModuleInitialize.cs index b8138e87682..b496a963d93 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimCmdletModuleInitialize.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimCmdletModuleInitialize.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimCommandBase.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimCommandBase.cs index 2f545311bc2..b3fb43ba926 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimCommandBase.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimCommandBase.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives using System; @@ -804,7 +802,6 @@ internal void ThrowTerminatingError(Exception exception, string operation) ///
internal const string ClassNameSessionSet = "ClassNameSessionSet"; - /// /// resource Uri session set name /// diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimGetAssociatedInstance.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimGetAssociatedInstance.cs index b21e8304ace..524f1c928ad 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimGetAssociatedInstance.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimGetAssociatedInstance.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimGetCimClass.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimGetCimClass.cs index 2fec594ad3a..61a1fbcdd02 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimGetCimClass.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimGetCimClass.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimGetInstance.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimGetInstance.cs index 562bce3b626..41b6434ad0f 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimGetInstance.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimGetInstance.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimIndicationWatcher.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimIndicationWatcher.cs index 2d33fc3cfd4..c32c1f3a7b5 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimIndicationWatcher.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimIndicationWatcher.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimInvokeCimMethod.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimInvokeCimMethod.cs index 63c8bafbe01..33e7e1e9fc0 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimInvokeCimMethod.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimInvokeCimMethod.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimNewCimInstance.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimNewCimInstance.cs index c56e604d903..7543e21a184 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimNewCimInstance.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimNewCimInstance.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimPromptUser.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimPromptUser.cs index 709e0690a11..d8a49bd9857 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimPromptUser.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimPromptUser.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives using Microsoft.Management.Infrastructure.Options; diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimRegisterCimIndication.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimRegisterCimIndication.cs index 81e3cf2adb0..909f994a445 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimRegisterCimIndication.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimRegisterCimIndication.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimRemoveCimInstance.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimRemoveCimInstance.cs index 726136fa334..c9454f8e6c8 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimRemoveCimInstance.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimRemoveCimInstance.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimResultObserver.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimResultObserver.cs index 0ea01b2a64a..8939e6d64e0 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimResultObserver.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimResultObserver.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimSessionOperations.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimSessionOperations.cs index bbf90949882..bdc22c965dc 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimSessionOperations.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimSessionOperations.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimSessionProxy.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimSessionProxy.cs index ba2cd51372f..ea84a9d718a 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimSessionProxy.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimSessionProxy.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimSetCimInstance.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimSetCimInstance.cs index 57ddb857cc2..c8ab7fa01b2 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimSetCimInstance.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimSetCimInstance.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives @@ -11,7 +9,6 @@ using System.Globalization; using System.Management.Automation; - #endregion namespace Microsoft.Management.Infrastructure.CimCmdlets diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimWriteError.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimWriteError.cs index 97c45cd77ce..72ad2505645 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimWriteError.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimWriteError.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives @@ -416,7 +414,6 @@ internal InvocationContext CimInvocationContext } } - /// /// /// diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimWriteMessage.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimWriteMessage.cs index b224364bfcc..0c3d07d4d0e 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimWriteMessage.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimWriteMessage.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimWriteProgress.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimWriteProgress.cs index 08eb6acc877..67f3250c282 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimWriteProgress.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimWriteProgress.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimWriteResultObject.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimWriteResultObject.cs index b060a728c01..48310add1a2 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/CimWriteResultObject.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/CimWriteResultObject.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/CmdletOperation.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/CmdletOperation.cs index 9d770ee22da..ab87b0676ab 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/CmdletOperation.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/CmdletOperation.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives using System.Management.Automation; diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/GetCimAssociatedInstanceCommand.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/GetCimAssociatedInstanceCommand.cs index 7afe7325230..9f05857fe6d 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/GetCimAssociatedInstanceCommand.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/GetCimAssociatedInstanceCommand.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives @@ -12,7 +10,6 @@ #endregion - namespace Microsoft.Management.Infrastructure.CimCmdlets { /// diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/GetCimClassCommand.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/GetCimClassCommand.cs index 7dabb35d2af..21425d7b63a 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/GetCimClassCommand.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/GetCimClassCommand.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/GetCimInstanceCommand.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/GetCimInstanceCommand.cs index 248e716c51f..f9a3b21db4a 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/GetCimInstanceCommand.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/GetCimInstanceCommand.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives @@ -13,7 +11,6 @@ #endregion - namespace Microsoft.Management.Infrastructure.CimCmdlets { /// diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/GetCimSessionCommand.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/GetCimSessionCommand.cs index 86b26890b7f..628ea348115 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/GetCimSessionCommand.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/GetCimSessionCommand.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives using System; @@ -10,7 +8,6 @@ using System.Management.Automation; #endregion - namespace Microsoft.Management.Infrastructure.CimCmdlets { /// diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/InvokeCimMethodCommand.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/InvokeCimMethodCommand.cs index eb434f16b66..0b619f87a7a 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/InvokeCimMethodCommand.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/InvokeCimMethodCommand.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives using System; @@ -11,7 +9,6 @@ using System.Management.Automation; #endregion - namespace Microsoft.Management.Infrastructure.CimCmdlets { /// diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/NewCimInstanceCommand.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/NewCimInstanceCommand.cs index b1a5986a0f5..14f9c5f13c7 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/NewCimInstanceCommand.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/NewCimInstanceCommand.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives using System; @@ -11,7 +9,6 @@ using System.Management.Automation; #endregion - namespace Microsoft.Management.Infrastructure.CimCmdlets { /// diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/NewCimSessionCommand.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/NewCimSessionCommand.cs index f1083747e80..a9cfe00ee49 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/NewCimSessionCommand.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/NewCimSessionCommand.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives using System; @@ -11,7 +9,6 @@ #endregion - namespace Microsoft.Management.Infrastructure.CimCmdlets { /// diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/NewCimSessionOptionCommand.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/NewCimSessionOptionCommand.cs index 9e12e007f3a..9bdc9c6c608 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/NewCimSessionOptionCommand.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/NewCimSessionOptionCommand.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives using System; @@ -12,7 +10,6 @@ using Microsoft.Management.Infrastructure.Options; #endregion - namespace Microsoft.Management.Infrastructure.CimCmdlets { /// diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/RegisterCimIndicationCommand.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/RegisterCimIndicationCommand.cs index 66213850619..ec3005062b8 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/RegisterCimIndicationCommand.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/RegisterCimIndicationCommand.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives using System; @@ -11,7 +9,6 @@ using Microsoft.PowerShell.Commands; #endregion - namespace Microsoft.Management.Infrastructure.CimCmdlets { /// diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/RemoveCimInstanceCommand.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/RemoveCimInstanceCommand.cs index 3e6e4166a4f..eb815411193 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/RemoveCimInstanceCommand.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/RemoveCimInstanceCommand.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives @@ -12,7 +10,6 @@ #endregion - namespace Microsoft.Management.Infrastructure.CimCmdlets { /// @@ -64,7 +61,6 @@ public CimSession[] CimSession } private CimSession[] cimSession; - /// /// /// The following is the definition of the input parameter "ResourceUri". diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/RemoveCimSessionCommand.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/RemoveCimSessionCommand.cs index f02f1598593..fbefb223027 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/RemoveCimSessionCommand.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/RemoveCimSessionCommand.cs @@ -1,6 +1,6 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #region Using directives using System; diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/SetCimInstanceCommand.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/SetCimInstanceCommand.cs index 717d3f805bd..e1a85f30b21 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/SetCimInstanceCommand.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/SetCimInstanceCommand.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives using System; diff --git a/src/Microsoft.Management.Infrastructure.CimCmdlets/Utils.cs b/src/Microsoft.Management.Infrastructure.CimCmdlets/Utils.cs index c5389942069..95d9efdc270 100644 --- a/src/Microsoft.Management.Infrastructure.CimCmdlets/Utils.cs +++ b/src/Microsoft.Management.Infrastructure.CimCmdlets/Utils.cs @@ -1,7 +1,5 @@ -/*============================================================================ - * Copyright (C) Microsoft Corporation, All rights reserved. - *============================================================================ - */ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. // #define LOGENABLE // uncomment this line to enable the log, // create c:\temp\cim.log before invoking cimcmdlets diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/CommonUtils.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/CommonUtils.cs index 8ee3e95903d..13b3eece1c2 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/CommonUtils.cs +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/CommonUtils.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.Collections; using System.Diagnostics; @@ -87,11 +90,9 @@ uint dwFlags [DllImport(LibraryLoadDllName)] private static extern bool FreeLibrary(IntPtr hModule); - [DllImport(LocalizationDllName, EntryPoint = "GetUserDefaultLangID", CallingConvention = CallingConvention.Winapi, SetLastError = true)] private static extern ushort GetUserDefaultLangID(); - public static uint FormatMessageFromModule(uint lastError, string moduleName, out String msg) { Debug.Assert(!string.IsNullOrEmpty(moduleName)); diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/CoreCLR/Stubs.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/CoreCLR/Stubs.cs index 88b3a6f134f..5ea3041de9e 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/CoreCLR/Stubs.cs +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/CoreCLR/Stubs.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #if CORECLR using System.ComponentModel; diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/CounterFileInfo.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/CounterFileInfo.cs index 54c0dd83ea3..f41e26a3a88 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/CounterFileInfo.cs +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/CounterFileInfo.cs @@ -1,6 +1,5 @@ -// -// Copyright (c) 2008 Microsoft Corporation. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections; diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/CounterSample.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/CounterSample.cs index ac376f7e00f..7732b20360c 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/CounterSample.cs +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/CounterSample.cs @@ -1,7 +1,5 @@ -// -// Copyright (c) 2008 Microsoft Corporation. All rights reserved. -// - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Reflection; @@ -13,7 +11,6 @@ using System.Globalization; using System.Diagnostics.CodeAnalysis; - namespace Microsoft.PowerShell.Commands.GetCounter { public class PerformanceCounterSample @@ -56,7 +53,6 @@ public string Path } private string _path = ""; - public string InstanceName { get { return _instanceName; } @@ -64,7 +60,6 @@ public string InstanceName } private string _instanceName = ""; - public double CookedValue { get { return _cookedValue; } @@ -107,7 +102,6 @@ public DateTime Timestamp } private DateTime _timeStamp = DateTime.MinValue; - public UInt64 Timestamp100NSec { get { return _timeStamp100nSec; } diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/CounterSet.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/CounterSet.cs index a7160d2ca92..d981700a11c 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/CounterSet.cs +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/CounterSet.cs @@ -1,6 +1,5 @@ -// -// Copyright (c) 2008 Microsoft Corporation. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections; @@ -64,7 +63,6 @@ public PerformanceCounterCategoryType CounterSetType } private PerformanceCounterCategoryType _counterSetType; - public string Description { get diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/ExportCounterCommand.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/ExportCounterCommand.cs index 8ef8fa3d49a..2769277e590 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/ExportCounterCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/ExportCounterCommand.cs @@ -1,7 +1,5 @@ -// -// Copyright (c) 2008 Microsoft Corporation. All rights reserved. -// - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Text; @@ -27,7 +25,6 @@ using Microsoft.PowerShell.Commands.GetCounter; using Microsoft.PowerShell.Commands.Diagnostics.Common; - namespace Microsoft.PowerShell.Commands { /// @@ -54,7 +51,6 @@ public string Path private string _path; private string _resolvedPath; - // // Format parameter. // Valid strings are "blg", "csv", "tsv" (case-insensitive). @@ -73,8 +69,6 @@ public string FileFormat } private string _format = "blg"; - - // // MaxSize parameter // Maximum output file size, in megabytes. @@ -88,7 +82,6 @@ public UInt32 MaxSize } private UInt32 _maxSize = 0; - // // InputObject parameter // @@ -109,7 +102,6 @@ public PerformanceCounterSampleSet[] InputObject } private PerformanceCounterSampleSet[] _counterSampleSets = new PerformanceCounterSampleSet[0]; - // // Force switch // @@ -134,8 +126,6 @@ public SwitchParameter Circular } private SwitchParameter _circular; - - private ResourceManager _resourceMgr = null; private PdhHelper _pdhHelper = null; @@ -213,7 +203,6 @@ protected override void EndProcessing() _pdhHelper.Dispose(); } - /// /// Handle Control-C /// @@ -279,7 +268,6 @@ protected override void ProcessRecord() _queryInitialized = true; } - foreach (PerformanceCounterSampleSet set in _counterSampleSets) { _pdhHelper.ResetRelogValues(); diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/GetCounterCommand.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/GetCounterCommand.cs index 9331855ad1c..50d099b25f8 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/GetCounterCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/GetCounterCommand.cs @@ -1,7 +1,5 @@ -// -// Copyright (c) 2008 Microsoft Corporation. All rights reserved. -// - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Text; @@ -27,7 +25,6 @@ using Microsoft.PowerShell.Commands.GetCounter; using Microsoft.PowerShell.Commands.Diagnostics.Common; - namespace Microsoft.PowerShell.Commands { /// @@ -59,7 +56,6 @@ public string[] ListSet } private string[] _listSet = { "*" }; - // // Counter parameter // @@ -93,7 +89,6 @@ public string[] Counter private List _accumulatedCounters = new List(); - // // SampleInterval parameter. // Defaults to 1 second. @@ -111,7 +106,6 @@ public int SampleInterval } private int _sampleInterval = 1; - // // MaxSamples parameter // @@ -134,7 +128,6 @@ public Int64 MaxSamples private Int64 _maxSamples = 1; private bool _maxSamplesSpecified = false; - // // Continuous switch // @@ -146,7 +139,6 @@ public SwitchParameter Continuous } private bool _continuous = false; - // // ComputerName parameter // @@ -228,7 +220,6 @@ protected override void BeginProcessing() return; } - if (Continuous.IsPresent && _maxSamplesSpecified) { Exception exc = new Exception(string.Format(CultureInfo.CurrentCulture, _resourceMgr.GetString("CounterContinuousOrMaxSamples"))); @@ -249,7 +240,6 @@ protected override void EndProcessing() _pdhHelper.Dispose(); } - // // Handle Control-C // @@ -449,7 +439,6 @@ private void ProcessGetCounter() _cultureAndSpecialCharacterMap.TryGetValue(culture.Name, out characterReplacementList); } - StringCollection allExpandedPaths = new StringCollection(); foreach (string path in paths) { @@ -597,7 +586,6 @@ private void ReportPdhError(uint res, bool bTerminate) } } - // // CombineMachinesAndCounterPaths() helper. // For paths that do not contain machine names, creates a path for each machine in machineNames. diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/GetEventCommand.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/GetEventCommand.cs index c44e17d1772..78b64e74b6d 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/GetEventCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/GetEventCommand.cs @@ -1,6 +1,5 @@ -// -// Copyright (c) 2007 Microsoft Corporation. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Xml; @@ -73,7 +72,6 @@ public string[] LogName } private string[] _logName = { "*" }; - /// /// ListProvider parameter /// @@ -99,7 +97,6 @@ public string[] ListProvider } private string[] _listProvider = { "*" }; - /// /// ProviderName parameter /// @@ -123,7 +120,6 @@ public string[] ProviderName } private string[] _providerName; - /// /// Path parameter /// @@ -147,7 +143,6 @@ public string[] Path } private string[] _path; - /// /// MaxEvents parameter /// @@ -244,7 +239,6 @@ public PSCredential Credential } private PSCredential _credential = PSCredential.Empty; - /// /// FilterXPath parameter /// @@ -294,7 +288,6 @@ public XmlDocument FilterXml } private XmlDocument _xmlQuery = null; - /// /// FilterHashtable parameter /// @@ -349,7 +342,6 @@ public SwitchParameter Oldest } private bool _oldest = false; - // // Query builder constant strings // @@ -404,7 +396,6 @@ public SwitchParameter Oldest private const string hashkey_data_lc = "data"; private const string hashkey_supress_lc = "suppresshashfilter"; - /// /// BeginProcessing() is invoked once per pipeline: we will load System.Core.dll here /// @@ -413,7 +404,6 @@ protected override void BeginProcessing() _resourceMgr = Microsoft.PowerShell.Commands.Diagnostics.Common.CommonUtilities.GetResourceManager(); } - /// /// EndProcessing() is invoked once per pipeline /// @@ -438,7 +428,6 @@ protected override void EndProcessing() } } - /// /// ProcessRecord() override. /// This is the main entry point for the cmdlet. @@ -481,7 +470,6 @@ protected override void ProcessRecord() } } - // // AccumulatePipelineCounters() accumulates log names in the pipeline scenario: // we do not want to construct a query until all the log names are supplied. @@ -540,7 +528,6 @@ private void ProcessGetLog() } } - // // Process GetProviderSet parameter set // @@ -558,7 +545,6 @@ private void ProcessGetProvider() return; } - EventLogQuery logQuery = null; if (_providersByLogMap.Count > 1) { @@ -584,7 +570,6 @@ private void ProcessGetProvider() } } - // // Process ListLog parameter set // @@ -746,7 +731,6 @@ private void ProcessFilterXml() } } - // // Process FileSet parameter set // @@ -857,7 +841,6 @@ private EventLogSession CreateSession() return eventLogSession; } - // // ReadEvents helper. // @@ -901,7 +884,6 @@ private void ReadEvents(EventLogQuery logQuery) } outputObj.Properties.Add(new PSNoteProperty("Message", evtMessage)); - // // Enumerate the object one level to get to event payload // @@ -918,8 +900,6 @@ private void ReadEvents(EventLogQuery logQuery) } } - - // // BuildStructuredQuery() builds a structured query from cmdlet arguments. // @@ -1311,7 +1291,6 @@ private string BuildStructuredQueryFromHashTable(EventLogSession eventLogSession } } //end foreach hashtable - result.Append(queryListClose); return result.ToString(); @@ -1444,7 +1423,6 @@ private string HandleContextHashValue(Object value) return string.Format(CultureInfo.InvariantCulture, SystemSecurityTemplate, sidCandidate.ToString()); } - // // HandleStartTimeHashValue helper for hashtable structured query builder. // Constructs and returns TimeCreated XPath portion as a string. @@ -1488,7 +1466,6 @@ private string HandleStartTimeHashValue(Object value, Hashtable hash) return ret.ToString(); } - // // HandleEndTimeHashValue helper for hashtable structured query builder. // Constructs and returns TimeCreated XPath portion as a string. @@ -1563,7 +1540,6 @@ private string HandleDataHashValue(Object value) return ret.ToString(); } - // // HandleNamedDataHashValue helper for hashtable structured query builder. // Constructs and returns named event data field XPath portion as a string. @@ -1598,7 +1574,6 @@ private string HandleNamedDataHashValue(String key, Object value) return ret.ToString(); } - // // Helper checking whether at least one of log, _path, provider is specified. // It will ThrowTerminatingError in case none of those keys are present. @@ -1673,7 +1648,6 @@ private bool ValidateLogName(string logName, EventLogSession eventLogSession) return true; } - // // KeywordStringToInt64 helper converts a string to Int64. // Returns true and keyLong ref if successful. @@ -1876,7 +1850,6 @@ private string AddProviderPredicatesToFilter(StringCollection providers) return ret; } - // // BuildProvidersPredicate() builds a predicate expression like: // "System/Provider[@Name='a' or @Name='b']" @@ -1903,7 +1876,6 @@ private string BuildProvidersPredicate(StringCollection providers) return predicate.ToString(); } - // // BuildAllProvidersPredicate() builds a predicate expression like: // "System/Provider[@Name='a' or @Name='b']" @@ -1948,7 +1920,6 @@ private string BuildAllProvidersPredicate() return predicate.ToString(); } - // // AddLogsForProviderToInternalMap helper. // Retrieves log names to which _providerName writes. @@ -2130,4 +2101,3 @@ private void FindProvidersByLogForWildcardPatterns(EventLogSession eventLogSessi } } - diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/GetEventSnapin.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/GetEventSnapin.cs index da6a77d4dd8..a4483c7497f 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/GetEventSnapin.cs +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/GetEventSnapin.cs @@ -1,7 +1,5 @@ -// -// Copyright (c) 2007 Microsoft Corporation. All rights reserved. -// - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/ImportCounterCommand.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/ImportCounterCommand.cs index b95103d8a38..b9275784fc4 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/ImportCounterCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/ImportCounterCommand.cs @@ -1,7 +1,5 @@ -// -// Copyright (c) 2008 Microsoft Corporation. All rights reserved. -// - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Text; @@ -27,7 +25,6 @@ using Microsoft.PowerShell.Commands.GetCounter; using Microsoft.PowerShell.Commands.Diagnostics.Common; - namespace Microsoft.PowerShell.Commands { /// @@ -62,7 +59,6 @@ public string[] Path private List _accumulatedFileNames = new List(); - // // ListSet parameter // @@ -84,7 +80,6 @@ public string[] ListSet } private string[] _listSet = new string[0]; - // // StartTime parameter // @@ -100,7 +95,6 @@ public DateTime StartTime } private DateTime _startTime = DateTime.MinValue; - // // EndTime parameter // @@ -116,7 +110,6 @@ public DateTime EndTime } private DateTime _endTime = DateTime.MaxValue; - // // Counter parameter // @@ -165,14 +158,12 @@ public Int64 MaxSamples } private Int64 _maxSamples = KEEP_ON_SAMPLING; - private ResourceManager _resourceMgr = null; private PdhHelper _pdhHelper = null; private bool _stopping = false; - // // AccumulatePipelineFileNames() accumulates counter file paths in the pipeline scenario: // we do not want to construct a Pdh query until all the file names are supplied. @@ -182,7 +173,6 @@ private void AccumulatePipelineFileNames() _accumulatedFileNames.AddRange(_path); } - // // BeginProcessing() is invoked once per pipeline // @@ -241,7 +231,6 @@ protected override void EndProcessing() _pdhHelper.Dispose(); } - // // Handle Control-C // @@ -251,7 +240,6 @@ protected override void StopProcessing() _pdhHelper.Dispose(); } - // // ProcessRecord() override. // This is the main entry point for the cmdlet. @@ -331,7 +319,6 @@ private void ProcessListSet() continue; } - StringCollection counterSetCounters = new StringCollection(); StringCollection counterSetInstances = new StringCollection(); @@ -508,7 +495,6 @@ private void ProcessGetCounter() } } - // // ValidateFilePaths() helper. // Validates the _resolvedPaths: present for all parametersets. @@ -563,7 +549,6 @@ private void ValidateFilePaths() } } - // // ResolveFilePath helper. // Returns a string collection of resolved file paths. @@ -674,4 +659,3 @@ private void WriteSampleSetObject(PerformanceCounterSampleSet set, bool firstSet } } - diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/NewWinEventCommand.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/NewWinEventCommand.cs index 16529125f3d..e242d3455ab 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/NewWinEventCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/NewWinEventCommand.cs @@ -1,6 +1,5 @@ -// -// Copyright (c) 2007 Microsoft Corporation. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; @@ -30,7 +29,6 @@ public sealed class NewWinEventCommand : PSCmdlet private const string DataTag = "data"; private ResourceManager _resourceMgr = Microsoft.PowerShell.Commands.Diagnostics.Common.CommonUtilities.GetResourceManager(); - /// /// ProviderName /// @@ -73,7 +71,6 @@ public int Id private int _id; private bool _idSpecified = false; - /// /// Version (event version) /// @@ -95,7 +92,6 @@ public byte Version private byte _version; private bool _versionSpecified = false; - /// /// Event Payload /// @@ -353,4 +349,4 @@ internal EventWriteException(string msg) : base(msg) { } } -} \ No newline at end of file +} diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs index a61b91cb766..d42d6a2f60b 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Diagnostics; @@ -105,8 +104,6 @@ internal static class PdhResults public const long PDH_QUERY_PERF_DATA_TIMEOUT = 0xC0000BFEL; } - - internal static class PerfDetail { public const uint PERF_DETAIL_NOVICE = 100; // The uninformed can understand it @@ -203,7 +200,6 @@ public PdhHelper(bool isPreVista) _isPreVista = isPreVista; } - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private struct PDH_COUNTER_PATH_ELEMENTS { @@ -274,7 +270,6 @@ private struct PDH_TIME_INFO public UInt32 SampleCount; } - /* // // This is the structure returned by PdhGetCounterInfo(). @@ -304,7 +299,6 @@ struct PDH_COUNTER_INFO { [FieldOffset(104)]public IntPtr DataBuffer; }*/ - [DllImport("pdh.dll", CharSet = CharSet.Unicode)] private static extern uint PdhBindInputDataSource(out PdhSafeDataSourceHandle phDataSource, string szLogFileNameList); @@ -347,7 +341,6 @@ out PdhSafeLogHandle phLog [DllImport("pdh.dll", CharSet = CharSet.Unicode)] private static extern void PdhResetRelogCounterValues(PdhSafeLogHandle LogHandle); - //Win7+ only [DllImport("pdh.dll", CharSet = CharSet.Unicode)] private static extern uint PdhSetCounterValue(IntPtr CounterHandle, @@ -396,7 +389,6 @@ private static extern uint PdhParseCounterPath(string szFullPathBuffer, ref IntPtr pdwBufferSize, uint dwFlags); - [DllImport("pdh.dll", CharSet = CharSet.Unicode)] private static extern uint PdhExpandWildCardPathH(PdhSafeDataSourceHandle hDataSource, string szWildCardPath, @@ -427,11 +419,9 @@ private static extern uint PdhExpandWildCardPathH(PdhSafeDataSourceHandle hDataS [DllImport("pdh.dll", CharSet = CharSet.Unicode)] private static extern uint PdhSetQueryTimeRange(PdhSafeQueryHandle hQuery, ref PDH_TIME_INFO pInfo); - [DllImport("pdh.dll", CharSet = CharSet.Unicode)] private static extern uint PdhLookupPerfNameByIndex(string szMachineName, UInt32 dwNameIndex, IntPtr szNameBuffer, ref int pcchNameBufferSize); - private PdhSafeDataSourceHandle _hDataSource = null; private PdhSafeQueryHandle _hQuery = null; @@ -468,7 +458,6 @@ public void Dispose() // private Dictionary _consumerPathToHandleAndInstanceMap = new Dictionary(); - // // m_ReloggerPathToHandleAndInstanceMap map is used for writing relog counters. // @@ -504,8 +493,6 @@ private void ReadPdhMultiString(ref IntPtr strNative, Int32 strSize, ref StringC strColl.AddRange(allSubstringsWithNulls.Split('\0')); } - - private uint GetCounterInfoPlus(IntPtr hCounter, out UInt32 counterType, out UInt32 defaultScale, out UInt64 timeBase) { uint res = 0; @@ -586,7 +573,6 @@ public uint ConnectToDataSource(string dataSourceName) return res; } - public uint ConnectToDataSource(StringCollection blgFileNames) { if (blgFileNames.Count == 1) @@ -635,7 +621,6 @@ public uint OpenLogForWriting(string logName, PdhLogFileType logFileType, bool b return res; } - public uint SetQueryTimeRange(DateTime startTime, DateTime endTime) { Debug.Assert(_hQuery != null); @@ -799,7 +784,6 @@ public uint GetValidPathsFromFiles(ref StringCollection validPaths) { Debug.Assert(_hDataSource != null && !_hDataSource.IsInvalid, "Call ConnectToDataSource before GetValidPathsFromFiles"); - StringCollection machineNames = new StringCollection(); uint res = this.EnumBlgFilesMachines(ref machineNames); if (res != 0) @@ -894,7 +878,6 @@ public bool IsPathValid(string path) } } - private uint MakePath(PDH_COUNTER_PATH_ELEMENTS pathElts, out string outPath, bool bWildcardInstances) { outPath = ""; @@ -947,7 +930,6 @@ private uint MakeAllInstancePath(string origPath, out string unifiedPath) return MakePath(elts, out unifiedPath, true); } - private uint ParsePath(string fullPath, ref PDH_COUNTER_PATH_ELEMENTS pCounterPathElements) { IntPtr bufSize = new IntPtr(0); @@ -1022,7 +1004,6 @@ public uint TranslateLocalCounterPath(string englishPath, out string localizedPa RegistryKey rootKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009"); string[] regCounters = (string[])rootKey.GetValue("Counter"); - // NOTE: 1-based enumeration because the name strings follow index strings in the array Int32 counterIndex = -1; Int32 objIndex = -1; @@ -1062,7 +1043,6 @@ public uint TranslateLocalCounterPath(string englishPath, out string localizedPa return (uint)PdhResults.PDH_INVALID_PATH; } - // Now, call retrieve the localized names of the object and the counter by index: string objNameLocalized; res = LookupPerfNameByIndex(pathElts.MachineName, (uint)objIndex, out objNameLocalized); @@ -1072,7 +1052,6 @@ public uint TranslateLocalCounterPath(string englishPath, out string localizedPa } pathElts.ObjectName = objNameLocalized; - string ctrNameLocalized; res = LookupPerfNameByIndex(pathElts.MachineName, (uint)counterIndex, out ctrNameLocalized); if (res != 0) @@ -1085,11 +1064,9 @@ public uint TranslateLocalCounterPath(string englishPath, out string localizedPa res = MakePath(pathElts, out localizedPath, false); - return res; } - public uint LookupPerfNameByIndex(string machineName, uint index, out string locName) { // @@ -1124,8 +1101,6 @@ public uint LookupPerfNameByIndex(string machineName, uint index, out string loc return res; } - - public uint GetValidPaths(string machineName, string objectName, ref StringCollection counters, @@ -1168,7 +1143,6 @@ public uint GetValidPaths(string machineName, return res; } - public uint AddCounters(ref StringCollection validPaths, bool bFlushOldCounters) { Debug.Assert(_hQuery != null && !_hQuery.IsInvalid); @@ -1210,7 +1184,6 @@ public uint AddCounters(ref StringCollection validPaths, bool bFlushOldCounters) return bAtLeastOneAdded ? 0 : res; } - // // AddRelogCounters combines instances and adds counters to m_hQuery. // The counter handles and full paths @@ -1325,8 +1298,6 @@ public uint AddRelogCounters(PerformanceCounterSampleSet sampleSet) return (_reloggerPathToHandleAndInstanceMap.Keys.Count > 0) ? 0 : res; } - - // // AddRelogCountersPreservingPaths preserves all paths and adds as relog counters to m_hQuery. // The counter handles and full paths are added to m_ReloggerPathToHandleAndInstanceMap @@ -1534,7 +1505,6 @@ public uint ReadNextSetPreVista(out PerformanceCounterSampleSet nextSet, bool bS return res; } - public uint ReadNextSet(out PerformanceCounterSampleSet nextSet, bool bSkipReading) { Debug.Assert(_hQuery != null && !_hQuery.IsInvalid); @@ -1658,7 +1628,6 @@ public uint ReadNextSet(out PerformanceCounterSampleSet nextSet, bool bSkipReadi fmtValueDouble.CStatus); } - nextSet = new PerformanceCounterSampleSet(batchStamp, samplesArr, _firstReading); _firstReading = false; @@ -1677,7 +1646,6 @@ public uint ReadNextSet(out PerformanceCounterSampleSet nextSet, bool bSkipReadi return res; } - public uint GetFilesSummary(out CounterFileInfo summary) { IntPtr pNumEntries = new IntPtr(0); @@ -1770,7 +1738,6 @@ public uint SetCounterValue(PerformanceCounterSample sample, out bool bUnknownPa rawStruct.TimeStamp.dwLowDateTime = (int)(new DateTime(sample.Timestamp.Ticks, DateTimeKind.Utc).ToFileTimeUtc() & 0xFFFFFFFFL); rawStruct.CStatus = sample.Status; - return PdhSetCounterValue(_reloggerPathToHandleAndInstanceMap[lcPath].hCounter, ref rawStruct, /*PPDH_RAW_COUNTER */ _reloggerPathToHandleAndInstanceMap[lcPath].InstanceName); diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/PdhSafeHandle.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/PdhSafeHandle.cs index eaa6a401b3f..c77e9f10f5e 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/PdhSafeHandle.cs +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/PdhSafeHandle.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Runtime.InteropServices; @@ -21,7 +20,6 @@ public override bool IsInvalid } } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { @@ -29,9 +27,6 @@ protected override bool ReleaseHandle() } } - - - internal sealed class PdhSafeQueryHandle : SafeHandle { private PdhSafeQueryHandle() : base(IntPtr.Zero, true) { } @@ -44,7 +39,6 @@ public override bool IsInvalid } } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { @@ -64,7 +58,6 @@ public override bool IsInvalid } } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/resources/GetEventResources.txt b/src/Microsoft.PowerShell.Commands.Diagnostics/resources/GetEventResources.txt index 751578835cd..6e004d457d8 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/resources/GetEventResources.txt +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/resources/GetEventResources.txt @@ -1,4 +1,4 @@ -#Copyright (c) 2008 Microsoft Corporation +#Copyright (c) Microsoft Corporation. All rights reserved. Vendor=Microsoft Description=This Windows PowerShell snap-in contains Windows Eventing and Performance Counter cmdlets. diff --git a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj index 7f0bb98cc6b..a95f1deb2ee 100644 --- a/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj +++ b/src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj @@ -68,7 +68,8 @@ - + + diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/SessionBasedWrapper.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/SessionBasedWrapper.cs index 56cbb10edc2..b878633b759 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/SessionBasedWrapper.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/SessionBasedWrapper.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections; diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/CimJobException.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/CimJobException.cs index 53c531b79f7..af44bb8fee8 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/CimJobException.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/CimJobException.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Globalization; diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/CreateInstanceJob.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/CreateInstanceJob.cs index 9710f3044a9..1ed6dadfa91 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/CreateInstanceJob.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/CreateInstanceJob.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using Microsoft.Management.Infrastructure; diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/DeleteInstanceJob.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/DeleteInstanceJob.cs index 075be25cccc..70911217468 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/DeleteInstanceJob.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/DeleteInstanceJob.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using Microsoft.Management.Infrastructure; diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/EnumerateAssociatedInstancesJob.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/EnumerateAssociatedInstancesJob.cs index 9ea248ff767..c28363eae55 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/EnumerateAssociatedInstancesJob.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/EnumerateAssociatedInstancesJob.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Globalization; diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/ExtrinsicMethodInvocationJob.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/ExtrinsicMethodInvocationJob.cs index 023a1fda977..1b7fbf99da9 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/ExtrinsicMethodInvocationJob.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/ExtrinsicMethodInvocationJob.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections; diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/InstanceMethodInvocationJob.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/InstanceMethodInvocationJob.cs index d9d7db6a2ab..088b56b796a 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/InstanceMethodInvocationJob.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/InstanceMethodInvocationJob.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using Microsoft.Management.Infrastructure; diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/MethodInvocationJobBase.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/MethodInvocationJobBase.cs index 273b25cc619..f93c54cd7c4 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/MethodInvocationJobBase.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/MethodInvocationJobBase.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/ModifyInstanceJob.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/ModifyInstanceJob.cs index 4efc7d12b66..a1cb7ad62ad 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/ModifyInstanceJob.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/ModifyInstanceJob.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/PropertySettingJob.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/PropertySettingJob.cs index c92ad7e548f..c1f0206420a 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/PropertySettingJob.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/PropertySettingJob.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using Microsoft.Management.Infrastructure; using Microsoft.PowerShell.Cim; diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/QueryJob.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/QueryJob.cs index 8a3d45715c7..bdddd60ac56 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/QueryJob.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/QueryJob.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Globalization; diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/QueryJobBase.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/QueryJobBase.cs index 3f04a81ecdc..edeb98b7848 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/QueryJobBase.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/QueryJobBase.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; using Microsoft.Management.Infrastructure; diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/StaticMethodInvocationJob.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/StaticMethodInvocationJob.cs index 5b47d46c6fc..a2a400eb7b2 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/StaticMethodInvocationJob.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/StaticMethodInvocationJob.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using Microsoft.Management.Infrastructure; diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/TerminatingErrorTracker.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/TerminatingErrorTracker.cs index b00184f0381..dc4a9c8d48c 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/TerminatingErrorTracker.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/TerminatingErrorTracker.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections; diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimChildJobBase.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimChildJobBase.cs index 30fec5de0b4..98007451289 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimChildJobBase.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimChildJobBase.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Concurrent; @@ -398,7 +397,6 @@ internal CimOperationOptions CreateOperationOptions() operationOptions.SetOption("__MI_OPERATIONOPTIONS_IMPROVEDPERF_STREAMING", 1); - operationOptions.Flags |= this.JobContext.CmdletInvocationContext.CmdletDefinitionContext.SchemaConformanceLevel; if (this.JobContext.CmdletInvocationContext.CmdletDefinitionContext.ResourceUri != null) @@ -524,7 +522,6 @@ private CimCustomOptionsDictionary GetJobSpecificCustomOptions() return _jobSpecificCustomOptions.Value; } - #endregion #region Controlling job state diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimCmdletDefinitionContext.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimCmdletDefinitionContext.cs index f08b4e69b6d..9d5606fd5bb 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimCmdletDefinitionContext.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimCmdletDefinitionContext.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimCmdletInvocationContext.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimCmdletInvocationContext.cs index b89f7c4de3e..96fd9c1e376 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimCmdletInvocationContext.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimCmdletInvocationContext.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimConverter.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimConverter.cs index 02b74033585..c51de701a70 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimConverter.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimConverter.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; @@ -666,4 +665,4 @@ internal static void AssertIntrinsicCimType(Type type) "Caller should verify that type is an intrinsic CIM type"); } } -} \ No newline at end of file +} diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimJobContext.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimJobContext.cs index a3caada5792..89f0cad9064 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimJobContext.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimJobContext.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Globalization; diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimOperationOptionsHelper.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimOperationOptionsHelper.cs index ededc6cd10e..bbd6bad2fc8 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimOperationOptionsHelper.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimOperationOptionsHelper.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimQuery.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimQuery.cs index 236585fd2a9..3add2eb53fd 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimQuery.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimQuery.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections; diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimWrapper.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimWrapper.cs index 54773a8b886..81fc991dd4e 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimWrapper.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimWrapper.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.ObjectModel; diff --git a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/clientSideQuery.cs b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/clientSideQuery.cs index 67ef3cb12a7..f07114a5379 100644 --- a/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/clientSideQuery.cs +++ b/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/clientSideQuery.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections; diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/AddContentCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/AddContentCommand.cs index d6a1c7f067f..04b2c6df353 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/AddContentCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/AddContentCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; @@ -52,7 +51,6 @@ internal override void SeekContentPosition(List contentHolders) holder.PathInfo.Path, e); - // Log a provider health event MshLog.LogProviderHealthEvent( diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/CIMHelper.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/CIMHelper.cs index ad56f989ae7..28f4e97f43e 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/CIMHelper.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/CIMHelper.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using System.Collections.Generic; using System.Reflection; diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/ClearContentCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/ClearContentCommand.cs index 13ec9dc416f..acda6e95aed 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/ClearContentCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/ClearContentCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; using Dbg = System.Management.Automation; @@ -77,7 +76,6 @@ protected override bool ProviderSupportsShouldProcess } } - /// /// A virtual method for retrieving the dynamic parameters for a cmdlet. Derived cmdlets /// that require dynamic parameters should override this method and return the diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/ClearPropertyCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/ClearPropertyCommand.cs index 6e74d62b502..60ded819c9c 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/ClearPropertyCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/ClearPropertyCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Collections.ObjectModel; using System.Management.Automation; @@ -173,6 +172,5 @@ protected override void ProcessRecord() } // ProcessRecord #endregion Command code - } // ClearItemPropertyCommand } // namespace Microsoft.PowerShell.Commands diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/ClearRecycleBinCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/ClearRecycleBinCommand.cs index 183c3712fbc..9e2ec6eb743 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/ClearRecycleBinCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/ClearRecycleBinCommand.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using System.Management.Automation; using System.Runtime.InteropServices; using System.IO; @@ -251,4 +254,4 @@ internal enum RecycleFlags : uint [DllImport("Shell32.dll", CharSet = CharSet.Unicode)] internal static extern uint SHEmptyRecycleBin(IntPtr hwnd, string pszRootPath, RecycleFlags dwFlags); } -} \ No newline at end of file +} diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/CombinePathCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/CombinePathCommand.cs index e6293091539..be7cda5a31a 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/CombinePathCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/CombinePathCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Text; @@ -217,7 +216,6 @@ protected override void ProcessRecord() } // ProcessRecord #endregion Command code - } // JoinPathCommand } // namespace Microsoft.PowerShell.Commands diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/CommitTransactionCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/CommitTransactionCommand.cs index 2058bdd833a..8d583a7fecc 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/CommitTransactionCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/CommitTransactionCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; using Dbg = System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Computer.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Computer.cs index 150298befb1..208c75d0614 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Computer.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Computer.cs @@ -1,8 +1,8 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #if !UNIX -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ using System; using System.Collections; using System.Collections.Generic; @@ -27,15 +27,7 @@ using Microsoft.Management.Infrastructure.Options; using System.Linq; using Dbg = System.Management.Automation; - -#if CORECLR using Microsoft.PowerShell.CoreClr.Stubs; -#else -//TODO:CORECLR System.DirectoryServices is not available on CORE CLR -using System.DirectoryServices; -using System.Management; // We are not porting the library to CoreCLR -using Microsoft.WSMan.Management; -#endif // FxCop suppressions for resource strings: [module: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", Scope = "resource", Target = "ComputerResources.resources", MessageId = "unjoined")] @@ -43,118 +35,181 @@ namespace Microsoft.PowerShell.Commands { -#region Test-Connection +#region Restart-Computer /// - /// This cmdlet is used to test whether a particular host is reachable across an - /// IP network. It works by sending ICMP "echo request" packets to the target - /// host and listening for ICMP "echo response" replies. This cmdlet prints a - /// statistical summary when finished. + /// This exception is thrown when the timeout expires before a computer finishes restarting /// - [Cmdlet(VerbsDiagnostic.Test, "Connection", DefaultParameterSetName = RegularParameterSet, - HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135266", RemotingCapability = RemotingCapability.OwnedByCommand)] - [OutputType(typeof(Boolean))] - [OutputType(@"System.Management.ManagementObject#root\cimv2\Win32_PingStatus")] - public class TestConnectionCommand : PSCmdlet + [Serializable] + public sealed class RestartComputerTimeoutException : RuntimeException { -#region "Parameters" + /// + /// Name of the computer that is restarting + /// + public string ComputerName { get; private set; } + + /// + /// The timeout value specified by the user. It indicates the seconds to wait before timeout. + /// + public int Timeout { get; private set; } + + /// + /// Construct a RestartComputerTimeoutException. + /// + /// + /// + /// + /// + internal RestartComputerTimeoutException(string computerName, int timeout, string message, string errorId) + : base(message) + { + SetErrorId(errorId); + SetErrorCategory(ErrorCategory.OperationTimeout); + ComputerName = computerName; + Timeout = timeout; + } - private const string RegularParameterSet = "Default"; - private const string QuietParameterSet = "Quiet"; - private const string SourceParameterSet = "Source"; + /// + /// Construct a RestartComputerTimeoutException + /// + public RestartComputerTimeoutException() : base() { } /// + /// Constructs a RestartComputerTimeoutException + /// /// + /// + /// The message used in the exception. + /// + public RestartComputerTimeoutException(string message) : base(message) { } + + /// + /// Constructs a RestartComputerTimeoutException /// - [Parameter(ParameterSetName = SourceParameterSet)] - [Parameter(ParameterSetName = RegularParameterSet)] - public SwitchParameter AsJob { get; set; } = false; + /// + /// + /// The message used in the exception. + /// + /// + /// + /// An exception that led to this exception. + /// + public RestartComputerTimeoutException(string message, Exception innerException) : base(message, innerException) { } +#region Serialization /// - /// The following is the definition of the input parameter "DcomAuthentication". - /// Specifies the authentication level to be used with WMI connection. Valid - /// values are: + /// Serialization constructor for class RestartComputerTimeoutException + /// + /// + /// + /// serialization information + /// /// - /// Unchanged = -1, - /// Default = 0, - /// None = 1, - /// Connect = 2, - /// Call = 3, - /// Packet = 4, - /// PacketIntegrity = 5, - /// PacketPrivacy = 6. + /// + /// streaming context + /// + private RestartComputerTimeoutException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + if (info == null) + { + throw new PSArgumentNullException("info"); + } + + ComputerName = info.GetString("ComputerName"); + Timeout = info.GetInt32("Timeout"); + } + + /// + /// Serializes the RestartComputerTimeoutException. /// + /// + /// + /// serialization information + /// + /// + /// + /// streaming context + /// + [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + if (info == null) + { + throw new PSArgumentNullException("info"); + } - [Parameter] - [Alias("Authentication")] - public AuthenticationLevel DcomAuthentication { get; set; } = AuthenticationLevel.Packet; + base.GetObjectData(info, context); + info.AddValue("ComputerName", ComputerName); + info.AddValue("Timeout", Timeout); + } +#endregion Serialization + } + /// + /// Defines the services that Restart-Computer can wait on + /// + [SuppressMessage("Microsoft.Design", "CA1027:MarkEnumsWithFlags")] + public enum WaitForServiceTypes + { /// - /// The authentication options for CIM_WSMan connection + /// Wait for the WMI service to be ready /// - [Parameter] - [ValidateSet( - "Default", - "Basic", - "Negotiate", // can be used with and without credential (without -> PSRP mapped to NegotiateWithImplicitCredential) - "CredSSP", - "Digest", - "Kerberos")] // can be used with and without credential (not sure about implications) - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] - public string WsmanAuthentication { get; set; } = "Default"; + Wmi = 0x0, /// - /// Specify the protocol to use + /// Wait for the WinRM service to be ready /// - [Parameter] - [ValidateSet(ComputerWMIHelper.DcomProtocol, ComputerWMIHelper.WsmanProtocol)] - public string Protocol { get; set; } = -#if CORECLR - //CoreClr does not support DCOM protocol - // This change makes sure that the the command works seamlessly if user did not explicitly entered the protocol - ComputerWMIHelper.WsmanProtocol; -#else - ComputerWMIHelper.DcomProtocol; -#endif + WinRM = 0x1, /// - /// The following is the definition of the input parameter "BufferSize". - /// Buffer size sent with the this command. The default value is 32. + /// Wait for the PowerShell to be ready /// - [Parameter] - [Alias("Size", "Bytes", "BS")] - [ValidateRange((int)0, (int)65500)] - public Int32 BufferSize { get; set; } = 32; + PowerShell = 0x2, + } + + /// + /// Restarts the computer + /// + [Cmdlet(VerbsLifecycle.Restart, "Computer", SupportsShouldProcess = true, DefaultParameterSetName = DefaultParameterSet, + HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135253", RemotingCapability = RemotingCapability.OwnedByCommand)] + public class RestartComputerCommand : PSCmdlet, IDisposable + { +#region "Parameters and PrivateData" + + private const string DefaultParameterSet = "DefaultSet"; + private const int forcedReboot = 6; // see https://msdn.microsoft.com/en-us/library/aa394058(v=vs.85).aspx /// - /// The following is the definition of the input parameter "TimeOut". - /// Time-out value in milliseconds. If a response is not received in this time, no response is assumed. The default is 1000 milliseconds. + /// The authentication options for CIM_WSMan connection /// - [Parameter] - [ValidateRange((int)1, Int32.MaxValue)] - public Int32 TimeOut { get; set; } = 1000; + [Parameter(ParameterSetName = DefaultParameterSet)] + [ValidateSet( + "Default", + "Basic", + "Negotiate", // can be used with and without credential (without -> PSRP mapped to NegotiateWithImplicitCredential) + "CredSSP", + "Digest", + "Kerberos")] // can be used with explicit or implicit credential + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] + public string WsmanAuthentication { get; set; } /// - /// The following is the definition of the input parameter "ComputerName". - /// Value of the address requested. The form of the value can be either the - /// computer name ("wxyz1234"), IPv4 address ("192.168.177.124"), or IPv6 - /// address ("2010:836B:4179::836B:4179"). + /// Specifies the computer (s)Name on which this command is executed. + /// When this parameter is omitted, this cmdlet restarts the local computer. + /// Type the NETBIOS name, IP address, or fully-qualified domain name of one + /// or more computers in a comma-separated list. To specify the local computer, type the computername or "localhost". /// - [Parameter(Mandatory = true, - Position = 0, + [Parameter(Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] [ValidateNotNullOrEmpty] [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - [Alias("CN", "IPAddress", "__SERVER", "Server", "Destination")] - public String[] ComputerName { get; set; } + [Alias("CN", "__SERVER", "Server", "IPAddress")] + public String[] ComputerName { get; set; } = new string[] { "." }; - /// - /// The following is the definition of the input parameter "Count". - /// Number of echo requests to send. - /// - [Parameter] - [ValidateRange(1, UInt32.MaxValue)] - public Int32 Count { get; set; } = 4; + private List _validatedComputerNames = new List(); + private readonly List _waitOnComputers = new List(); + private readonly HashSet _uniqueComputerNames = new HashSet(StringComparer.OrdinalIgnoreCase); /// /// The following is the definition of the input parameter "Credential". @@ -162,539 +217,156 @@ public class TestConnectionCommand : PSCmdlet /// user-name, such as "User01" or "Domain01\User01", or enter a PSCredential /// object, such as one from the Get-Credential cmdlet /// - [Parameter(ParameterSetName = SourceParameterSet, Mandatory = false)] + [Parameter(Position = 1)] [ValidateNotNullOrEmpty] [Credential] public PSCredential Credential { get; set; } /// - /// The following is the definition of the input parameter "FromComputerName". - /// Specifies the Computer names where the ping request is originated from. + /// Using Force in conjunction with Reboot on a + /// remote computer immediately reboots the remote computer. /// - [Parameter(Position = 1, ParameterSetName = SourceParameterSet, Mandatory = true)] - [ValidateNotNullOrEmpty] - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - [Alias("FCN", "SRC")] - public String[] Source { get; set; } = new string[] { "." }; + [Parameter] + [Alias("f")] + public SwitchParameter Force { get; set; } /// - /// The following is the definition of the input parameter "Impersonation". - /// Specifies the impersonation level to use when calling the WMI method. Valid - /// values are: - /// - /// Default = 0, - /// Anonymous = 1, - /// Identify = 2, - /// Impersonate = 3, - /// Delegate = 4. + /// Specify the Wait parameter. Prompt will be blocked is the Timeout is not 0 /// - [Parameter] - public ImpersonationLevel Impersonation { get; set; } = ImpersonationLevel.Impersonate; + [Parameter(ParameterSetName = DefaultParameterSet)] + public SwitchParameter Wait { get; set; } /// - /// The following is the definition of the input parameter "ThrottleLimit". - /// The number of concurrent computers on which the command will be allowed to - /// execute + /// Specify the Timeout parameter. + /// Negative value indicates wait infinitely. + /// Positive value indicates the seconds to wait before timeout. /// - [Parameter(ParameterSetName = SourceParameterSet)] - [Parameter(ParameterSetName = RegularParameterSet)] - [ValidateRange(int.MinValue, (int)1000)] - public Int32 ThrottleLimit + [Parameter(ParameterSetName = DefaultParameterSet)] + [Alias("TimeoutSec")] + [ValidateRange(-1, int.MaxValue)] + public int Timeout { - get { return throttlelimit; } + get { return _timeout; } set { - throttlelimit = value; - if (throttlelimit <= 0) - throttlelimit = 32; + _timeout = value; + _timeoutSpecified = true; } } - private Int32 throttlelimit = 32; + private int _timeout = -1; + private bool _timeoutSpecified = false; /// - /// The following is the definition of the input parameter "TimeToLive". - /// Life span of the packet in seconds. The value is treated as an upper limit. - /// All routers must decrement this value by 1 (one). When this value becomes 0 - /// (zero), the packet is dropped by the router. The default value is 80 - /// seconds. The hops between routers rarely take this amount of time. + /// Specify the For parameter. + /// Wait for the specific service before unblocking the prompt. /// - [Parameter] - [ValidateRange(1, (int)255)] - [Alias("TTL")] - public Int32 TimeToLive { get; set; } = 80; + [Parameter(ParameterSetName = DefaultParameterSet)] + public WaitForServiceTypes For + { + get { return _waitFor; } + set + { + _waitFor = value; + _waitForSpecified = true; + } + } + private WaitForServiceTypes _waitFor = WaitForServiceTypes.PowerShell; + private bool _waitForSpecified = false; /// - /// delay parameter + /// Specify the Delay parameter. + /// The specific time interval (in second) to wait between network pings or service queries. /// - [Parameter] - [ValidateRange(1, 60)] - public Int32 Delay { get; set; } = 1; + [Parameter(ParameterSetName = DefaultParameterSet)] + [ValidateRange(1, Int16.MaxValue)] + public Int16 Delay + { + get { return (Int16)_delay; } + set + { + _delay = value; + _delaySpecified = true; + } + } + private int _delay = 5; + private bool _delaySpecified = false; /// - /// quiet parameter + /// Script to test if the PowerShell is ready /// - [Parameter(ParameterSetName = QuietParameterSet)] - public SwitchParameter Quiet - { - get { return quiet; } - set { quiet = value; } - } - private bool quiet = false; + private const string TestPowershellScript = @" +$array = @($input) +$result = @{} +foreach ($computerName in $array[1]) +{ + $ret = $null + $arguments = @{ + ComputerName = $computerName + ScriptBlock = { $true } + SessionOption = NewPSSessionOption -NoMachineProfile + ErrorAction = 'SilentlyContinue' + } + if ( $null -ne $array[0] ) + { + $arguments['Credential'] = $array[0] + } + $result[$computerName] = (Invoke-Command @arguments) -as [bool] +} +$result +"; -#endregion "parameters" -#region "Overrides" + /// + /// The indicator to use when show progress + /// + private string[] _indicator = { "|", "/", "-", "\\" }; -#if !CORECLR - ///// - ///// To Store the output for each ping reply - ///// - private ManagementObjectSearcher searcher; + /// + /// The activity id + /// + private int _activityId; -#endif - private TransportProtocol _transportProtocol = TransportProtocol.DCOM; - private readonly CancellationTokenSource cancel = new CancellationTokenSource(); - private Dictionary quietResults = new Dictionary(); /// - /// To begin processing Test-connection + /// After call 'Shutdown' on the target computer, wait a few + /// seconds for the restart to begin. /// - protected override void BeginProcessing() - { - base.BeginProcessing(); - // Verify parameter set + private const int SecondsToWaitForRestartToBegin = 25; - bool haveProtocolParam = this.MyInvocation.BoundParameters.ContainsKey("Protocol"); - bool haveWsmanAuthenticationParam = this.MyInvocation.BoundParameters.ContainsKey("WsmanAuthentication"); - bool haveDcomAuthenticationParam = this.MyInvocation.BoundParameters.ContainsKey("DcomAuthentication"); - bool haveDcomImpersonation = this.MyInvocation.BoundParameters.ContainsKey("Impersonation"); - _transportProtocol = (this.Protocol.Equals(ComputerWMIHelper.WsmanProtocol, StringComparison.OrdinalIgnoreCase) || (haveWsmanAuthenticationParam && !haveProtocolParam)) ? - TransportProtocol.WSMan : TransportProtocol.DCOM; + /// + /// Actual time out in seconds + /// + private int _timeoutInMilliseconds; - if (haveWsmanAuthenticationParam && (haveDcomAuthenticationParam || haveDcomImpersonation)) - { - string errMsg = StringUtil.Format(ComputerResources.StopCommandParamWSManAuthConflict, ComputerResources.StopCommandParamMessage); - ThrowTerminatingError( - new ErrorRecord( - new PSArgumentException(errMsg), - "InvalidParameter", - ErrorCategory.InvalidArgument, - this)); - } - - if ((_transportProtocol == TransportProtocol.DCOM) && haveWsmanAuthenticationParam) - { - string errMsg = StringUtil.Format(ComputerResources.StopCommandWSManAuthProtocolConflict, ComputerResources.StopCommandParamMessage); - ThrowTerminatingError( - new ErrorRecord( - new PSArgumentException(errMsg), - "InvalidParameter", - ErrorCategory.InvalidArgument, - this)); - } - - if ((_transportProtocol == TransportProtocol.WSMan) && (haveDcomAuthenticationParam || haveDcomImpersonation)) - { - string errMsg = StringUtil.Format(ComputerResources.StopCommandAuthProtocolConflict, ComputerResources.StopCommandParamMessage); - ThrowTerminatingError( - new ErrorRecord( - new PSArgumentException(errMsg), - "InvalidParameter", - ErrorCategory.InvalidArgument, - this)); - } - -#if CORECLR - if (this.MyInvocation.BoundParameters.ContainsKey("DcomAuthentication")) - { - string errMsg = StringUtil.Format(ComputerResources.InvalidParameterForCoreClr, "DcomAuthentication"); - PSArgumentException ex = new PSArgumentException(errMsg, ComputerResources.InvalidParameterForCoreClr); - ThrowTerminatingError(new ErrorRecord(ex, "InvalidParameterForCoreClr", ErrorCategory.InvalidArgument, null)); - } - - if (this.MyInvocation.BoundParameters.ContainsKey("Impersonation")) - { - string errMsg = StringUtil.Format(ComputerResources.InvalidParameterForCoreClr, "Impersonation"); - PSArgumentException ex = new PSArgumentException(errMsg, ComputerResources.InvalidParameterForCoreClr); - ThrowTerminatingError(new ErrorRecord(ex, "InvalidParameterForCoreClr", ErrorCategory.InvalidArgument, null)); - } - - if(this.Protocol.Equals(ComputerWMIHelper.DcomProtocol , StringComparison.OrdinalIgnoreCase)) - { - InvalidOperationException ex = new InvalidOperationException(ComputerResources.InvalidParameterDCOMNotSupported); - ThrowTerminatingError(new ErrorRecord(ex, "InvalidParameterDCOMNotSupported", ErrorCategory.InvalidOperation, null)); - } -#endif - - - //testing - } /// - /// Process Record + /// Indicate to exit /// - protected override void ProcessRecord() - { - switch (_transportProtocol) - { -#if !CORECLR - case TransportProtocol.DCOM: - processDCOMProtocolForTestConnection(); - break; -#endif + private bool _exit, _timeUp; + private readonly CancellationTokenSource _cancel = new CancellationTokenSource(); - case TransportProtocol.WSMan: - ProcessWSManProtocolForTestConnection(); - break; - } - } /// - /// to implement ^C + /// A waithandler to wait on. Current thread will wait on it during the delay interval. /// - protected override void StopProcessing() - { -#if !CORECLR - ManagementObjectSearcher stopSearcher = searcher; - if (stopSearcher != null) - { - try - { - stopSearcher.Dispose(); - } - catch (ObjectDisposedException) { } - } -#endif - try - { - cancel.Cancel(); - } - catch (ObjectDisposedException) { } - catch (AggregateException) { } - } -#endregion - -#region "Private Methods " - private string QueryString(string[] machinenames, bool escaperequired, bool selectrequired) - { - StringBuilder FilterString = new StringBuilder(); - if (selectrequired) - { - FilterString.Append("Select * from "); - FilterString.Append(ComputerWMIHelper.WMI_Class_PingStatus); - FilterString.Append(" where "); - } - FilterString.Append("(("); - for (int i = 0; i <= machinenames.Length - 1; i++) - { - FilterString.Append("Address='"); - string EscapeComp = machinenames[i].ToString(); - if (EscapeComp.Equals(".", StringComparison.CurrentCultureIgnoreCase)) - EscapeComp = "localhost"; - if (escaperequired) - { - EscapeComp = EscapeComp.Replace("\\", "\\\\'").ToString(); - EscapeComp = EscapeComp.Replace("'", "\\'").ToString(); - } - FilterString.Append(EscapeComp.ToString()); - FilterString.Append("'"); - if (i < machinenames.Length - 1) - { - FilterString.Append(" Or "); - } - } - FilterString.Append(")"); - FilterString.Append(" And "); - FilterString.Append("TimeToLive="); - FilterString.Append(TimeToLive); - FilterString.Append(" And "); - FilterString.Append("BufferSize="); - FilterString.Append(BufferSize); - FilterString.Append(" And "); - FilterString.Append("TimeOut="); - FilterString.Append(TimeOut); - FilterString.Append(")"); - return FilterString.ToString(); - } - private void ProcessPingStatus(Object pingStatusObj) - { - Dbg.Diagnostics.Assert(pingStatusObj != null, "Caller should verify that pingStatus != null"); - //Dbg.Diagnostics.Assert(pingStatusObj.ClassPath.ClassName.Equals("Win32_PingStatus"), "Caller should verify that pingStatus is a Win32_PingStatus object"); - string destinationAddress = null; - UInt32 primaryAddressResolutionStatus; - UInt32 statusCode; -#if !CORECLR - if (_transportProtocol == TransportProtocol.DCOM) - { - ManagementBaseObject pingStatus = (ManagementBaseObject)pingStatusObj; - - destinationAddress = (string)LanguagePrimitives.ConvertTo( - pingStatus.GetPropertyValue("Address"), - typeof(string), - CultureInfo.InvariantCulture); - - primaryAddressResolutionStatus = (UInt32)LanguagePrimitives.ConvertTo( - pingStatus.GetPropertyValue("PrimaryAddressResolutionStatus"), - typeof(UInt32), - CultureInfo.InvariantCulture); - statusCode = (UInt32)LanguagePrimitives.ConvertTo( - pingStatus.GetPropertyValue("StatusCode"), - typeof(UInt32), - CultureInfo.InvariantCulture); - } - else - { -#endif - CimInstance pingStatus = (CimInstance)pingStatusObj; - destinationAddress = (string)LanguagePrimitives.ConvertTo( - pingStatus.CimInstanceProperties["Address"].Value.ToString(), - typeof(string), - CultureInfo.InvariantCulture); - primaryAddressResolutionStatus = (UInt32)LanguagePrimitives.ConvertTo( - pingStatus.CimInstanceProperties["PrimaryAddressResolutionStatus"].Value, - typeof(UInt32), - CultureInfo.InvariantCulture); - statusCode = (UInt32)LanguagePrimitives.ConvertTo( - pingStatus.CimInstanceProperties["StatusCode"].Value, - typeof(UInt32), - CultureInfo.InvariantCulture); - -#if !CORECLR - } -#endif - if (primaryAddressResolutionStatus != 0) - { - if (!quiet) - { - Win32Exception win32Exception = new Win32Exception(unchecked((int)primaryAddressResolutionStatus)); - string message = StringUtil.Format(ComputerResources.NoPingResult, destinationAddress, win32Exception.Message); - Exception pingException = new System.Net.NetworkInformation.PingException(message, win32Exception); - ErrorRecord errorRecord = new ErrorRecord(pingException, "TestConnectionException", ErrorCategory.ResourceUnavailable, destinationAddress); - WriteError(errorRecord); - } - } - else - { - if (statusCode != 0) - { - if (!quiet) - { - Win32Exception win32Exception = new Win32Exception(unchecked((int)statusCode)); - string message = StringUtil.Format(ComputerResources.NoPingResult, destinationAddress, win32Exception.Message); - Exception pingException = new System.Net.NetworkInformation.PingException(message, win32Exception); - ErrorRecord errorRecord = new ErrorRecord(pingException, "TestConnectionException", ErrorCategory.ResourceUnavailable, destinationAddress); - WriteError(errorRecord); - } - } - else - { - this.quietResults[destinationAddress] = true; - if (!quiet) - { - WriteObject(pingStatusObj); - } - } - } - } - -#if !CORECLR - private void processDCOMProtocolForTestConnection() - { - ConnectionOptions options = ComputerWMIHelper.GetConnectionOptions(DcomAuthentication, this.Impersonation, this.Credential); - if (AsJob) - { - string filter = QueryString(ComputerName, true, false); - GetWmiObjectCommand WMICmd = new GetWmiObjectCommand(); - WMICmd.Filter = filter.ToString(); - WMICmd.Class = ComputerWMIHelper.WMI_Class_PingStatus; - WMICmd.ComputerName = Source; - WMICmd.Authentication = DcomAuthentication; - WMICmd.Impersonation = Impersonation; - WMICmd.ThrottleLimit = throttlelimit; - PSWmiJob wmiJob = new PSWmiJob(WMICmd, Source, throttlelimit, this.MyInvocation.MyCommand.Name, Count); - this.JobRepository.Add(wmiJob); - WriteObject(wmiJob); - } - else - { - int sourceCount = 0; - foreach (string fromcomp in Source) - { - try - { - sourceCount++; - EnumerationOptions enumOptions = new EnumerationOptions(); - enumOptions.UseAmendedQualifiers = true; - enumOptions.DirectRead = true; - - int destCount = 0; - foreach (var tocomp in ComputerName) - { - destCount++; - string querystring = QueryString(new string[] { tocomp }, true, true); - ObjectQuery query = new ObjectQuery(querystring); - ManagementScope scope = new ManagementScope(ComputerWMIHelper.GetScopeString(fromcomp, ComputerWMIHelper.WMI_Path_CIM), options); - scope.Options.EnablePrivileges = true; - scope.Connect(); - - using (searcher = new ManagementObjectSearcher(scope, query, enumOptions)) - { - for (int j = 0; j <= Count - 1; j++) - { - using (ManagementObjectCollection mobj = searcher.Get()) - { - int mobjCount = 0; - foreach (ManagementBaseObject obj in mobj) - { - using (obj) - { - mobjCount++; - - ProcessPingStatus(obj); - - // to delay the request, if case to avoid the delay for the last pingrequest - if (mobjCount < mobj.Count || j < Count - 1 || sourceCount < Source.Length || destCount < ComputerName.Length) - Thread.Sleep(Delay * 1000); - } - } - } - } - } - } - searcher = null; - } - catch (ManagementException e) - { - ErrorRecord errorRecord = new ErrorRecord(e, "TestConnectionException", ErrorCategory.InvalidOperation, null); - WriteError(errorRecord); - continue; - } - catch (System.Runtime.InteropServices.COMException e) - { - ErrorRecord errorRecord = new ErrorRecord(e, "TestConnectionException", ErrorCategory.InvalidOperation, null); - WriteError(errorRecord); - continue; - } - } - } - - if (quiet) - { - foreach (string destinationAddress in this.ComputerName) - { - bool destinationResult = false; - this.quietResults.TryGetValue(destinationAddress, out destinationResult); - WriteObject(destinationResult); - } - } - } -#endif - private void ProcessWSManProtocolForTestConnection() - { - if (AsJob) - { - // TODO: Need job for MI.Net WSMan protocol - // Early return of job object. - throw new PSNotSupportedException(); - } - - var operationOptions = new CimOperationOptions - { - Timeout = TimeSpan.FromMilliseconds(2000), - CancellationToken = cancel.Token - }; - int destCount = 0; - int sourceCount = 0; - foreach (string sourceComp in Source) - { - try - { - sourceCount++; - string sourceMachine; - if ((sourceComp.Equals("localhost", StringComparison.CurrentCultureIgnoreCase)) || (sourceComp.Equals(".", StringComparison.OrdinalIgnoreCase))) - { - sourceMachine = Dns.GetHostName(); - } - else - { - sourceMachine = sourceComp; - } - foreach (var tocomp in ComputerName) - { - destCount++; - string querystring = QueryString(new string[] { tocomp }, true, true); + private readonly ManualResetEventSlim _waitHandler = new ManualResetEventSlim(false); + private readonly Dictionary _computerInfos = new Dictionary(StringComparer.OrdinalIgnoreCase); - using (CimSession cimSession = RemoteDiscoveryHelper.CreateCimSession(sourceComp, this.Credential, WsmanAuthentication, cancel.Token, this)) - { - WriteVerbose(String.Format("WMI query {0} sent to {1}", querystring, sourceComp)); - for (int echoRequestCount = 0; echoRequestCount < Count; echoRequestCount++) - { - IEnumerable mCollection = cimSession.QueryInstances( - ComputerWMIHelper.CimOperatingSystemNamespace, - ComputerWMIHelper.CimQueryDialect, - querystring, - operationOptions); - int total = mCollection.ToList().Count; - int cimInsCount = 1; - foreach (CimInstance obj in mCollection) - { - ProcessPingStatus(obj); - cimInsCount++; - // to delay the request, if case to avoid the delay for the last pingrequest - if (cimInsCount < total || echoRequestCount < Count - 1 || sourceCount < Source.Length || destCount < ComputerName.Length) - Thread.Sleep(Delay * 1000); - } - } - } - } - } - catch (CimException ex) - { - ErrorRecord errorRecord = new ErrorRecord(ex, "TestConnectionException", ErrorCategory.InvalidOperation, null); - WriteError(errorRecord); - continue; - } - catch (System.Runtime.InteropServices.COMException e) - { - ErrorRecord errorRecord = new ErrorRecord(e, "TestConnectionException", ErrorCategory.InvalidOperation, null); - WriteError(errorRecord); - continue; - } - } + // CLR 4.0 Port note - use https://msdn.microsoft.com/en-us/library/system.net.networkinformation.ipglobalproperties.hostname(v=vs.110).aspx + private readonly string _shortLocalMachineName = Dns.GetHostName(); - if (quiet) - { - foreach (string destinationAddress in this.ComputerName) - { - bool destinationResult = false; - this.quietResults.TryGetValue(destinationAddress, out destinationResult); - WriteObject(destinationResult); - } - } - } + // And for this, use PsUtils.GetHostname() + private readonly string _fullLocalMachineName = Dns.GetHostEntryAsync("").Result.HostName; -#endregion "Private Methods " - } -#endregion Test-Connection -#if !CORECLR + private int _percent; + private string _status; + private string _activity; + private Timer _timer; + private System.Management.Automation.PowerShell _powershell; -#region Enable-ComputerRestore + private const string StageVerification = "VerifyStage"; + private const string WmiConnectionTest = "WMI"; + private const string WinrmConnectionTest = "WinRM"; + private const string PowerShellConnectionTest = "PowerShell"; - /// - /// Cmdlet for Enable-ComputerRestore - /// - [Cmdlet(VerbsLifecycle.Enable, "ComputerRestore", SupportsShouldProcess = true, HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135209")] - public sealed class EnableComputerRestoreCommand : PSCmdlet, IDisposable - { -#region Parameters - /// - /// Specifies the Drive on which the system restore will be enabled. - /// The drive string should be of the form "C:\". - /// - [Parameter(Position = 0, Mandatory = true)] - [ValidateNotNullOrEmpty] - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - public string[] Drive { get; set; } +#endregion "parameters and PrivateData" - #endregion Parameters - private const string ErrorBase = "ComputerResources"; - private ManagementClass WMIClass; #region "IDisposable Members" /// @@ -716,5561 +388,1210 @@ public void Dispose(bool disposing) { if (disposing) { - if (WMIClass != null) + if (_timer != null) + { + _timer.Dispose(); + } + + _waitHandler.Dispose(); + _cancel.Dispose(); + if (_powershell != null) { - WMIClass.Dispose(); + _powershell.Dispose(); } } } #endregion "IDisposable Members" -#region Overrides +#region "Private Methods" /// - /// To Enable the Restore Point of the drives + /// Validate parameters for 'DefaultSet' + /// 1. When the Wait is specified, the computername cannot contain the local machine + /// 2. If the local machine is present, make sure it is at the end of the list (so the remote ones get restarted before the local machine reboot). /// - protected override void BeginProcessing() + private void ValidateComputerNames() { - // system restore APIs are not supported on ARM platform - if (ComputerWMIHelper.SkipSystemRestoreOperationForARMPlatform(this)) - { - return; - } - - ManagementScope scope = new ManagementScope(ComputerWMIHelper.WMI_Path_Default); - scope.Connect(); - WMIClass = new ManagementClass(ComputerWMIHelper.WMI_Class_SystemRestore); - WMIClass.Scope = scope; - int retValue; - //get the system drive - string sysdrive = System.Environment.ExpandEnvironmentVariables("%SystemDrive%"); - sysdrive = String.Concat(new string[] { sysdrive, "\\" }); - + bool containLocalhost = false; + _validatedComputerNames.Clear(); - if (ComputerWMIHelper.ContainsSystemDrive(Drive, sysdrive)) + foreach (string name in ComputerName) { - object[] input = { sysdrive }; - try + ErrorRecord error = null; + string targetComputerName = ComputerWMIHelper.ValidateComputerName(name, _shortLocalMachineName, _fullLocalMachineName, ref error); + if (targetComputerName == null) { - retValue = Convert.ToInt32(WMIClass.InvokeMethod("Enable", input), System.Globalization.CultureInfo.CurrentCulture); - //if success (return value is 0 or if already enabled (error code is 1056 in XP and 0 in vista) - if ((retValue.Equals(0)) || (retValue.Equals(ComputerWMIHelper.ErrorCode_Service))) - { - string driveNew; - foreach (string drive in Drive) //for each input drive - { - if (!ShouldProcess(drive)) - { - continue; - } - if (!drive.EndsWith("\\", StringComparison.CurrentCultureIgnoreCase)) - { - driveNew = String.Concat(drive, "\\"); - } - else - driveNew = drive; - if (!ComputerWMIHelper.IsValidDrive(driveNew))//if not valid drive,throw error - { - Exception Ex = new ArgumentException(StringUtil.Format(ComputerResources.InvalidDrive, drive)); - WriteError(new ErrorRecord(Ex, "EnableComputerRestoreInvalidDrive", ErrorCategory.InvalidData, null)); - continue; - } - //parameter for Enable method - //if the input drive is not system drive - if (!driveNew.Equals(sysdrive, StringComparison.OrdinalIgnoreCase)) - { - object[] inputDrive = { driveNew }; - retValue = Convert.ToInt32(WMIClass.InvokeMethod("Enable", inputDrive), System.Globalization.CultureInfo.CurrentCulture); - - //if not enabled, retry again - if (retValue.Equals(ComputerWMIHelper.ErrorCode_Interface)) - { - retValue = Convert.ToInt32(WMIClass.InvokeMethod("Enable", inputDrive), System.Globalization.CultureInfo.CurrentCulture); - } - } - //if not success and if it is not already enabled (error code is 1056 in XP) - // Error 1717 - The interface is unknown. Even though this comes sometimes . The Drive is getting enabled. - if (!(retValue.Equals(0)) && !(retValue.Equals(ComputerWMIHelper.ErrorCode_Service)) && !(retValue.Equals(ComputerWMIHelper.ErrorCode_Interface))) - { - Exception Ex = new ArgumentException(StringUtil.Format(ComputerResources.NotEnabled, drive)); - WriteError(new ErrorRecord(Ex, "EnableComputerRestoreNotEnabled", ErrorCategory.InvalidOperation, null)); - continue; - } - } - } - else + if (error != null) { - ArgumentException Ex = new ArgumentException(StringUtil.Format(ComputerResources.NotEnabled, sysdrive)); - WriteError(new ErrorRecord(Ex, "EnableComputerRestoreNotEnabled", ErrorCategory.InvalidOperation, null)); + WriteError(error); } + continue; } - catch (ManagementException e) + + if (targetComputerName.Equals(ComputerWMIHelper.localhostStr, StringComparison.OrdinalIgnoreCase)) { - if ((e.ErrorCode.Equals(ManagementStatus.NotFound)) || (e.ErrorCode.Equals(ManagementStatus.InvalidClass))) - { - ErrorRecord er = new ErrorRecord(new ArgumentException(StringUtil.Format(ComputerResources.NotSupported)), null, ErrorCategory.InvalidOperation, null); - WriteError(er); - } - else - { - ErrorRecord errorRecord = new ErrorRecord(e, "GetWMIManagementException", ErrorCategory.InvalidOperation, null); - WriteError(errorRecord); - } + containLocalhost = true; } - catch (COMException e) + else if (!_uniqueComputerNames.Contains(targetComputerName)) { - if (string.IsNullOrEmpty(e.Message)) - { - Exception Ex = new ArgumentException(StringUtil.Format(ComputerResources.SystemRestoreServiceDisabled)); - WriteError(new ErrorRecord(Ex, "ServiceDisabled", ErrorCategory.InvalidOperation, null)); - } - else - { - ErrorRecord errorRecord = new ErrorRecord(e, "COMException", ErrorCategory.InvalidOperation, null); - WriteError(errorRecord); - } + _validatedComputerNames.Add(targetComputerName); + _uniqueComputerNames.Add(targetComputerName); } } - else + + // Force wait with a test hook even if we're on the local computer + if (! InternalTestHooks.TestWaitStopComputer && Wait && containLocalhost) { - ArgumentException Ex = new ArgumentException(StringUtil.Format(ComputerResources.NoSystemDrive)); - WriteError(new ErrorRecord(Ex, "EnableComputerNoSystemDrive", ErrorCategory.InvalidArgument, null)); + // The local machine will be ignored, and an error will be emitted. + InvalidOperationException ex = new InvalidOperationException(ComputerResources.CannotWaitLocalComputer); + WriteError(new ErrorRecord(ex, "CannotWaitLocalComputer", ErrorCategory.InvalidOperation, null)); + containLocalhost = false; } - }//end of BeginProcessing - /// - /// to implement ^C - /// - protected override void StopProcessing() - { - if (WMIClass != null) + // Add the localhost to the end of the list, so we will restart remote machines + // before we restart the local one. + if (containLocalhost) { - WMIClass.Dispose(); + _validatedComputerNames.Add(ComputerWMIHelper.localhostStr); } } -#endregion Overrides - }//end of class -#endregion - -#region Disable-ComputerRestore - - /// - /// This cmdlet is to Disable Computer Restore points. - /// - [Cmdlet(VerbsLifecycle.Disable, "ComputerRestore", SupportsShouldProcess = true, HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135207")] - public sealed class DisableComputerRestoreCommand : PSCmdlet, IDisposable - { -#region Parameters - /// - /// Specifies the Drive on which the system restore will be enabled. - /// The drive string should be of the form "C:\". - /// - [Parameter(Position = 0, Mandatory = true)] - [ValidateNotNullOrEmpty] - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - public string[] Drive { get; set; } - - #endregion Parameters - - private ManagementClass WMIClass; - private const string ErrorBase = "ComputerResources"; -#region "IDisposable Members" - /// - /// Dispose Method + /// Write out progress /// - public void Dispose() + /// + /// + /// + /// + private void WriteProgress(string activity, string status, int percent, ProgressRecordType progressRecordType) { - this.Dispose(true); - // Use SuppressFinalize in case a subclass - // of this type implements a finalizer. - GC.SuppressFinalize(this); + ProgressRecord progress = new ProgressRecord(_activityId, activity, status); + progress.PercentComplete = percent; + progress.RecordType = progressRecordType; + WriteProgress(progress); } /// - /// Dispose Method. + /// Calculate the progress percentage /// - /// - public void Dispose(bool disposing) + /// + /// + private int CalculateProgressPercentage(string currentStage) { - if (disposing) + switch (currentStage) { - if (WMIClass != null) - { - WMIClass.Dispose(); - } + case StageVerification: + return _waitFor.Equals(WaitForServiceTypes.Wmi) || _waitFor.Equals(WaitForServiceTypes.WinRM) + ? 33 + : 20; + case WmiConnectionTest: + return _waitFor.Equals(WaitForServiceTypes.Wmi) ? 66 : 40; + case WinrmConnectionTest: + return _waitFor.Equals(WaitForServiceTypes.WinRM) ? 66 : 60; + case PowerShellConnectionTest: + return 80; + default: + break; } - } -#endregion "IDisposable Members" - -#region Overrides + Dbg.Diagnostics.Assert(false, "CalculateProgressPercentage should never hit the default case"); + return 0; + } /// - /// To Disable the Restore Point of the drives + /// Event handler for the timer /// - protected override void BeginProcessing() + /// + private void OnTimedEvent(object s) { - // system restore APIs are not supported on ARM platform - if (ComputerWMIHelper.SkipSystemRestoreOperationForARMPlatform(this)) - { - return; - } + _exit = _timeUp = true; + _cancel.Cancel(); + _waitHandler.Set(); - ManagementScope scope = new ManagementScope(ComputerWMIHelper.WMI_Path_Default); - scope.Connect(); - WMIClass = new ManagementClass(ComputerWMIHelper.WMI_Class_SystemRestore); - WMIClass.Scope = scope; - string driveNew; - foreach (string drive in Drive) + if (_powershell != null) { - if (!ShouldProcess(drive)) - { - continue; - } - - if (!drive.EndsWith("\\", StringComparison.CurrentCultureIgnoreCase)) - { - driveNew = String.Concat(drive, "\\"); - } - else - driveNew = drive; + _powershell.Stop(); + _powershell.Dispose(); + } + } + private class ComputerInfo + { + internal string LastBootUpTime; + internal bool RebootComplete; + } - if (!ComputerWMIHelper.IsValidDrive(driveNew)) - { - ErrorRecord er = new ErrorRecord(new ArgumentException(StringUtil.Format(ComputerResources.NotValidDrive, drive)), null, ErrorCategory.InvalidData, null); - WriteError(er); - continue; - } - else + private List TestRestartStageUsingWsman(IEnumerable computerNames, List nextTestList, CancellationToken token) + { + var restartStageTestList = new List(); + var operationOptions = new CimOperationOptions + { + Timeout = TimeSpan.FromMilliseconds(2000), + CancellationToken = token + }; + foreach (var computer in computerNames) + { + try { - try - { - object[] input = { driveNew }; - int retValue = Convert.ToInt32(WMIClass.InvokeMethod("Disable", input), System.Globalization.CultureInfo.CurrentCulture); - // Error 1717 - The interface is unknown. Even though this comes sometimes . The Drive is getting disabled. - if (!(retValue.Equals(0)) && !(retValue.Equals(ComputerWMIHelper.ErrorCode_Interface))) - { - ErrorRecord er = new ErrorRecord(new ArgumentException(StringUtil.Format(ComputerResources.NotDisabled, drive)), null, ErrorCategory.InvalidOperation, null); - WriteError(er); - continue; - } - } - catch (ManagementException e) + if (token.IsCancellationRequested) { break; } + using (CimSession cimSession = RemoteDiscoveryHelper.CreateCimSession(computer, Credential, WsmanAuthentication, token, this)) { - if ((e.ErrorCode.Equals(ManagementStatus.NotFound)) || (e.ErrorCode.Equals(ManagementStatus.InvalidClass))) + bool itemRetrieved = false; + IEnumerable mCollection = cimSession.QueryInstances( + ComputerWMIHelper.CimOperatingSystemNamespace, + ComputerWMIHelper.CimQueryDialect, + "Select * from " + ComputerWMIHelper.WMI_Class_OperatingSystem, + operationOptions); + foreach (CimInstance os in mCollection) { - ErrorRecord er = new ErrorRecord(new ArgumentException(StringUtil.Format(ComputerResources.NotSupported)), null, ErrorCategory.InvalidOperation, null); - WriteError(er); + itemRetrieved = true; + string newLastBootUpTime = os.CimInstanceProperties["LastBootUpTime"].Value.ToString(); + string oldLastBootUpTime = _computerInfos[computer].LastBootUpTime; + + if (string.Compare(newLastBootUpTime, oldLastBootUpTime, StringComparison.OrdinalIgnoreCase) != 0) + { + _computerInfos[computer].RebootComplete = true; + nextTestList.Add(computer); + } + else + { + restartStageTestList.Add(computer); + } } - else + + if (!itemRetrieved) { - ErrorRecord errorRecord = new ErrorRecord(e, "GetWMIManagementException", ErrorCategory.InvalidOperation, null); - WriteError(errorRecord); + restartStageTestList.Add(computer); } } - catch (COMException e) + } + catch (CimException) + { + restartStageTestList.Add(computer); + } + catch (Exception) + { + restartStageTestList.Add(computer); + } + } + + return restartStageTestList; + } + + private List SetUpComputerInfoUsingWsman(IEnumerable computerNames, CancellationToken token) + { + var validComputerNameList = new List(); + var operationOptions = new CimOperationOptions + { + Timeout = TimeSpan.FromMilliseconds(2000), + CancellationToken = token + }; + foreach (var computer in computerNames) + { + try + { + using (CimSession cimSession = RemoteDiscoveryHelper.CreateCimSession(computer, Credential, WsmanAuthentication, token, this)) { - if (string.IsNullOrEmpty(e.Message)) + bool itemRetrieved = false; + IEnumerable mCollection = cimSession.QueryInstances( + ComputerWMIHelper.CimOperatingSystemNamespace, + ComputerWMIHelper.CimQueryDialect, + "Select * from " + ComputerWMIHelper.WMI_Class_OperatingSystem, + operationOptions); + foreach (CimInstance os in mCollection) { - Exception Ex = new ArgumentException(StringUtil.Format(ComputerResources.SystemRestoreServiceDisabled)); - WriteError(new ErrorRecord(Ex, "ServiceDisabled", ErrorCategory.InvalidOperation, null)); + itemRetrieved = true; + if (!_computerInfos.ContainsKey(computer)) + { + var info = new ComputerInfo + { + LastBootUpTime = os.CimInstanceProperties["LastBootUpTime"].Value.ToString(), + RebootComplete = false + }; + _computerInfos.Add(computer, info); + validComputerNameList.Add(computer); + } } - else + + if (!itemRetrieved) { - ErrorRecord errorRecord = new ErrorRecord(e, "COMException", ErrorCategory.InvalidOperation, null); - WriteError(errorRecord); + string errMsg = StringUtil.Format(ComputerResources.RestartComputerSkipped, computer, ComputerResources.CannotGetOperatingSystemObject); + var error = new ErrorRecord(new InvalidOperationException(errMsg), "RestartComputerSkipped", + ErrorCategory.OperationStopped, computer); + this.WriteError(error); } } } + catch (CimException ex) + { + string errMsg = StringUtil.Format(ComputerResources.RestartComputerSkipped, computer, ex.Message); + var error = new ErrorRecord(new InvalidOperationException(errMsg), "RestartComputerSkipped", + ErrorCategory.OperationStopped, computer); + this.WriteError(error); + } + catch (Exception ex) + { + string errMsg = StringUtil.Format(ComputerResources.RestartComputerSkipped, computer, ex.Message); + var error = new ErrorRecord(new InvalidOperationException(errMsg), "RestartComputerSkipped", + ErrorCategory.OperationStopped, computer); + this.WriteError(error); + } } - } - /// - /// to implement ^C - /// - protected override void StopProcessing() - { - if (WMIClass != null) - { - WMIClass.Dispose(); - } + return validComputerNameList; } -#endregion Overrides - }//end of class -#endregion Disable-ComputerRestore - -#region Checkpoint-Computer - - /// - /// Creates the Restore Point for the Local computer - /// - - [Cmdlet(VerbsData.Checkpoint, "Computer", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135197")] - public class CheckpointComputerCommand : PSCmdlet, IDisposable - { -#region Parameters - - /// - /// The description to be displayed so the user can easily identify a restore point. - /// - [Parameter(Position = 0, Mandatory = true)] - [ValidateNotNullOrEmpty] - public string Description { get; set; } - - - /// - /// The type of restore point. - /// - [Parameter(Position = 1)] - [Alias("RPT")] - [ValidateSetAttribute(new string[] { "APPLICATION_INSTALL", "APPLICATION_UNINSTALL", "DEVICE_DRIVER_INSTALL", "MODIFY_SETTINGS", "CANCELLED_OPERATION" })] - [ValidateNotNullOrEmpty] - public string RestorePointType + private void WriteOutTimeoutError(IEnumerable computerNames) { - get { return _restorepointtype; } - set + const string errorId = "RestartComputerTimeout"; + foreach (string computer in computerNames) { - // null check is not needed (because of ValidateNotNullOrEmpty), - // but we have to include it to silence OACR - if (value == null) - { - throw PSTraceSource.NewArgumentNullException("value"); + string errorMsg = StringUtil.Format(ComputerResources.RestartcomputerFailed, computer, ComputerResources.TimeoutError); + var exception = new RestartComputerTimeoutException(computer, Timeout, errorMsg, errorId); + var error = new ErrorRecord(exception, errorId, ErrorCategory.OperationTimeout, computer); + if (! InternalTestHooks.TestWaitStopComputer ) { + WriteError(error); } - - _restorepointtype = value; - if (_restorepointtype.Equals("APPLICATION_INSTALL", StringComparison.OrdinalIgnoreCase)) - intRestorePoint = 0; - else if (_restorepointtype.Equals("APPLICATION_UNINSTALL", StringComparison.OrdinalIgnoreCase)) - intRestorePoint = 1; - else if (_restorepointtype.Equals("DEVICE_DRIVER_INSTALL", StringComparison.OrdinalIgnoreCase)) - intRestorePoint = 10; - else if (_restorepointtype.Equals("MODIFY_SETTINGS", StringComparison.OrdinalIgnoreCase)) - intRestorePoint = 12; - else if (_restorepointtype.Equals("CANCELLED_OPERATION", StringComparison.OrdinalIgnoreCase)) - intRestorePoint = 13; } } - private string _restorepointtype = "APPLICATION_INSTALL"; -#endregion Parameters -#region private +#endregion "Private Methods" - private DateTime lastTimeProgressWasWritten = DateTime.UtcNow; - private int intRestorePoint = 0; - private int ret = int.MaxValue; - /// - /// Shared Exception. Used when exception thrown from the Restore point thread. - /// - private static Exception exceptionfromnewthread = null; +#region "Internal Methods" - private void WriteProgress(string statusDescription, int? percentComplete) + internal static List TestWmiConnectionUsingWsman(List computerNames, List nextTestList, CancellationToken token, PSCredential credential, string wsmanAuthentication, PSCmdlet cmdlet) { - ProgressRecordType recordType; - if (percentComplete.HasValue && percentComplete.Value == 100) + // Check if the WMI service "Winmgmt" is started + const string wmiServiceQuery = "Select * from " + ComputerWMIHelper.WMI_Class_Service + " Where name = 'Winmgmt'"; + var wmiTestList = new List(); + var operationOptions = new CimOperationOptions { - recordType = ProgressRecordType.Completed; - } - else + Timeout = TimeSpan.FromMilliseconds(2000), + CancellationToken = token + }; + foreach (var computer in computerNames) { - recordType = ProgressRecordType.Processing; - } + try + { + if (token.IsCancellationRequested) { break; } + using (CimSession cimSession = RemoteDiscoveryHelper.CreateCimSession(computer, credential, wsmanAuthentication, token, cmdlet)) + { + bool itemRetrieved = false; + IEnumerable mCollection = cimSession.QueryInstances( + ComputerWMIHelper.CimOperatingSystemNamespace, + ComputerWMIHelper.CimQueryDialect, + wmiServiceQuery, + operationOptions); + foreach (CimInstance service in mCollection) + { + itemRetrieved = true; + if (LanguagePrimitives.IsTrue(service.CimInstanceProperties["Started"].Value)) + { + nextTestList.Add(computer); + } + else + { + wmiTestList.Add(computer); + } + } - if (recordType == ProgressRecordType.Processing) - { - TimeSpan timeSinceProgressWasWrittenLast = DateTime.UtcNow - lastTimeProgressWasWritten; - if (timeSinceProgressWasWrittenLast < TimeSpan.FromMilliseconds(200)) + if (!itemRetrieved) + { + wmiTestList.Add(computer); + } + } + } + catch (CimException) { - return; + wmiTestList.Add(computer); + } + catch (Exception) + { + wmiTestList.Add(computer); } - } - lastTimeProgressWasWritten = DateTime.UtcNow; - - string activityDescription = StringUtil.Format(ComputerResources.ProgressActivity); - ProgressRecord progressRecord = new ProgressRecord( - 1905347723, // unique id - activityDescription, - statusDescription); - - if (percentComplete.HasValue) - { - progressRecord.PercentComplete = percentComplete.Value; } - progressRecord.RecordType = recordType; - this.WriteProgress(progressRecord); + return wmiTestList; } - private void WriteProgress(DateTime starttime) + /// + /// Test the PowerShell state for the restarting computer + /// + /// + /// + /// + /// + /// + internal static List TestPowerShell(List computerNames, List nextTestList, System.Management.Automation.PowerShell powershell, PSCredential credential) { - int percentageCompleted = ProgressRecord.GetPercentageComplete(starttime, TimeSpan.FromSeconds(90)); - if (percentageCompleted < 100) - { - WriteProgress(StringUtil.Format(ComputerResources.ProgressStatusCreatingRestorePoint, percentageCompleted), percentageCompleted); - } - } + List psList = new List(); - private DateTime startUtcTime, startLocalTime; - private void WriteProgress() - { - while (true) + try { - WriteProgress(this.startUtcTime); - System.Threading.Thread.Sleep(1000); - if (exceptionfromnewthread == null) + Collection psObjectCollection = powershell.Invoke(new object[] { credential, computerNames.ToArray() }); + if (psObjectCollection == null) { - if (ret == 0) - { - if (this.IsRestorePointCreated(Description, this.startLocalTime)) - { - break; - } - } - else if (ret != int.MaxValue) - { - // Invocation is complete with error - break; - } + Dbg.Diagnostics.Assert(false, "This should never happen. Invoke should never return null."); } - else + + // If ^C or timeout happens when we are in powershell.Invoke(), the psObjectCollection might be empty + if (psObjectCollection.Count == 0) { - // Exception is thrown, breaking the loop - break; + return computerNames; } - } - WriteProgress(StringUtil.Format(ComputerResources.ProgressStatusCompleted), 100); - } + object result = PSObject.Base(psObjectCollection[0]); + Hashtable data = result as Hashtable; - private void CreateRestorePoint() - { - ManagementClass WMIClass = null; - try - { - ManagementScope scope = new ManagementScope(ComputerWMIHelper.WMI_Path_Default); - scope.Connect(); - WMIClass = new ManagementClass(ComputerWMIHelper.WMI_Class_SystemRestore); - WMIClass.Scope = scope; - - //create restore point - ManagementBaseObject inParams = WMIClass.GetMethodParameters("CreateRestorePoint"); - object[] param = { Description, intRestorePoint, 100 }; // the event type will be always 100,Begin_System_Change - ret = Convert.ToInt32(WMIClass.InvokeMethod("CreateRestorePoint", param), System.Globalization.CultureInfo.CurrentCulture); + Dbg.Diagnostics.Assert(data != null, "data should never be null"); + Dbg.Diagnostics.Assert(data.Count == computerNames.Count, "data should contain results for all computers in computerNames"); + + foreach (string computer in computerNames) + { + if (LanguagePrimitives.IsTrue(data[computer])) + { + nextTestList.Add(computer); + } + else + { + psList.Add(computer); + } + } } - catch (Exception ex) + catch (PipelineStoppedException) { - // We catch all exceptions because we don't want the exception to be thrown from a separate worker thread - exceptionfromnewthread = ex; + // powershell.Stop() is invoked because timeout expires, or Ctrl+C is pressed } - finally + catch (ObjectDisposedException) { - if (WMIClass != null) - { - WMIClass.Dispose(); - } + // powershell.dispose() is invoked because timeout expires, or Ctrl+C is pressed } - } - -#endregion - -#region "IDisposable Members" - /// - /// Dispose Method - /// - public void Dispose() - { - // Use SuppressFinalize in case a subclass - // of this type implements a finalizer. - GC.SuppressFinalize(this); + return psList; } -#endregion "IDisposable Members" +#endregion "Internal Methods" + +#region "Overrides" /// /// BeginProcessing method. /// protected override void BeginProcessing() { - // system restore APIs are not supported on ARM platform - if (ComputerWMIHelper.SkipSystemRestoreOperationForARMPlatform(this)) - { - return; - } - - //Setting Exception from the new thread always to null - exceptionfromnewthread = null; - - //on vista, CANCELLED_OPERATION restorepointtype does not work - if ((Environment.OSVersion.Version.Major >= 6) && (intRestorePoint == 13)) + // Timeout, For, Delay, Progress cannot be present if Wait is not present + if ((_timeoutSpecified || _waitForSpecified || _delaySpecified) && !Wait) { - ErrorRecord er = new ErrorRecord(new InvalidOperationException(StringUtil.Format(ComputerResources.NotSupported)), null, ErrorCategory.InvalidOperation, null); - ThrowTerminatingError(er); + InvalidOperationException ex = new InvalidOperationException(ComputerResources.RestartComputerInvalidParameter); + ThrowTerminatingError(new ErrorRecord(ex, "RestartComputerInvalidParameter", ErrorCategory.InvalidOperation, null)); } - if (!CanCreateNewRestorePoint(DateTime.Now)) { return; } - - this.startUtcTime = DateTime.UtcNow; - this.startLocalTime = DateTime.Now; - ThreadStart start = new ThreadStart(this.CreateRestorePoint); - Thread thread = new Thread(start); - thread.Start(); - WriteProgress(); - if (exceptionfromnewthread == null) - { - if (ret.Equals(1058)) - { - Exception Ex = new ArgumentException(StringUtil.Format(ComputerResources.ServiceDisabled)); - WriteError(new ErrorRecord(Ex, "CheckpointComputerServiceDisabled", ErrorCategory.InvalidOperation, null)); - } - else if (!(ret.Equals(0)) && !(ret.Equals(1058))) - { - Exception Ex = new ArgumentException(StringUtil.Format(ComputerResources.RestorePointNotCreated)); - WriteError(new ErrorRecord(Ex, "CheckpointComputerPointNotCreated", ErrorCategory.InvalidOperation, null)); - } - } - else + if (Wait) { - if (exceptionfromnewthread is System.Runtime.InteropServices.COMException) + _activityId = (new Random()).Next(); + if (_timeout == -1 || _timeout >= int.MaxValue / 1000) { - if (string.IsNullOrEmpty(exceptionfromnewthread.Message)) - { - Exception e = new ArgumentException(StringUtil.Format(ComputerResources.SystemRestoreServiceDisabled)); - WriteError(new ErrorRecord(e, "ServiceDisabled", ErrorCategory.InvalidOperation, null)); - } - else - { - ErrorRecord errorRecord = new ErrorRecord(exceptionfromnewthread, "COMException", ErrorCategory.InvalidOperation, null); - WriteError(errorRecord); - } + _timeoutInMilliseconds = int.MaxValue; } - else if (exceptionfromnewthread is ManagementException) + else { - if (((ManagementException)exceptionfromnewthread).ErrorCode.Equals(ManagementStatus.NotFound) || ((ManagementException)exceptionfromnewthread).ErrorCode.Equals(ManagementStatus.InvalidClass)) - { - Exception e = new ArgumentException(StringUtil.Format(ComputerResources.NotSupported)); - WriteError(new ErrorRecord(e, "CheckpointComputerNotSupported", ErrorCategory.InvalidOperation, null)); - } - else - { - ErrorRecord errorRecord = new ErrorRecord(exceptionfromnewthread, "GetWMIManagementException", ErrorCategory.InvalidOperation, null); - WriteError(errorRecord); - } + _timeoutInMilliseconds = _timeout * 1000; } - else + + // We don't support combined service types for now + switch (_waitFor) { - // For other exception we caught from the worker thread, we throw it out here - throw exceptionfromnewthread; + case WaitForServiceTypes.Wmi: + case WaitForServiceTypes.WinRM: + break; + case WaitForServiceTypes.PowerShell: + _powershell = System.Management.Automation.PowerShell.Create(); + _powershell.AddScript(TestPowershellScript); + break; + default: + InvalidOperationException ex = new InvalidOperationException(ComputerResources.NoSupportForCombinedServiceType); + ErrorRecord error = new ErrorRecord(ex, "NoSupportForCombinedServiceType", ErrorCategory.InvalidOperation, (int)_waitFor); + ThrowTerminatingError(error); + break; } } - }//End BeginProcessing() + } - private bool CanCreateNewRestorePoint(DateTime startTime) + /// + /// ProcessRecord method. + /// + [SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling")] + protected override void ProcessRecord() { - const string srRegistryKeyPath = @"Software\Microsoft\Windows NT\CurrentVersion\SystemRestore"; - const string srFrequencyKeyName = "SystemRestorePointCreationFrequency"; - Version osVersion = Environment.OSVersion.Version; - int timeInterval = 1440; // Default value: 24 hours * 60 min/hr - bool canCreate = true; - - // From Win8+, the default frequency of restore point creation is 24 hours, but the user - // can create the DWORD value SystemRestorePointCreationFrequency under the registry key - // HKLM\Software\Microsoft\Windows NT\CurrentVersion\SystemRestore, and the value of it - // can change the frequency of restore point creation. There are three cases here: - // 1. Such registry key doesn't exist. We use the default setting: 24 hours. - // 2. Registry key value is 0. No frequency limitation, new restore point can be created anytime. - // 3. Registry key value is integer N, the time interval is N minutes. - if ((osVersion.Major > 6) || (osVersion.Major == 6 && osVersion.Minor >= 2)) + // Validate parameters + ValidateComputerNames(); + + object[] flags = new object[] { 2, 0 }; + if (Force) flags[0] = forcedReboot; + + if (ParameterSetName.Equals(DefaultParameterSet, StringComparison.OrdinalIgnoreCase)) { - using (RegistryKey key = Registry.LocalMachine.OpenSubKey(srRegistryKeyPath)) + if (Wait && _timeout != 0) { - if (key != null) - { - object value = key.GetValue(srFrequencyKeyName); - if (value is int) { timeInterval = (int)value; } - } + _validatedComputerNames = + SetUpComputerInfoUsingWsman(_validatedComputerNames, _cancel.Token); } - var objectQuery = new ObjectQuery { QueryString = "select * from " + ComputerWMIHelper.WMI_Class_SystemRestore }; - var scope = new ManagementScope(ComputerWMIHelper.WMI_Path_Default); - scope.Connect(); - - try + foreach (string computer in _validatedComputerNames) { - DateTime lastCreationTime = DateTime.MinValue; - using (var searcher = new ManagementObjectSearcher(scope, objectQuery)) - { - foreach (ManagementObject obj in searcher.Get()) - { - using (obj) - { - DateTime creationTime = - ManagementDateTimeConverter.ToDateTime(obj.Properties["CreationTime"].Value.ToString()); - if (creationTime > lastCreationTime) - { - lastCreationTime = creationTime; - } - } - } - } + bool isLocal = false; + string compname; - TimeSpan span = startTime.Subtract(lastCreationTime); - canCreate = (span.TotalMinutes >= timeInterval); - } - catch (Exception ex) - { - // Fail to retrieve restore points - if (ex is ManagementException || ex is COMException) + if (computer.Equals("localhost", StringComparison.CurrentCultureIgnoreCase)) { - // Something is wrong with System Restore (it may not be supported). We continue to let the - // call to "CreateRestorePoint" happen, and will handle the exception generated by that call. - canCreate = true; + compname = _shortLocalMachineName; + isLocal = true; } else { - // Not sure what happened, so we'd better terminate the execution and report the error. - string errorMsg = StringUtil.Format(ComputerResources.FailToRetrieveLastRestorePoint, ex.Message); - ThrowTerminatingError( - new ErrorRecord(new InvalidOperationException(errorMsg), - "FailToRetrieveLastRestorePoint", - ErrorCategory.InvalidOperation, null)); + compname = computer; } - } - } - if (!canCreate) - { - // A new restore point cannot be created yet, so we write out warning message. - WriteWarning(StringUtil.Format(ComputerResources.CannotCreateRestorePointWarning, timeInterval)); - } + // Generate target and action strings + string action = + StringUtil.Format( + ComputerResources.RestartComputerAction, + isLocal ? ComputerResources.LocalShutdownPrivilege : ComputerResources.RemoteShutdownPrivilege); + string target = + isLocal ? StringUtil.Format(ComputerResources.DoubleComputerName, "localhost", compname) : compname; - return canCreate; - } + if (!ShouldProcess(target, action)) + { + continue; + } - private bool IsRestorePointCreated(string description, DateTime starttime) - { - bool foundrestorepoint = false; - ManagementScope scope = new ManagementScope(ComputerWMIHelper.WMI_Path_Default); - scope.Connect(); - - ObjectQuery objquery = new ObjectQuery(); - StringBuilder sb = new StringBuilder("select * from "); - sb.Append(ComputerWMIHelper.WMI_Class_SystemRestore); - sb.Append(" where description = '"); - sb.Append(description.Replace("'", "\\'")); - sb.Append("'"); - objquery.QueryString = sb.ToString(); + bool isSuccess = + ComputerWMIHelper.InvokeWin32ShutdownUsingWsman(this, isLocal, compname, flags, Credential, WsmanAuthentication, ComputerResources.RestartcomputerFailed, "RestartcomputerFailed", _cancel.Token); - try - { - using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, objquery)) - { - if (searcher.Get().Count > 0) + if (isSuccess && Wait && _timeout != 0) { - foreach (ManagementObject obj in searcher.Get()) - { - using (obj) - { - // we are adding 1 second to creationTime to account for the fact that milliseconds - // are not reported in CreationTime property - it is possible to have - // startTime = 2009-07-20 9:35:18.123 - // creationTime = 2009-07-20 9:35:18 - // which would indicate creationTime < startTime - DateTime creationTime = ManagementDateTimeConverter.ToDateTime(obj.Properties["CreationTime"].Value.ToString()); - if (creationTime.AddSeconds(1.0) >= starttime) - { - foundrestorepoint = true; - } - } - } + _waitOnComputers.Add(computer); } - } - } - catch (ManagementException) - { - foundrestorepoint = true; - } - catch (COMException) - { - foundrestorepoint = true; - } - return foundrestorepoint; - } - } -#endregion - -#region Get-ComputerRestorePoint + }//end foreach - /// - /// This cmdlet is to Get Computer Restore points. - /// - [Cmdlet(VerbsCommon.Get, "ComputerRestorePoint", DefaultParameterSetName = "ID", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135215")] - [OutputType(@"System.Management.ManagementObject#root\default\SystemRestore")] - public sealed class GetComputerRestorePointCommand : PSCmdlet, IDisposable - { -#region Parameters + if (_waitOnComputers.Count > 0) + { + var restartStageTestList = new List(_waitOnComputers); + var wmiTestList = new List(); + var winrmTestList = new List(); + var psTestList = new List(); + var allDoneList = new List(); - /// - /// This cmdlet is to get Computer Restore points. - /// - [Parameter(Position = 0, ParameterSetName = "ID")] - [ValidateNotNullOrEmpty] - [ValidateRangeAttribute((int)1, int.MaxValue)] - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - public int[] RestorePoint { get; set; } + bool isForWmi = _waitFor.Equals(WaitForServiceTypes.Wmi); + bool isForWinRm = _waitFor.Equals(WaitForServiceTypes.WinRM); + bool isForPowershell = _waitFor.Equals(WaitForServiceTypes.PowerShell); - /// - /// This cmdlet is to get Computer Restore points. - /// - [Parameter(ParameterSetName = "LastStatus", Mandatory = true)] - [ValidateNotNull] - public SwitchParameter LastStatus { get; set; } + int indicatorIndex = 0; + int machineCompleteRestart = 0; + int actualDelay = SecondsToWaitForRestartToBegin; + bool first = true; + bool waitComplete = false; - #endregion + _percent = 0; + _status = ComputerResources.WaitForRestartToBegin; + _activity = _waitOnComputers.Count == 1 ? + StringUtil.Format(ComputerResources.RestartSingleComputerActivity, _waitOnComputers[0]) : + ComputerResources.RestartMultipleComputersActivity; - private ManagementClass WMIClass; + _timer = new Timer(OnTimedEvent, null, _timeoutInMilliseconds, System.Threading.Timeout.Infinite); -#region "IDisposable Members" + while (true) + { + int loopCount = actualDelay * 4; // (delay * 1000)/250ms + while (loopCount > 0) + { + WriteProgress(_indicator[(indicatorIndex++) % 4] + _activity, _status, _percent, ProgressRecordType.Processing); - /// - /// Dispose Method - /// - public void Dispose() - { - this.Dispose(true); - // Use SuppressFinalize in case a subclass - // of this type implements a finalizer. - GC.SuppressFinalize(this); - } + loopCount--; + _waitHandler.Wait(250); + if (_exit) { break; } + } - /// - /// Dispose Method. - /// - /// - public void Dispose(bool disposing) - { - if (disposing) - { - if (WMIClass != null) - { - WMIClass.Dispose(); - } - } - } + if (first) + { + actualDelay = _delay; + first = false; -#endregion "IDisposable Members" + if (_waitOnComputers.Count > 1) + { + _status = StringUtil.Format(ComputerResources.WaitForMultipleComputers, machineCompleteRestart, _waitOnComputers.Count); + WriteProgress(_indicator[(indicatorIndex++) % 4] + _activity, _status, _percent, ProgressRecordType.Processing); + } + } -#region overrides - /// - /// Gets the list of Computer Restore point. - /// ID parameter id used to refer the sequence no. When given searched with particular - /// sequence no. and returns the restore point - /// - protected override void BeginProcessing() - { - // system restore APIs are not supported on ARM platform - if (ComputerWMIHelper.SkipSystemRestoreOperationForARMPlatform(this)) - { - return; - } + do + { + // Test restart stage. + // We check if the target machine has already rebooted by querying the LastBootUpTime from the Win32_OperatingSystem object. + // So after this step, we are sure that both the Network and the WMI or WinRM service have already come up. + if (_exit) { break; } + if (restartStageTestList.Count > 0) + { + if (_waitOnComputers.Count == 1) + { + _status = ComputerResources.VerifyRebootStage; + _percent = CalculateProgressPercentage(StageVerification); + WriteProgress(_indicator[(indicatorIndex++) % 4] + _activity, _status, _percent, ProgressRecordType.Processing); + } + List nextTestList = (isForWmi || isForPowershell) ? wmiTestList : winrmTestList; + restartStageTestList = TestRestartStageUsingWsman(restartStageTestList, nextTestList, _cancel.Token); + } - try - { - ManagementScope scope = new ManagementScope(ComputerWMIHelper.WMI_Path_Default); - scope.Connect(); - WMIClass = new ManagementClass(ComputerWMIHelper.WMI_Class_SystemRestore); - WMIClass.Scope = scope; + // Test WMI service + if (_exit) { break; } + if (wmiTestList.Count > 0) + { + // This statement block executes for both CLRs. + // In the "full" CLR, it serves as the else case. + { + if (_waitOnComputers.Count == 1) + { + _status = ComputerResources.WaitForWMI; + _percent = CalculateProgressPercentage(WmiConnectionTest); + WriteProgress(_indicator[(indicatorIndex++) % 4] + _activity, _status, _percent, ProgressRecordType.Processing); + } + wmiTestList = TestWmiConnectionUsingWsman(wmiTestList, winrmTestList, _cancel.Token, Credential, WsmanAuthentication, this); + } + } + if (isForWmi) { break; } - if (ParameterSetName.Equals("LastStatus")) - { - int restoreStatus = Convert.ToInt32(WMIClass.InvokeMethod("GetLastRestoreStatus", null), System.Globalization.CultureInfo.CurrentCulture); - - if (restoreStatus.Equals(0)) - WriteObject(ComputerResources.RestoreFailed); - else if (restoreStatus.Equals(1)) - WriteObject(ComputerResources.RestoreSuccess); - else if (restoreStatus.Equals(2)) - WriteObject(ComputerResources.RestoreInterrupted); - } - Dictionary sequenceList = new Dictionary(); - if (ParameterSetName.Equals("ID")) - { - ObjectQuery objquery = new ObjectQuery(); - // Dictionary sequenceList = new Dictionary(); - if (RestorePoint == null) - { - objquery.QueryString = "select * from " + ComputerWMIHelper.WMI_Class_SystemRestore; - } - else - { - // sequenceList = new List(); - StringBuilder sb = new StringBuilder("select * from "); - sb.Append(ComputerWMIHelper.WMI_Class_SystemRestore); - sb.Append(" where SequenceNumber = "); - for (int i = 0; i <= RestorePoint.Length - 1; i++) - { - sb.Append(RestorePoint[i]); - if (i < RestorePoint.Length - 1) - sb.Append(" OR SequenceNumber = "); - if (!sequenceList.ContainsKey(RestorePoint[i])) - sequenceList.Add(RestorePoint[i], "true"); - } - objquery.QueryString = sb.ToString(); - } + // Test WinRM service + if (_exit) { break; } + if (winrmTestList.Count > 0) + { + // This statement block executes for both CLRs. + // In the "full" CLR, it serves as the else case. + { + // CIM-WSMan in use. In this case, restart stage checking is done by using WMIv2, + // so the WinRM service on the target machine is already up at this point. + psTestList.AddRange(winrmTestList); + winrmTestList.Clear(); - using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, objquery)) - { - foreach (ManagementObject obj in searcher.Get()) - { - using (obj) + if (_waitOnComputers.Count == 1) + { + // This is to simulate the test for WinRM service + _status = ComputerResources.WaitForWinRM; + _percent = CalculateProgressPercentage(WinrmConnectionTest); + + loopCount = actualDelay * 4; // (delay * 1000)/250ms + while (loopCount > 0) + { + WriteProgress(_indicator[(indicatorIndex++) % 4] + _activity, _status, _percent, ProgressRecordType.Processing); + + loopCount--; + _waitHandler.Wait(250); + if (_exit) { break; } + } + } + } + } + if (isForWinRm) { break; } + + // Test PowerShell + if (_exit) { break; } + if (psTestList.Count > 0) { - WriteObject(obj); - if (RestorePoint != null) + if (_waitOnComputers.Count == 1) { - int sequenceNo = Convert.ToInt32(obj.Properties["SequenceNumber"].Value, System.Globalization.CultureInfo.CurrentCulture); - sequenceList.Remove(sequenceNo); + _status = ComputerResources.WaitForPowerShell; + _percent = CalculateProgressPercentage(PowerShellConnectionTest); + WriteProgress(_indicator[(indicatorIndex++) % 4] + _activity, _status, _percent, ProgressRecordType.Processing); } + psTestList = TestPowerShell(psTestList, allDoneList, _powershell, this.Credential); } + } while (false); + + // if time is up or Ctrl+c is typed, break out + if (_exit) { break; } + + // Check if the restart completes + switch (_waitFor) + { + case WaitForServiceTypes.Wmi: + waitComplete = (winrmTestList.Count == _waitOnComputers.Count); + machineCompleteRestart = winrmTestList.Count; + break; + case WaitForServiceTypes.WinRM: + waitComplete = (psTestList.Count == _waitOnComputers.Count); + machineCompleteRestart = psTestList.Count; + break; + case WaitForServiceTypes.PowerShell: + waitComplete = (allDoneList.Count == _waitOnComputers.Count); + machineCompleteRestart = allDoneList.Count; + break; } - } - if (sequenceList != null) - { - if (sequenceList.Count > 0) + // Wait is done or time is up + if (waitComplete || _exit) { - foreach (int id in sequenceList.Keys) + if (waitComplete) { - string message = StringUtil.Format(ComputerResources.NoRestorePoint, id); - ArgumentException e = new ArgumentException(message); - ErrorRecord errorrecord = new ErrorRecord(e, "NoRestorePoint", ErrorCategory.InvalidArgument, null); - WriteError(errorrecord); + _status = ComputerResources.RestartComplete; + WriteProgress(_indicator[indicatorIndex % 4] + _activity, _status, 100, ProgressRecordType.Completed); + _timer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite); } + break; + } + + if (_waitOnComputers.Count > 1) + { + _status = StringUtil.Format(ComputerResources.WaitForMultipleComputers, machineCompleteRestart, _waitOnComputers.Count); + _percent = machineCompleteRestart * 100 / _waitOnComputers.Count; } + }// end while(true) + + if (_timeUp) + { + // The timeout expires. Write out timeout error messages for the computers that haven't finished restarting + do + { + if (restartStageTestList.Count > 0) { WriteOutTimeoutError(restartStageTestList); } + if (wmiTestList.Count > 0) { WriteOutTimeoutError(wmiTestList); } + // Wait for WMI. All computers that finished restarting are put in "winrmTestList" + if (isForWmi) { break; } + + // Wait for WinRM. All computers that finished restarting are put in "psTestList" + if (winrmTestList.Count > 0) { WriteOutTimeoutError(winrmTestList); } + if (isForWinRm) { break; } + + if (psTestList.Count > 0) { WriteOutTimeoutError(psTestList); } + // Wait for PowerShell. All computers that finished restarting are put in "allDoneList" + } while (false); } - } - } - catch (ManagementException e) - { - if ((e.ErrorCode.Equals(ManagementStatus.NotFound)) || (e.ErrorCode.Equals(ManagementStatus.InvalidClass))) - { - Exception Ex = new ArgumentException(StringUtil.Format(ComputerResources.NotSupported)); - WriteError(new ErrorRecord(Ex, "GetComputerRestorePointNotSupported", ErrorCategory.InvalidOperation, null)); - } - else - { - ErrorRecord errorRecord = new ErrorRecord(e, "GetWMIManagementException", ErrorCategory.InvalidOperation, null); - WriteError(errorRecord); - } - } - catch (COMException e) - { - if (string.IsNullOrEmpty(e.Message)) - { - Exception Ex = new ArgumentException(StringUtil.Format(ComputerResources.SystemRestoreServiceDisabled)); - WriteError(new ErrorRecord(Ex, "ServiceDisabled", ErrorCategory.InvalidOperation, null)); - } - else - { - ErrorRecord errorRecord = new ErrorRecord(e, "COMException", ErrorCategory.InvalidOperation, null); - WriteError(errorRecord); - } - } - } + }// end if(waitOnComputer.Count > 0) + }//end DefaultParameter + }//End Processrecord /// /// to implement ^C /// protected override void StopProcessing() { - if (WMIClass != null) + _exit = true; + _cancel.Cancel(); + _waitHandler.Set(); + + if (_timer != null) + { + _timer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite); + } + + if (_powershell != null) { - WMIClass.Dispose(); + _powershell.Stop(); + _powershell.Dispose(); } } -#endregion overrides +#endregion "Overrides" } -#endregion +#endregion Restart-Computer -#endif - -#region Restart-Computer - - /// - /// This exception is thrown when the timeout expires before a computer finishes restarting - /// - [Serializable] - public sealed class RestartComputerTimeoutException : RuntimeException - { - /// - /// Name of the computer that is restarting - /// - public string ComputerName { get; private set; } - - /// - /// The timeout value specified by the user. It indicates the seconds to wait before timeout. - /// - public int Timeout { get; private set; } - - /// - /// Construct a RestartComputerTimeoutException. - /// - /// - /// - /// - /// - internal RestartComputerTimeoutException(string computerName, int timeout, string message, string errorId) - : base(message) - { - SetErrorId(errorId); - SetErrorCategory(ErrorCategory.OperationTimeout); - ComputerName = computerName; - Timeout = timeout; - } - - /// - /// Construct a RestartComputerTimeoutException - /// - public RestartComputerTimeoutException() : base() { } - - /// - /// Constructs a RestartComputerTimeoutException - /// - /// - /// - /// The message used in the exception. - /// - public RestartComputerTimeoutException(string message) : base(message) { } - - /// - /// Constructs a RestartComputerTimeoutException - /// - /// - /// - /// The message used in the exception. - /// - /// - /// - /// An exception that led to this exception. - /// - public RestartComputerTimeoutException(string message, Exception innerException) : base(message, innerException) { } - -#region Serialization - /// - /// Serialization constructor for class RestartComputerTimeoutException - /// - /// - /// - /// serialization information - /// - /// - /// - /// streaming context - /// - private RestartComputerTimeoutException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - if (info == null) - { - throw new PSArgumentNullException("info"); - } - - ComputerName = info.GetString("ComputerName"); - Timeout = info.GetInt32("Timeout"); - } - - /// - /// Serializes the RestartComputerTimeoutException. - /// - /// - /// - /// serialization information - /// - /// - /// - /// streaming context - /// - [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)] - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - if (info == null) - { - throw new PSArgumentNullException("info"); - } - - base.GetObjectData(info, context); - info.AddValue("ComputerName", ComputerName); - info.AddValue("Timeout", Timeout); - } -#endregion Serialization - } - - /// - /// Defines the services that Restart-Computer can wait on - /// - [SuppressMessage("Microsoft.Design", "CA1027:MarkEnumsWithFlags")] - public enum WaitForServiceTypes - { - /// - /// Wait for the WMI service to be ready - /// - Wmi = 0x0, - - /// - /// Wait for the WinRM service to be ready - /// - WinRM = 0x1, - - /// - /// Wait for the PowerShell to be ready - /// - PowerShell = 0x2, - } +#region Stop-Computer /// - /// Restarts the computer + /// cmdlet to stop computer /// - [Cmdlet(VerbsLifecycle.Restart, "Computer", SupportsShouldProcess = true, DefaultParameterSetName = DefaultParameterSet, - HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135253", RemotingCapability = RemotingCapability.OwnedByCommand)] - public class RestartComputerCommand : PSCmdlet, IDisposable + [Cmdlet(VerbsLifecycle.Stop, "Computer", SupportsShouldProcess = true, + HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135263", RemotingCapability = RemotingCapability.SupportedByCommand)] + public sealed class StopComputerCommand : PSCmdlet, IDisposable { -#region "Parameters and PrivateData" - - private const string DefaultParameterSet = "DefaultSet"; - private const string AsJobParameterSet = "AsJobSet"; +#region Private Members - /// - /// Used to start a command remotely as a Job. The Job results are collected - /// and stored in the global cache on the client machine. - /// - [Parameter(ParameterSetName = AsJobParameterSet)] - public SwitchParameter AsJob { get; set; } = false; + private readonly CancellationTokenSource _cancel = new CancellationTokenSource(); + private const int forcedShutdown = 5; // See https://msdn.microsoft.com/en-us/library/aa394058(v=vs.85).aspx - /// - /// The following is the definition of the input parameter "Authentication". - /// Specifies the authentication level to be used with WMI connection. Valid - /// values are: - /// - /// Unchanged = -1, - /// Default = 0, - /// None = 1, - /// Connect = 2, - /// Call = 3, - /// Packet = 4, - /// PacketIntegrity = 5, - /// PacketPrivacy = 6. - /// - [Parameter] - [Alias("Authentication")] - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] - public AuthenticationLevel DcomAuthentication - { - get { return _dcomAuthentication; } - set - { - _dcomAuthentication = value; - _isDcomAuthenticationSpecified = true; - } - } - private AuthenticationLevel _dcomAuthentication = AuthenticationLevel.Packet; - private bool _isDcomAuthenticationSpecified = false; +#endregion - /// - /// The following is the definition of the input parameter "Impersonation". - /// Specifies the impersonation level to use when calling the WMI method. Valid - /// values are: - /// - /// Default = 0, - /// Anonymous = 1, - /// Identify = 2, - /// Impersonate = 3, - /// Delegate = 4. - /// - [Parameter] - public ImpersonationLevel Impersonation - { - get { return _impersonation; } - set - { - _impersonation = value; - _isImpersonationSpecified = true; - } - } - private ImpersonationLevel _impersonation = ImpersonationLevel.Impersonate; - private bool _isImpersonationSpecified = false; +#region "Parameters" /// /// The authentication options for CIM_WSMan connection /// - [Parameter(ParameterSetName = DefaultParameterSet)] + [Parameter] [ValidateSet( "Default", "Basic", "Negotiate", // can be used with and without credential (without -> PSRP mapped to NegotiateWithImplicitCredential) "CredSSP", "Digest", - "Kerberos")] // can be used with and without credential (not sure about implications) + "Kerberos")] // can be used with explicit or implicit credential [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] - public string WsmanAuthentication { get; set; } - - /// - /// Specify the protocol to use - /// - [Parameter(ParameterSetName = DefaultParameterSet)] - [ValidateSet(ComputerWMIHelper.DcomProtocol, ComputerWMIHelper.WsmanProtocol)] - public string Protocol - { - get { return _protocol; } - set - { - _protocol = value; - _isProtocolSpecified = true; - } - } - - //CoreClr does not support DCOM protocol - // This change makes sure that the the command works seamlessly if user did not explicitly entered the protocol -#if CORECLR - private string _protocol = ComputerWMIHelper.WsmanProtocol; -#else - private string _protocol = ComputerWMIHelper.DcomProtocol; -#endif - private bool _isProtocolSpecified = false; - - /// - /// Specifies the computer (s)Name on which this command is executed. - /// When this parameter is omitted, this cmdlet restarts the local computer. - /// Type the NETBIOS name, IP address, or fully-qualified domain name of one - /// or more computers in a comma-separated list. To specify the local computer, type the computername or "localhost". - /// - [Parameter(Position = 0, ValueFromPipeline = true, - ValueFromPipelineByPropertyName = true)] - [ValidateNotNullOrEmpty] - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - [Alias("CN", "__SERVER", "Server", "IPAddress")] - public String[] ComputerName { get; set; } = new string[] { "." }; - - private List _validatedComputerNames = new List(); - private readonly List _waitOnComputers = new List(); - private readonly HashSet _uniqueComputerNames = new HashSet(StringComparer.OrdinalIgnoreCase); - - /// - /// The following is the definition of the input parameter "Credential". - /// Specifies a user account that has permission to perform this action. Type a - /// user-name, such as "User01" or "Domain01\User01", or enter a PSCredential - /// object, such as one from the Get-Credential cmdlet - /// - [Parameter(Position = 1)] - [ValidateNotNullOrEmpty] - [Credential] - public PSCredential Credential { get; set; } - - /// - /// Using Force in conjunction with Reboot on a - /// remote computer immediately reboots the remote computer. - /// - [Parameter] - [Alias("f")] - public SwitchParameter Force { get; set; } - - /// - /// Allows the user of the cmdlet to specify a throttling value - /// for throttling the number of remote operations that can - /// be executed simultaneously. - /// - [Parameter(ParameterSetName = AsJobParameterSet)] - [ValidateRange(int.MinValue, (int)1000)] - public Int32 ThrottleLimit - { - get { return _throttlelimit; } - set - { - _throttlelimit = value; - if (_throttlelimit <= 0) - _throttlelimit = 32; - } - } - private Int32 _throttlelimit = 32; - - /// - /// Specify the Wait parameter. Prompt will be blocked is the Timeout is not 0 - /// - [Parameter(ParameterSetName = DefaultParameterSet)] - public SwitchParameter Wait { get; set; } - - /// - /// Specify the Timeout parameter. - /// Negative value indicates wait infinitely. - /// Positive value indicates the seconds to wait before timeout. - /// - [Parameter(ParameterSetName = DefaultParameterSet)] - [Alias("TimeoutSec")] - [ValidateRange(-1, int.MaxValue)] - public int Timeout - { - get { return _timeout; } - set - { - _timeout = value; - _timeoutSpecified = true; - } - } - private int _timeout = -1; - private bool _timeoutSpecified = false; - - /// - /// Specify the For parameter. - /// Wait for the specific service before unblocking the prompt. - /// - [Parameter(ParameterSetName = DefaultParameterSet)] - public WaitForServiceTypes For - { - get { return _waitFor; } - set - { - _waitFor = value; - _waitForSpecified = true; - } - } - private WaitForServiceTypes _waitFor = WaitForServiceTypes.PowerShell; - private bool _waitForSpecified = false; - - /// - /// Specify the Delay parameter. - /// The specific time interval (in second) to wait between network pings or service queries. - /// - [Parameter(ParameterSetName = DefaultParameterSet)] - [ValidateRange(1, Int16.MaxValue)] - public Int16 Delay - { - get { return (Int16)_delay; } - set - { - _delay = value; - _delaySpecified = true; - } - } - private int _delay = 5; - private bool _delaySpecified = false; - - /// - /// Script to test if the PowerShell is ready - /// - private const string TestPowershellScript = @" -$array = @($input) -$result = @{} -foreach ($computerName in $array[1]) -{ - $ret = $null - if ($null -eq array[0]) - { - $ret = Invoke-Command -ComputerName $computerName {$true} -SessionOption (New-PSSessionOption -NoMachineProfile) -ErrorAction SilentlyContinue - } - else - { - $ret = Invoke-Command -ComputerName $computerName {$true} -SessionOption (New-PSSessionOption -NoMachineProfile) -ErrorAction SilentlyContinue -Credential $array[0] - } - - if ($ret -eq $true) - { - $result[$computerName] = $true - } - else - { - $result[$computerName] = $false - } -} -$result -"; - - /// - /// The indicator to use when show progress - /// - private string[] _indicator = { "|", "/", "-", "\\" }; - - /// - /// The activity id - /// - private int _activityId; - - /// - /// After call 'Shutdown' on the target computer, wait a few - /// seconds for the restart to begin. - /// - private const int SecondsToWaitForRestartToBegin = 25; - - /// - /// Actual time out in seconds - /// - private int _timeoutInMilliseconds; - - /// - /// Indicate to exit - /// - private bool _exit, _timeUp; - private readonly CancellationTokenSource _cancel = new CancellationTokenSource(); - - /// - /// A waithandler to wait on. Current thread will wait on it during the delay interval. - /// - private readonly ManualResetEventSlim _waitHandler = new ManualResetEventSlim(false); - private readonly Dictionary _computerInfos = new Dictionary(StringComparer.OrdinalIgnoreCase); - - // CLR 4.0 Port note - use https://msdn.microsoft.com/en-us/library/system.net.networkinformation.ipglobalproperties.hostname(v=vs.110).aspx - private readonly string _shortLocalMachineName = Dns.GetHostName(); - - // And for this, use PsUtils.GetHostname() - private readonly string _fullLocalMachineName = Dns.GetHostEntryAsync("").Result.HostName; - - private int _percent; - private string _status; - private string _activity; - private Timer _timer; - private System.Management.Automation.PowerShell _powershell; - - private const string StageVerification = "VerifyStage"; - private const string WmiConnectionTest = "WMI"; - private const string WinrmConnectionTest = "WinRM"; - private const string PowerShellConnectionTest = "PowerShell"; - -#endregion "parameters and PrivateData" - -#region "IDisposable Members" - - /// - /// Dispose Method - /// - public void Dispose() - { - this.Dispose(true); - // Use SuppressFinalize in case a subclass - // of this type implements a finalizer. - GC.SuppressFinalize(this); - } - - /// - /// Dispose Method. - /// - /// - public void Dispose(bool disposing) - { - if (disposing) - { - if (_timer != null) - { - _timer.Dispose(); - } - - _waitHandler.Dispose(); - _cancel.Dispose(); - if (_powershell != null) - { - _powershell.Dispose(); - } - } - } - -#endregion "IDisposable Members" - -#region "Private Methods" - - /// - /// Validate parameters for 'DefaultSet' - /// 1. When the Wait is specified, the computername cannot contain the local machine - /// 2. If the local machine is present, make sure it is at the end of the list (so the remote ones get restarted before the local machine reboot). - /// - private void ValidateComputerNames() - { - bool containLocalhost = false; - _validatedComputerNames.Clear(); - - foreach (string name in ComputerName) - { - ErrorRecord error = null; - string targetComputerName = ComputerWMIHelper.ValidateComputerName(name, _shortLocalMachineName, _fullLocalMachineName, ref error); - if (targetComputerName == null) - { - if (error != null) - { - WriteError(error); - } - continue; - } - - if (targetComputerName.Equals(ComputerWMIHelper.localhostStr, StringComparison.OrdinalIgnoreCase)) - { - containLocalhost = true; - } - else if (!_uniqueComputerNames.Contains(targetComputerName)) - { - _validatedComputerNames.Add(targetComputerName); - _uniqueComputerNames.Add(targetComputerName); - } - } - - if (Wait && containLocalhost) - { - // The local machine will be ignored, and an error will be emitted. - InvalidOperationException ex = new InvalidOperationException(ComputerResources.CannotWaitLocalComputer); - WriteError(new ErrorRecord(ex, "CannotWaitLocalComputer", ErrorCategory.InvalidOperation, null)); - containLocalhost = false; - } - - // Add the localhost to the end of the list, so we will restart remote machines - // before we restart the local one. - if (containLocalhost) - { - _validatedComputerNames.Add(ComputerWMIHelper.localhostStr); - } - } - - /// - /// Write out progress - /// - /// - /// - /// - /// - private void WriteProgress(string activity, string status, int percent, ProgressRecordType progressRecordType) - { - ProgressRecord progress = new ProgressRecord(_activityId, activity, status); - progress.PercentComplete = percent; - progress.RecordType = progressRecordType; - WriteProgress(progress); - } - - /// - /// Calculate the progress percentage - /// - /// - /// - private int CalculateProgressPercentage(string currentStage) - { - switch (currentStage) - { - case StageVerification: - return _waitFor.Equals(WaitForServiceTypes.Wmi) || _waitFor.Equals(WaitForServiceTypes.WinRM) - ? 33 - : 20; - case WmiConnectionTest: - return _waitFor.Equals(WaitForServiceTypes.Wmi) ? 66 : 40; - case WinrmConnectionTest: - return _waitFor.Equals(WaitForServiceTypes.WinRM) ? 66 : 60; - case PowerShellConnectionTest: - return 80; - default: - break; - } - - Dbg.Diagnostics.Assert(false, "CalculateProgressPercentage should never hit the default case"); - return 0; - } - - /// - /// Event handler for the timer - /// - /// - private void OnTimedEvent(object s) - { - _exit = _timeUp = true; - _cancel.Cancel(); - _waitHandler.Set(); - - if (_powershell != null) - { - _powershell.Stop(); - _powershell.Dispose(); - } - } - - private class ComputerInfo - { - internal string LastBootUpTime; - internal bool RebootComplete; - } - -#if !CORECLR - private List TestRestartStageUsingDcom(IEnumerable computerNames, List nextTestList, CancellationToken token, ConnectionOptions options) - { - var restartStageTestList = new List(); - var query = new ObjectQuery("Select * from " + ComputerWMIHelper.WMI_Class_OperatingSystem); - var enumOptions = new EnumerationOptions { UseAmendedQualifiers = true, DirectRead = true }; - - foreach (var computer in computerNames) - { - try - { - if (token.IsCancellationRequested) { break; } - var scope = new ManagementScope(ComputerWMIHelper.GetScopeString(computer, ComputerWMIHelper.WMI_Path_CIM), options); - using (var searcher = new ManagementObjectSearcher(scope, query, enumOptions)) - { - if (token.IsCancellationRequested) { break; } - - using (var mCollection = searcher.Get()) - { - if (mCollection.Count > 0) - { - foreach (ManagementBaseObject os in mCollection) - { - using (os) - { - string newLastBootUpTime = os.Properties["LastBootUpTime"].Value.ToString(); - string oldLastBootUpTime = _computerInfos[computer].LastBootUpTime; - - if (string.Compare(newLastBootUpTime, oldLastBootUpTime, StringComparison.OrdinalIgnoreCase) != 0) - { - _computerInfos[computer].RebootComplete = true; - nextTestList.Add(computer); - } - else - { - restartStageTestList.Add(computer); - } - } - } - } - else - { - restartStageTestList.Add(computer); - } - } - } - } - catch (ManagementException) - { - restartStageTestList.Add(computer); - } - catch (COMException) - { - restartStageTestList.Add(computer); - } - catch (UnauthorizedAccessException) - { - restartStageTestList.Add(computer); - } - } - - return restartStageTestList; - } -#endif - - private List TestRestartStageUsingWsman(IEnumerable computerNames, List nextTestList, CancellationToken token) - { - var restartStageTestList = new List(); - var operationOptions = new CimOperationOptions - { - Timeout = TimeSpan.FromMilliseconds(2000), - CancellationToken = token - }; - foreach (var computer in computerNames) - { - try - { - if (token.IsCancellationRequested) { break; } - using (CimSession cimSession = RemoteDiscoveryHelper.CreateCimSession(computer, Credential, WsmanAuthentication, token, this)) - { - bool itemRetrieved = false; - IEnumerable mCollection = cimSession.QueryInstances( - ComputerWMIHelper.CimOperatingSystemNamespace, - ComputerWMIHelper.CimQueryDialect, - "Select * from " + ComputerWMIHelper.WMI_Class_OperatingSystem, - operationOptions); - foreach (CimInstance os in mCollection) - { - itemRetrieved = true; - string newLastBootUpTime = os.CimInstanceProperties["LastBootUpTime"].Value.ToString(); - string oldLastBootUpTime = _computerInfos[computer].LastBootUpTime; - - if (string.Compare(newLastBootUpTime, oldLastBootUpTime, StringComparison.OrdinalIgnoreCase) != 0) - { - _computerInfos[computer].RebootComplete = true; - nextTestList.Add(computer); - } - else - { - restartStageTestList.Add(computer); - } - } - - if (!itemRetrieved) - { - restartStageTestList.Add(computer); - } - } - } - catch (CimException) - { - restartStageTestList.Add(computer); - } - catch (Exception) - { - restartStageTestList.Add(computer); - } - } - - return restartStageTestList; - } - -#if !CORECLR - private List SetUpComputerInfoUsingDcom(IEnumerable computerNames, ConnectionOptions options) - { - var validComputerNameList = new List(); - var query = new ObjectQuery("Select * From " + ComputerWMIHelper.WMI_Class_OperatingSystem); - var enumOptions = new EnumerationOptions { UseAmendedQualifiers = true, DirectRead = true }; - - foreach (var computer in computerNames) - { - try - { - var scope = new ManagementScope(ComputerWMIHelper.GetScopeString(computer, ComputerWMIHelper.WMI_Path_CIM), options); - using (var searcher = new ManagementObjectSearcher(scope, query, enumOptions)) - { - using (var mCollection = searcher.Get()) - { - if (mCollection.Count > 0) - { - foreach (ManagementBaseObject os in mCollection) - { - using (os) - { - if (!_computerInfos.ContainsKey(computer)) - { - var info = new ComputerInfo - { - LastBootUpTime = os.Properties["LastBootUpTime"].Value.ToString(), - RebootComplete = false - }; - _computerInfos.Add(computer, info); - validComputerNameList.Add(computer); - } - } - } - } - else - { - string errMsg = StringUtil.Format(ComputerResources.RestartComputerSkipped, computer, ComputerResources.CannotGetOperatingSystemObject); - var error = new ErrorRecord(new InvalidOperationException(errMsg), "RestartComputerSkipped", - ErrorCategory.OperationStopped, computer); - this.WriteError(error); - } - } - } - } - catch (ManagementException ex) - { - string errMsg = StringUtil.Format(ComputerResources.RestartComputerSkipped, computer, ex.Message); - var error = new ErrorRecord(new InvalidOperationException(errMsg), "RestartComputerSkipped", - ErrorCategory.OperationStopped, computer); - this.WriteError(error); - } - catch (COMException ex) - { - string errMsg = StringUtil.Format(ComputerResources.RestartComputerSkipped, computer, ex.Message); - var error = new ErrorRecord(new InvalidOperationException(errMsg), "RestartComputerSkipped", - ErrorCategory.OperationStopped, computer); - this.WriteError(error); - } - catch (UnauthorizedAccessException ex) - { - string errMsg = StringUtil.Format(ComputerResources.RestartComputerSkipped, computer, ex.Message); - var error = new ErrorRecord(new InvalidOperationException(errMsg), "RestartComputerSkipped", - ErrorCategory.OperationStopped, computer); - this.WriteError(error); - } - } - - return validComputerNameList; - } -#endif - - private List SetUpComputerInfoUsingWsman(IEnumerable computerNames, CancellationToken token) - { - var validComputerNameList = new List(); - var operationOptions = new CimOperationOptions - { - Timeout = TimeSpan.FromMilliseconds(2000), - CancellationToken = token - }; - foreach (var computer in computerNames) - { - try - { - using (CimSession cimSession = RemoteDiscoveryHelper.CreateCimSession(computer, Credential, WsmanAuthentication, token, this)) - { - bool itemRetrieved = false; - IEnumerable mCollection = cimSession.QueryInstances( - ComputerWMIHelper.CimOperatingSystemNamespace, - ComputerWMIHelper.CimQueryDialect, - "Select * from " + ComputerWMIHelper.WMI_Class_OperatingSystem, - operationOptions); - foreach (CimInstance os in mCollection) - { - itemRetrieved = true; - if (!_computerInfos.ContainsKey(computer)) - { - var info = new ComputerInfo - { - LastBootUpTime = os.CimInstanceProperties["LastBootUpTime"].Value.ToString(), - RebootComplete = false - }; - _computerInfos.Add(computer, info); - validComputerNameList.Add(computer); - } - } - - if (!itemRetrieved) - { - string errMsg = StringUtil.Format(ComputerResources.RestartComputerSkipped, computer, ComputerResources.CannotGetOperatingSystemObject); - var error = new ErrorRecord(new InvalidOperationException(errMsg), "RestartComputerSkipped", - ErrorCategory.OperationStopped, computer); - this.WriteError(error); - } - } - } - catch (CimException ex) - { - string errMsg = StringUtil.Format(ComputerResources.RestartComputerSkipped, computer, ex.Message); - var error = new ErrorRecord(new InvalidOperationException(errMsg), "RestartComputerSkipped", - ErrorCategory.OperationStopped, computer); - this.WriteError(error); - } - catch (Exception ex) - { - string errMsg = StringUtil.Format(ComputerResources.RestartComputerSkipped, computer, ex.Message); - var error = new ErrorRecord(new InvalidOperationException(errMsg), "RestartComputerSkipped", - ErrorCategory.OperationStopped, computer); - this.WriteError(error); - } - } - - return validComputerNameList; - } - - private void WriteOutTimeoutError(IEnumerable computerNames) - { - const string errorId = "RestartComputerTimeout"; - foreach (string computer in computerNames) - { - string errorMsg = StringUtil.Format(ComputerResources.RestartcomputerFailed, computer, ComputerResources.TimeoutError); - var exception = new RestartComputerTimeoutException(computer, Timeout, errorMsg, errorId); - var error = new ErrorRecord(exception, errorId, ErrorCategory.OperationTimeout, computer); - WriteError(error); - } - } - -#endregion "Private Methods" - -#region "Internal Methods" - - internal static List TestWmiConnectionUsingWsman(List computerNames, List nextTestList, CancellationToken token, PSCredential credential, string wsmanAuthentication, PSCmdlet cmdlet) - { - // Check if the WMI service "Winmgmt" is started - const string wmiServiceQuery = "Select * from " + ComputerWMIHelper.WMI_Class_Service + " Where name = 'Winmgmt'"; - var wmiTestList = new List(); - var operationOptions = new CimOperationOptions - { - Timeout = TimeSpan.FromMilliseconds(2000), - CancellationToken = token - }; - foreach (var computer in computerNames) - { - try - { - if (token.IsCancellationRequested) { break; } - using (CimSession cimSession = RemoteDiscoveryHelper.CreateCimSession(computer, credential, wsmanAuthentication, token, cmdlet)) - { - bool itemRetrieved = false; - IEnumerable mCollection = cimSession.QueryInstances( - ComputerWMIHelper.CimOperatingSystemNamespace, - ComputerWMIHelper.CimQueryDialect, - wmiServiceQuery, - operationOptions); - foreach (CimInstance service in mCollection) - { - itemRetrieved = true; - if (LanguagePrimitives.IsTrue(service.CimInstanceProperties["Started"].Value)) - { - nextTestList.Add(computer); - } - else - { - wmiTestList.Add(computer); - } - } - - if (!itemRetrieved) - { - wmiTestList.Add(computer); - } - } - } - catch (CimException) - { - wmiTestList.Add(computer); - } - catch (Exception) - { - wmiTestList.Add(computer); - } - } - - return wmiTestList; - } - -#if !CORECLR - /// - /// Test WinRM connectivity for the restarting machine - /// - /// - /// - /// - /// - internal static List TestWinrmConnection(List computerNames, List nextTestList, CancellationToken token) - { - List winrmTestList = new List(); - IWSManEx wsmanObject = (IWSManEx)new WSManClass(); - int sessionFlags = (int)WSManSessionFlags.WSManFlagUseNoAuthentication | (int)WSManSessionFlags.WSManFlagUtf8; - IWSManConnectionOptionsEx2 connObject = (IWSManConnectionOptionsEx2)wsmanObject.CreateConnectionOptions(); - - foreach (string computerName in computerNames) - { - try - { - if (token.IsCancellationRequested) { break; } - IWSManSession sessionObj = (IWSManSession)wsmanObject.CreateSession(computerName, sessionFlags, connObject); - if (token.IsCancellationRequested) { break; } - sessionObj.Timeout = 1500; - sessionObj.Identify(0); - nextTestList.Add(computerName); - } - catch (COMException) - { - winrmTestList.Add(computerName); - } - catch (Exception) - { - winrmTestList.Add(computerName); - } - } - return winrmTestList; - } -#endif - - /// - /// Test the PowerShell state for the restarting computer - /// - /// - /// - /// - /// - /// - internal static List TestPowerShell(List computerNames, List nextTestList, System.Management.Automation.PowerShell powershell, PSCredential credential) - { - List psList = new List(); - - try - { - Collection psObjectCollection = powershell.Invoke(new object[] { credential, computerNames.ToArray() }); - if (psObjectCollection == null) - { - Dbg.Diagnostics.Assert(false, "This should never happen. Invoke should never return null."); - } - - // If ^C or timeout happens when we are in powershell.Invoke(), the psObjectCollection might be empty - if (psObjectCollection.Count == 0) - { - return computerNames; - } - - object result = PSObject.Base(psObjectCollection[0]); - Hashtable data = result as Hashtable; - - Dbg.Diagnostics.Assert(data != null, "data should never be null"); - Dbg.Diagnostics.Assert(data.Count == computerNames.Count, "data should contain results for all computers in computerNames"); - - foreach (string computer in computerNames) - { - if (LanguagePrimitives.IsTrue(data[computer])) - { - nextTestList.Add(computer); - } - else - { - psList.Add(computer); - } - } - } - catch (PipelineStoppedException) - { - // powershell.Stop() is invoked because timeout expires, or Ctrl+C is pressed - } - catch (ObjectDisposedException) - { - // powershell.dispose() is invoked because timeout expires, or Ctrl+C is pressed - } - - return psList; - } - -#if !CORECLR - /// - /// Restart one computer - /// - /// - /// - /// - /// - /// - /// - /// True if the restart was successful - /// False otherwise - /// - internal static bool RestartOneComputerUsingDcom(PSCmdlet cmdlet, bool isLocalhost, string computerName, object[] flags, ConnectionOptions options) - { - bool isSuccess = false; - PlatformInvokes.TOKEN_PRIVILEGE currentPrivilegeState = new PlatformInvokes.TOKEN_PRIVILEGE(); - - try - { - if (!(isLocalhost && PlatformInvokes.EnableTokenPrivilege(ComputerWMIHelper.SE_SHUTDOWN_NAME, ref currentPrivilegeState)) && - !(!isLocalhost && PlatformInvokes.EnableTokenPrivilege(ComputerWMIHelper.SE_REMOTE_SHUTDOWN_NAME, ref currentPrivilegeState))) - { - string message = - StringUtil.Format(ComputerResources.PrivilegeNotEnabled, computerName, - isLocalhost ? ComputerWMIHelper.SE_SHUTDOWN_NAME : ComputerWMIHelper.SE_REMOTE_SHUTDOWN_NAME); - ErrorRecord errorRecord = new ErrorRecord(new InvalidOperationException(message), "PrivilegeNotEnabled", ErrorCategory.InvalidOperation, null); - cmdlet.WriteError(errorRecord); - return false; - } - - ManagementScope scope = new ManagementScope(ComputerWMIHelper.GetScopeString(isLocalhost ? "localhost" : computerName, ComputerWMIHelper.WMI_Path_CIM), options); - EnumerationOptions enumOptions = new EnumerationOptions { UseAmendedQualifiers = true, DirectRead = true }; - ObjectQuery query = new ObjectQuery("select * from " + ComputerWMIHelper.WMI_Class_OperatingSystem); - using (var searcher = new ManagementObjectSearcher(scope, query, enumOptions)) - { - foreach (ManagementObject operatingSystem in searcher.Get()) - { - using (operatingSystem) - { - object result = operatingSystem.InvokeMethod("Win32shutdown", flags); - int retVal = Convert.ToInt32(result.ToString(), CultureInfo.CurrentCulture); - if (retVal != 0) - { - var ex = new Win32Exception(retVal); - string errMsg = StringUtil.Format(ComputerResources.RestartcomputerFailed, computerName, ex.Message); - ErrorRecord error = new ErrorRecord( - new InvalidOperationException(errMsg), "RestartcomputerFailed", ErrorCategory.OperationStopped, computerName); - cmdlet.WriteError(error); - } - else - { - isSuccess = true; - } - } - } - } - } - catch (ManagementException ex) - { - string errMsg = StringUtil.Format(ComputerResources.RestartcomputerFailed, computerName, ex.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "RestartcomputerFailed", - ErrorCategory.OperationStopped, computerName); - cmdlet.WriteError(error); - } - catch (COMException ex) - { - string errMsg = StringUtil.Format(ComputerResources.RestartcomputerFailed, computerName, ex.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "RestartcomputerFailed", - ErrorCategory.OperationStopped, computerName); - cmdlet.WriteError(error); - } - catch (UnauthorizedAccessException ex) - { - string errMsg = StringUtil.Format(ComputerResources.RestartcomputerFailed, computerName, ex.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "RestartcomputerFailed", - ErrorCategory.OperationStopped, computerName); - cmdlet.WriteError(error); - } - finally - { - // Restore the previous privilege state if something unexpected happened - PlatformInvokes.RestoreTokenPrivilege( - isLocalhost ? ComputerWMIHelper.SE_SHUTDOWN_NAME : ComputerWMIHelper.SE_REMOTE_SHUTDOWN_NAME, ref currentPrivilegeState); - } - - return isSuccess; - } -#endif - -#endregion "Internal Methods" - -#region "Overrides" - - /// - /// BeginProcessing method. - /// - protected override void BeginProcessing() - { - if (ParameterSetName.Equals(DefaultParameterSet, StringComparison.OrdinalIgnoreCase)) - { - if (WsmanAuthentication != null && (_isDcomAuthenticationSpecified || _isImpersonationSpecified)) - { - string errorMsg = StringUtil.Format(ComputerResources.ParameterConfliction, - ComputerResources.ParameterUsage); - InvalidOperationException ex = new InvalidOperationException(errorMsg); - ThrowTerminatingError(new ErrorRecord(ex, "ParameterConfliction", ErrorCategory.InvalidOperation, null)); - } - - bool usingDcom = Protocol.Equals(ComputerWMIHelper.DcomProtocol, StringComparison.OrdinalIgnoreCase); - bool usingWsman = Protocol.Equals(ComputerWMIHelper.WsmanProtocol, StringComparison.OrdinalIgnoreCase); - - if (_isProtocolSpecified && usingDcom && WsmanAuthentication != null) - { - string errorMsg = StringUtil.Format(ComputerResources.InvalidParameterForDCOM, - ComputerResources.ParameterUsage); - InvalidOperationException ex = new InvalidOperationException(errorMsg); - ThrowTerminatingError(new ErrorRecord(ex, "InvalidParameterForDCOM", ErrorCategory.InvalidOperation, null)); - } - - if (_isProtocolSpecified && usingWsman && (_isDcomAuthenticationSpecified || _isImpersonationSpecified)) - { - string errorMsg = StringUtil.Format(ComputerResources.InvalidParameterForWSMan, - ComputerResources.ParameterUsage); - InvalidOperationException ex = new InvalidOperationException(errorMsg); - ThrowTerminatingError(new ErrorRecord(ex, "InvalidParameterForWSMan", ErrorCategory.InvalidOperation, null)); - } - - if (!_isProtocolSpecified && WsmanAuthentication != null) - { - // Change the protocol to be WSMan if the WsmanAuthentication is specified - Protocol = ComputerWMIHelper.WsmanProtocol; - } - } - -#if CORECLR - if (this.MyInvocation.BoundParameters.ContainsKey("DcomAuthentication")) - { - string errMsg = StringUtil.Format(ComputerResources.InvalidParameterForCoreClr, "DcomAuthentication"); - PSArgumentException ex = new PSArgumentException(errMsg, ComputerResources.InvalidParameterForCoreClr); - ThrowTerminatingError(new ErrorRecord(ex, "InvalidParameterForCoreClr", ErrorCategory.InvalidArgument, null)); - } - - if (this.MyInvocation.BoundParameters.ContainsKey("Impersonation")) - { - string errMsg = StringUtil.Format(ComputerResources.InvalidParameterForCoreClr, "Impersonation"); - PSArgumentException ex = new PSArgumentException(errMsg, ComputerResources.InvalidParameterForCoreClr); - ThrowTerminatingError(new ErrorRecord(ex, "InvalidParameterForCoreClr", ErrorCategory.InvalidArgument, null)); - } - - // DCOM Authentication is not supported for CoreCLR. Throw an error - // and request that the user specify WSMan Authentication. - if (_isDcomAuthenticationSpecified || - Protocol.Equals(ComputerWMIHelper.DcomProtocol, StringComparison.OrdinalIgnoreCase)) - { - InvalidOperationException ex = new InvalidOperationException(ComputerResources.InvalidParameterDCOMNotSupported); - ThrowTerminatingError(new ErrorRecord(ex, "InvalidParameterDCOMNotSupported", ErrorCategory.InvalidOperation, null)); - } - - // TODO:CORECLR This should be re-visited if we decide to add double hop remoting to CoreCLR (outgoing connections) - if (ParameterSetName.Equals(AsJobParameterSet, StringComparison.OrdinalIgnoreCase)) - { - InvalidOperationException ex = new InvalidOperationException(ComputerResources.InvalidParameterSetAsJob); - ThrowTerminatingError(new ErrorRecord(ex, "InvalidParameterSetAsJob", ErrorCategory.InvalidOperation, null)); - } -#endif - - // Timeout, For, Delay, Progress cannot be present if Wait is not present - if ((_timeoutSpecified || _waitForSpecified || _delaySpecified) && !Wait) - { - InvalidOperationException ex = new InvalidOperationException(ComputerResources.RestartComputerInvalidParameter); - ThrowTerminatingError(new ErrorRecord(ex, "RestartComputerInvalidParameter", ErrorCategory.InvalidOperation, null)); - } - - if (Wait) - { - _activityId = (new Random()).Next(); - if (_timeout == -1 || _timeout >= int.MaxValue / 1000) - { - _timeoutInMilliseconds = int.MaxValue; - } - else - { - _timeoutInMilliseconds = _timeout * 1000; - } - - // We don't support combined service types for now - switch (_waitFor) - { - case WaitForServiceTypes.Wmi: - case WaitForServiceTypes.WinRM: - break; - case WaitForServiceTypes.PowerShell: - _powershell = System.Management.Automation.PowerShell.Create(); - _powershell.AddScript(TestPowershellScript); - break; - default: - InvalidOperationException ex = new InvalidOperationException(ComputerResources.NoSupportForCombinedServiceType); - ErrorRecord error = new ErrorRecord(ex, "NoSupportForCombinedServiceType", ErrorCategory.InvalidOperation, (int)_waitFor); - ThrowTerminatingError(error); - break; - } - } - } - - /// - /// ProcessRecord method. - /// - [SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling")] - protected override void ProcessRecord() - { - // Validate parameters - ValidateComputerNames(); - - object[] flags = new object[] { 2, 0 }; - if (Force) flags[0] = 6; - -#if CORECLR - if (ParameterSetName.Equals(DefaultParameterSet, StringComparison.OrdinalIgnoreCase)) - { -#else // TODO:CORECLR Revisit if or when jobs are supported - if (ParameterSetName.Equals(AsJobParameterSet, StringComparison.OrdinalIgnoreCase)) - { - string[] names = _validatedComputerNames.ToArray(); - string strComputers = ComputerWMIHelper.GetMachineNames(names); - if (!ShouldProcess(strComputers)) - return; - - InvokeWmiMethod WmiInvokeCmd = new InvokeWmiMethod(); - WmiInvokeCmd.Path = ComputerWMIHelper.WMI_Class_OperatingSystem + "=@"; - WmiInvokeCmd.ComputerName = names; - WmiInvokeCmd.Authentication = DcomAuthentication; - WmiInvokeCmd.Impersonation = Impersonation; - WmiInvokeCmd.Credential = Credential; - WmiInvokeCmd.ThrottleLimit = ThrottleLimit; - WmiInvokeCmd.Name = "Win32Shutdown"; - WmiInvokeCmd.EnableAllPrivileges = SwitchParameter.Present; - WmiInvokeCmd.ArgumentList = flags; - PSWmiJob wmiJob = new PSWmiJob(WmiInvokeCmd, names, ThrottleLimit, Job.GetCommandTextFromInvocationInfo(this.MyInvocation)); - this.JobRepository.Add(wmiJob); - WriteObject(wmiJob); - } - else if (ParameterSetName.Equals(DefaultParameterSet, StringComparison.OrdinalIgnoreCase)) - { - // CoreCLR does not support DCOM, so there is no point checking - // it here. It was already validated in BeginProcessing(). - - bool dcomInUse = Protocol.Equals(ComputerWMIHelper.DcomProtocol, StringComparison.OrdinalIgnoreCase); - ConnectionOptions options = ComputerWMIHelper.GetConnectionOptions(this.DcomAuthentication, this.Impersonation, this.Credential); -#endif - if (Wait && _timeout != 0) - { - _validatedComputerNames = -#if !CORECLR - dcomInUse ? SetUpComputerInfoUsingDcom(_validatedComputerNames, options) : -#endif - SetUpComputerInfoUsingWsman(_validatedComputerNames, _cancel.Token); - } - - foreach (string computer in _validatedComputerNames) - { - bool isLocal = false; - string compname; - - if (computer.Equals("localhost", StringComparison.CurrentCultureIgnoreCase)) - { - compname = _shortLocalMachineName; - isLocal = true; - -#if !CORECLR - if (dcomInUse) - { - // The local machine will always at the end of the list. If the current target - // computer is the local machine, it's safe to set Username and Password to null. - options.Username = null; - options.SecurePassword = null; - } -#endif - } - else - { - compname = computer; - } - - // Generate target and action strings - string action = - StringUtil.Format( - ComputerResources.RestartComputerAction, - isLocal ? ComputerResources.LocalShutdownPrivilege : ComputerResources.RemoteShutdownPrivilege); - string target = - isLocal ? StringUtil.Format(ComputerResources.DoubleComputerName, "localhost", compname) : compname; - - if (!ShouldProcess(target, action)) - { - continue; - } - - bool isSuccess = -#if !CORECLR - dcomInUse ? RestartOneComputerUsingDcom(this, isLocal, compname, flags, options) : -#endif - ComputerWMIHelper.InvokeWin32ShutdownUsingWsman(this, isLocal, compname, flags, Credential, WsmanAuthentication, ComputerResources.RestartcomputerFailed, "RestartcomputerFailed", _cancel.Token); - - if (isSuccess && Wait && _timeout != 0) - { - _waitOnComputers.Add(computer); - } - }//end foreach - - if (_waitOnComputers.Count > 0) - { - var restartStageTestList = new List(_waitOnComputers); - var wmiTestList = new List(); - var winrmTestList = new List(); - var psTestList = new List(); - var allDoneList = new List(); - - bool isForWmi = _waitFor.Equals(WaitForServiceTypes.Wmi); - bool isForWinRm = _waitFor.Equals(WaitForServiceTypes.WinRM); - bool isForPowershell = _waitFor.Equals(WaitForServiceTypes.PowerShell); - - int indicatorIndex = 0; - int machineCompleteRestart = 0; - int actualDelay = SecondsToWaitForRestartToBegin; - bool first = true; - bool waitComplete = false; - - _percent = 0; - _status = ComputerResources.WaitForRestartToBegin; - _activity = _waitOnComputers.Count == 1 ? - StringUtil.Format(ComputerResources.RestartSingleComputerActivity, _waitOnComputers[0]) : - ComputerResources.RestartMultipleComputersActivity; - - _timer = new Timer(OnTimedEvent, null, _timeoutInMilliseconds, System.Threading.Timeout.Infinite); - - while (true) - { - int loopCount = actualDelay * 4; // (delay * 1000)/250ms - while (loopCount > 0) - { - WriteProgress(_indicator[(indicatorIndex++) % 4] + _activity, _status, _percent, ProgressRecordType.Processing); - - loopCount--; - _waitHandler.Wait(250); - if (_exit) { break; } - } - - if (first) - { - actualDelay = _delay; - first = false; - - if (_waitOnComputers.Count > 1) - { - _status = StringUtil.Format(ComputerResources.WaitForMultipleComputers, machineCompleteRestart, _waitOnComputers.Count); - WriteProgress(_indicator[(indicatorIndex++) % 4] + _activity, _status, _percent, ProgressRecordType.Processing); - } - } - - do - { - // Test restart stage. - // We check if the target machine has already rebooted by querying the LastBootUpTime from the Win32_OperatingSystem object. - // So after this step, we are sure that both the Network and the WMI or WinRM service have already come up. - if (_exit) { break; } - if (restartStageTestList.Count > 0) - { - if (_waitOnComputers.Count == 1) - { - _status = ComputerResources.VerifyRebootStage; - _percent = CalculateProgressPercentage(StageVerification); - WriteProgress(_indicator[(indicatorIndex++) % 4] + _activity, _status, _percent, ProgressRecordType.Processing); - } - List nextTestList = (isForWmi || isForPowershell) ? wmiTestList : winrmTestList; - restartStageTestList = -#if !CORECLR - dcomInUse ? TestRestartStageUsingDcom(restartStageTestList, nextTestList, _cancel.Token, options) : -#endif - TestRestartStageUsingWsman(restartStageTestList, nextTestList, _cancel.Token); - } - - // Test WMI service - if (_exit) { break; } - if (wmiTestList.Count > 0) - { -#if !CORECLR - if (dcomInUse) - { - // CIM-DCOM is in use. In this case, restart stage checking is done by using WMIv1, - // so the WMI service on the target machine is already up at this point. - winrmTestList.AddRange(wmiTestList); - wmiTestList.Clear(); - - if (_waitOnComputers.Count == 1) - { - // This is to simulate the test for WMI service - _status = ComputerResources.WaitForWMI; - _percent = CalculateProgressPercentage(WmiConnectionTest); - - loopCount = actualDelay * 4; // (delay * 1000)/250ms - while (loopCount > 0) - { - WriteProgress(_indicator[(indicatorIndex++) % 4] + _activity, _status, _percent, ProgressRecordType.Processing); - - loopCount--; - _waitHandler.Wait(250); - if (_exit) { break; } - } - } - } - else -#endif - // This statement block executes for both CLRs. - // In the "full" CLR, it serves as the else case. - { - if (_waitOnComputers.Count == 1) - { - _status = ComputerResources.WaitForWMI; - _percent = CalculateProgressPercentage(WmiConnectionTest); - WriteProgress(_indicator[(indicatorIndex++) % 4] + _activity, _status, _percent, ProgressRecordType.Processing); - } - wmiTestList = TestWmiConnectionUsingWsman(wmiTestList, winrmTestList, _cancel.Token, Credential, WsmanAuthentication, this); - } - } - if (isForWmi) { break; } - - // Test WinRM service - if (_exit) { break; } - if (winrmTestList.Count > 0) - { -#if !CORECLR - if (dcomInUse) - { - if (_waitOnComputers.Count == 1) - { - _status = ComputerResources.WaitForWinRM; - _percent = CalculateProgressPercentage(WinrmConnectionTest); - WriteProgress(_indicator[(indicatorIndex++) % 4] + _activity, _status, _percent, ProgressRecordType.Processing); - } - winrmTestList = TestWinrmConnection(winrmTestList, psTestList, _cancel.Token); - } - else -#endif - // This statement block executes for both CLRs. - // In the "full" CLR, it serves as the else case. - { - // CIM-WSMan in use. In this case, restart stage checking is done by using WMIv2, - // so the WinRM service on the target machine is already up at this point. - psTestList.AddRange(winrmTestList); - winrmTestList.Clear(); - - if (_waitOnComputers.Count == 1) - { - // This is to simulate the test for WinRM service - _status = ComputerResources.WaitForWinRM; - _percent = CalculateProgressPercentage(WinrmConnectionTest); - - loopCount = actualDelay * 4; // (delay * 1000)/250ms - while (loopCount > 0) - { - WriteProgress(_indicator[(indicatorIndex++) % 4] + _activity, _status, _percent, ProgressRecordType.Processing); - - loopCount--; - _waitHandler.Wait(250); - if (_exit) { break; } - } - } - } - } - if (isForWinRm) { break; } - - // Test PowerShell - if (_exit) { break; } - if (psTestList.Count > 0) - { - if (_waitOnComputers.Count == 1) - { - _status = ComputerResources.WaitForPowerShell; - _percent = CalculateProgressPercentage(PowerShellConnectionTest); - WriteProgress(_indicator[(indicatorIndex++) % 4] + _activity, _status, _percent, ProgressRecordType.Processing); - } - psTestList = TestPowerShell(psTestList, allDoneList, _powershell, this.Credential); - } - } while (false); - - // if time is up or Ctrl+c is typed, break out - if (_exit) { break; } - - // Check if the restart completes - switch (_waitFor) - { - case WaitForServiceTypes.Wmi: - waitComplete = (winrmTestList.Count == _waitOnComputers.Count); - machineCompleteRestart = winrmTestList.Count; - break; - case WaitForServiceTypes.WinRM: - waitComplete = (psTestList.Count == _waitOnComputers.Count); - machineCompleteRestart = psTestList.Count; - break; - case WaitForServiceTypes.PowerShell: - waitComplete = (allDoneList.Count == _waitOnComputers.Count); - machineCompleteRestart = allDoneList.Count; - break; - } - - // Wait is done or time is up - if (waitComplete || _exit) - { - if (waitComplete) - { - _status = ComputerResources.RestartComplete; - WriteProgress(_indicator[indicatorIndex % 4] + _activity, _status, 100, ProgressRecordType.Completed); - _timer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite); - } - break; - } - - if (_waitOnComputers.Count > 1) - { - _status = StringUtil.Format(ComputerResources.WaitForMultipleComputers, machineCompleteRestart, _waitOnComputers.Count); - _percent = machineCompleteRestart * 100 / _waitOnComputers.Count; - } - }// end while(true) - - if (_timeUp) - { - // The timeout expires. Write out timeout error messages for the computers that haven't finished restarting - do - { - if (restartStageTestList.Count > 0) { WriteOutTimeoutError(restartStageTestList); } - if (wmiTestList.Count > 0) { WriteOutTimeoutError(wmiTestList); } - // Wait for WMI. All computers that finished restarting are put in "winrmTestList" - if (isForWmi) { break; } - - // Wait for WinRM. All computers that finished restarting are put in "psTestList" - if (winrmTestList.Count > 0) { WriteOutTimeoutError(winrmTestList); } - if (isForWinRm) { break; } - - if (psTestList.Count > 0) { WriteOutTimeoutError(psTestList); } - // Wait for PowerShell. All computers that finished restarting are put in "allDoneList" - } while (false); - } - }// end if(waitOnComputer.Count > 0) - }//end DefaultParameter - }//End Processrecord - - /// - /// to implement ^C - /// - protected override void StopProcessing() - { - _exit = true; - _cancel.Cancel(); - _waitHandler.Set(); - - if (_timer != null) - { - _timer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite); - } - - if (_powershell != null) - { - _powershell.Stop(); - _powershell.Dispose(); - } - } - -#endregion "Overrides" - } - -#endregion Restart-Computer - -#region Stop-Computer - - /// - /// cmdlet to stop computer - /// - [Cmdlet(VerbsLifecycle.Stop, "Computer", SupportsShouldProcess = true, - HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135263", RemotingCapability = RemotingCapability.SupportedByCommand)] - public sealed class StopComputerCommand : PSCmdlet, IDisposable - { -#region Private Members - -#if !CORECLR - private ManagementObjectSearcher _searcher; -#endif - private readonly CancellationTokenSource _cancel = new CancellationTokenSource(); - private TransportProtocol _transportProtocol = TransportProtocol.DCOM; - -#endregion - -#region "Parameters" - - /// - /// parameter - /// - [Parameter] - public SwitchParameter AsJob { get; set; } = false; - - /// - /// The following is the definition of the input parameter "DcomAuthentication". - /// Specifies the authentication level to be used with WMI connection. Valid - /// values are: - /// - /// Unchanged = -1, - /// Default = 0, - /// None = 1, - /// Connect = 2, - /// Call = 3, - /// Packet = 4, - /// PacketIntegrity = 5, - /// PacketPrivacy = 6. - /// - [Parameter] - [Alias("Authentication")] - public AuthenticationLevel DcomAuthentication { get; set; } = AuthenticationLevel.Packet; - - /// - /// The authentication options for CIM_WSMan connection - /// - [Parameter] - [ValidateSet( - "Default", - "Basic", - "Negotiate", // can be used with and without credential (without -> PSRP mapped to NegotiateWithImplicitCredential) - "CredSSP", - "Digest", - "Kerberos")] // can be used with and without credential (not sure about implications) - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] - public string WsmanAuthentication { get; set; } = "Default"; - - /// - /// Specify the protocol to use - /// - [Parameter] - [ValidateSet(ComputerWMIHelper.DcomProtocol, ComputerWMIHelper.WsmanProtocol)] - public string Protocol { get; set; } = -#if CORECLR - //CoreClr does not support DCOM protocol - // This change makes sure that the the command works seamlessly if user did not explicitly entered the protocol - ComputerWMIHelper.WsmanProtocol; -#else - ComputerWMIHelper.DcomProtocol; -#endif - - /// - /// The following is the definition of the input parameter "ComputerName". - /// Value of the address requested. The form of the value can be either the - /// computer name ("wxyz1234"), IPv4 address ("192.168.177.124"), or IPv6 - /// address ("2010:836B:4179::836B:4179"). - /// - [Parameter(Position = 0, ValueFromPipelineByPropertyName = true)] - [ValidateNotNullOrEmpty] - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - [Alias("CN", "__SERVER", "Server", "IPAddress")] - public String[] ComputerName { get; set; } = new string[] { "." }; - - - /// - /// The following is the definition of the input parameter "Credential". - /// Specifies a user account that has permission to perform this action. Type a - /// user-name, such as "User01" or "Domain01\User01", or enter a PSCredential - /// object, such as one from the Get-Credential cmdlet - /// - [Parameter(Position = 1)] - [ValidateNotNullOrEmpty] - [Credential] - public PSCredential Credential { get; set; } - - /// - /// The following is the definition of the input parameter "Impersonation". - /// Specifies the impersonation level to use when calling the WMI method. Valid - /// values are: - /// - /// Default = 0, - /// Anonymous = 1, - /// Identify = 2, - /// Impersonate = 3, - /// Delegate = 4. - /// - [Parameter] - public ImpersonationLevel Impersonation { get; set; } = ImpersonationLevel.Impersonate; - - /// - /// The following is the definition of the input parameter "ThrottleLimit". - /// The number of concurrent computers on which the command will be allowed to - /// execute - /// - [Parameter] - [ValidateRange(int.MinValue, (int)1000)] - public Int32 ThrottleLimit - { - get { return _throttlelimit; } - set - { - _throttlelimit = value; - if (_throttlelimit <= 0) - _throttlelimit = 32; - } - } - private Int32 _throttlelimit = 32; - - /// - /// The following is the definition of the input parameter "ThrottleLimit". - /// The number of concurrent computers on which the command will be allowed to - /// execute - /// - [Parameter] - public SwitchParameter Force { get; set; } = false; - - #endregion "parameters" - -#region "IDisposable Members" - - /// - /// Dispose Method - /// - public void Dispose() - { - try - { - _cancel.Dispose(); - } - catch (ObjectDisposedException) { } - } - -#endregion "IDisposable Members" - -#region "Overrides" - - /// - /// BeginProcessing - /// - protected override void BeginProcessing() - { - base.BeginProcessing(); - - // Verify parameter set - bool haveProtocolParam = this.MyInvocation.BoundParameters.ContainsKey("Protocol"); - bool haveWsmanAuthenticationParam = this.MyInvocation.BoundParameters.ContainsKey("WsmanAuthentication"); - bool haveDcomAuthenticationParam = this.MyInvocation.BoundParameters.ContainsKey("DcomAuthentication"); - bool haveDcomImpersonation = this.MyInvocation.BoundParameters.ContainsKey("Impersonation"); - _transportProtocol = (this.Protocol.Equals(ComputerWMIHelper.WsmanProtocol, StringComparison.OrdinalIgnoreCase) || (haveWsmanAuthenticationParam && !haveProtocolParam)) ? - TransportProtocol.WSMan : TransportProtocol.DCOM; - - if (haveWsmanAuthenticationParam && (haveDcomAuthenticationParam || haveDcomImpersonation)) - { - string errMsg = StringUtil.Format(ComputerResources.StopCommandParamWSManAuthConflict, ComputerResources.StopCommandParamMessage); - ThrowTerminatingError( - new ErrorRecord( - new PSArgumentException(errMsg), - "InvalidParameter", - ErrorCategory.InvalidArgument, - this)); - } - - if ((_transportProtocol == TransportProtocol.DCOM) && haveWsmanAuthenticationParam) - { - string errMsg = StringUtil.Format(ComputerResources.StopCommandWSManAuthProtocolConflict, ComputerResources.StopCommandParamMessage); - ThrowTerminatingError( - new ErrorRecord( - new PSArgumentException(errMsg), - "InvalidParameter", - ErrorCategory.InvalidArgument, - this)); - } - - if ((_transportProtocol == TransportProtocol.WSMan) && (haveDcomAuthenticationParam || haveDcomImpersonation)) - { - string errMsg = StringUtil.Format(ComputerResources.StopCommandAuthProtocolConflict, ComputerResources.StopCommandParamMessage); - ThrowTerminatingError( - new ErrorRecord( - new PSArgumentException(errMsg), - "InvalidParameter", - ErrorCategory.InvalidArgument, - this)); - } - -#if CORECLR - if (this.MyInvocation.BoundParameters.ContainsKey("DcomAuthentication")) - { - string errMsg = StringUtil.Format(ComputerResources.InvalidParameterForCoreClr, "DcomAuthentication"); - PSArgumentException ex = new PSArgumentException(errMsg, ComputerResources.InvalidParameterForCoreClr); - ThrowTerminatingError(new ErrorRecord(ex, "InvalidParameterForCoreClr", ErrorCategory.InvalidArgument, null)); - } - - if (this.MyInvocation.BoundParameters.ContainsKey("Impersonation")) - { - string errMsg = StringUtil.Format(ComputerResources.InvalidParameterForCoreClr, "Impersonation"); - PSArgumentException ex = new PSArgumentException(errMsg, ComputerResources.InvalidParameterForCoreClr); - ThrowTerminatingError(new ErrorRecord(ex, "InvalidParameterForCoreClr", ErrorCategory.InvalidArgument, null)); - } - - if(this.Protocol.Equals(ComputerWMIHelper.DcomProtocol , StringComparison.OrdinalIgnoreCase)) - { - InvalidOperationException ex = new InvalidOperationException(ComputerResources.InvalidParameterDCOMNotSupported); - ThrowTerminatingError(new ErrorRecord(ex, "InvalidParameterDCOMNotSupported", ErrorCategory.InvalidOperation, null)); - } -#endif - } - - /// - /// ProcessRecord - /// - [SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling")] - protected override void ProcessRecord() - { - object[] flags = new object[] { 1, 0 }; - if (Force.IsPresent) - flags[0] = 5; - - switch (_transportProtocol) - { -#if !CORECLR - case TransportProtocol.DCOM: - ProcessDCOMProtocol(flags); - break; -#endif - - case TransportProtocol.WSMan: - ProcessWSManProtocol(flags); - break; - } - }//End Processrecord - - /// - /// to implement ^C - /// - protected override void StopProcessing() - { -#if !CORECLR - ManagementObjectSearcher searcher = _searcher; - if (searcher != null) - { - try - { - searcher.Dispose(); - } - catch (ObjectDisposedException) { } - } -#endif - - try - { - _cancel.Cancel(); - } - catch (ObjectDisposedException) { } - catch (AggregateException) { } - } - -#endregion "Overrides" - -#region Private Methods - -#if !CORECLR - private void ProcessDCOMProtocol(object[] flags) - { - if (AsJob.IsPresent) - { - string strComputers = ComputerWMIHelper.GetMachineNames(ComputerName); - if (!ShouldProcess(strComputers)) - return; - InvokeWmiMethod WmiInvokeCmd = new InvokeWmiMethod(); - WmiInvokeCmd.Path = ComputerWMIHelper.WMI_Class_OperatingSystem + "=@"; - WmiInvokeCmd.ComputerName = ComputerName; - WmiInvokeCmd.Authentication = DcomAuthentication; - WmiInvokeCmd.Impersonation = Impersonation; - WmiInvokeCmd.Credential = Credential; - WmiInvokeCmd.ThrottleLimit = _throttlelimit; - WmiInvokeCmd.Name = "Win32Shutdown"; - WmiInvokeCmd.EnableAllPrivileges = SwitchParameter.Present; - WmiInvokeCmd.ArgumentList = flags; - PSWmiJob wmiJob = new PSWmiJob(WmiInvokeCmd, ComputerName, _throttlelimit, Job.GetCommandTextFromInvocationInfo(this.MyInvocation)); - this.JobRepository.Add(wmiJob); - WriteObject(wmiJob); - } - else - { - string compname = string.Empty; - string strLocal = string.Empty; - - foreach (string computer in ComputerName) - { - if ((computer.Equals("localhost", StringComparison.CurrentCultureIgnoreCase)) || (computer.Equals(".", StringComparison.OrdinalIgnoreCase))) - { - compname = Dns.GetHostName(); - strLocal = "localhost"; - } - else - { - compname = computer; - } - - if (!ShouldProcess(StringUtil.Format(ComputerResources.DoubleComputerName, strLocal, compname))) - { - continue; - } - else - { - try - { - ConnectionOptions options = ComputerWMIHelper.GetConnectionOptions(DcomAuthentication, this.Impersonation, this.Credential); - ManagementScope scope = new ManagementScope(ComputerWMIHelper.GetScopeString(computer, ComputerWMIHelper.WMI_Path_CIM), options); - EnumerationOptions enumOptions = new EnumerationOptions(); - enumOptions.UseAmendedQualifiers = true; - enumOptions.DirectRead = true; - ObjectQuery query = new ObjectQuery("select * from " + ComputerWMIHelper.WMI_Class_OperatingSystem); - using (_searcher = new ManagementObjectSearcher(scope, query, enumOptions)) - { - foreach (ManagementObject obj in _searcher.Get()) - { - using (obj) - { - object result = obj.InvokeMethod("Win32shutdown", flags); - int retVal = Convert.ToInt32(result.ToString(), CultureInfo.CurrentCulture); - if (retVal != 0) - { - ComputerWMIHelper.WriteNonTerminatingError(retVal, this, compname); - } - } - } - } - _searcher = null; - } - catch (ManagementException e) - { - ErrorRecord errorRecord = new ErrorRecord(e, "StopComputerException", ErrorCategory.InvalidOperation, compname); - WriteError(errorRecord); - continue; - } - catch (System.Runtime.InteropServices.COMException e) - { - ErrorRecord errorRecord = new ErrorRecord(e, "StopComputerException", ErrorCategory.InvalidOperation, compname); - WriteError(errorRecord); - continue; - } - } - } - } - } -#endif - - private void ProcessWSManProtocol(object[] flags) - { - if (AsJob.IsPresent) - { - // TODO: Need job for MI.Net WSMan protocol - // Early return of job object. - throw new PSNotSupportedException(); - } - - foreach (string computer in ComputerName) - { - string compname = string.Empty; - string strLocal = string.Empty; - bool isLocalHost = false; - - if (_cancel.Token.IsCancellationRequested) { break; } - - if ((computer.Equals("localhost", StringComparison.CurrentCultureIgnoreCase)) || (computer.Equals(".", StringComparison.OrdinalIgnoreCase))) - { - compname = Dns.GetHostName(); - strLocal = "localhost"; - isLocalHost = true; - } - else - { - compname = computer; - } - - if (!ShouldProcess(StringUtil.Format(ComputerResources.DoubleComputerName, strLocal, compname))) - { - continue; - } - else - { - ComputerWMIHelper.InvokeWin32ShutdownUsingWsman( - this, - isLocalHost, - compname, - flags, - Credential, - WsmanAuthentication, - ComputerResources.StopcomputerFailed, - "StopComputerException", - _cancel.Token); - } - } - } - -#endregion - } - -#endregion - -#if !CORECLR // TODO:CORECLR Enable once moved to MI .Net - -#region Restore-Computer - - /// - /// This cmdlet is to Restore Computer - /// - [Cmdlet(VerbsData.Restore, "Computer", SupportsShouldProcess = true, HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135254")] - public sealed class RestoreComputerCommand : PSCmdlet, IDisposable - { -#region Parameters - /// - /// Restorepoint parameter - /// - - [Parameter(Position = 0, Mandatory = true)] - [ValidateNotNull] - [ValidateRangeAttribute((int)1, int.MaxValue)] - [Alias("SequenceNumber", "SN", "RP")] - public int RestorePoint { get; set; } - - #endregion - - private ManagementClass WMIClass; - -#region "IDisposable Members" - - /// - /// Dispose Method - /// - public void Dispose() - { - this.Dispose(true); - // Use SuppressFinalize in case a subclass - // of this type implements a finalizer. - GC.SuppressFinalize(this); - } - - /// - /// Dispose Method. - /// - /// - public void Dispose(bool disposing) - { - if (disposing) - { - if (WMIClass != null) - { - WMIClass.Dispose(); - } - } - } - -#endregion "IDisposable Members" - -#region overrides - /// - /// Restores the computer with - /// - protected override void BeginProcessing() - { - // system restore APIs are not supported on ARM platform - if (ComputerWMIHelper.SkipSystemRestoreOperationForARMPlatform(this)) - { - return; - } - - try - { - ConnectionOptions conn = ComputerWMIHelper.GetConnectionOptions(AuthenticationLevel.Packet, ImpersonationLevel.Impersonate, null); - ManagementPath mPath = new ManagementPath(); - mPath.Path = ComputerWMIHelper.WMI_Path_Default; - ManagementScope scope = new ManagementScope(mPath, conn); - scope.Connect(); - WMIClass = new ManagementClass(ComputerWMIHelper.WMI_Class_SystemRestore); - WMIClass.Scope = scope; - - //query to get the list of restore points - ObjectQuery oquery = new ObjectQuery("select * from " + ComputerWMIHelper.WMI_Class_SystemRestore + " where SequenceNumber = " + RestorePoint); - using (ManagementObjectSearcher R_results = new ManagementObjectSearcher(scope, oquery)) - { - //check if the entered restore point is a valid one - if (R_results.Get().Count == 0) - { - string message = StringUtil.Format(ComputerResources.InvalidRestorePoint, RestorePoint); - ArgumentException e = new ArgumentException(message); - ErrorRecord errorrecord = new ErrorRecord(e, "InvalidRestorePoint", ErrorCategory.InvalidArgument, null); - WriteError(errorrecord); - return; - } - } - //confirm with the user before restoring - string computerName = Environment.MachineName; - if (!ShouldProcess(computerName)) - { - return; - } - else - { - //add the restorepoint parameter and invoke th emethod - Object[] arr = new Object[] { RestorePoint }; - WMIClass.InvokeMethod("Restore", arr); - //Restore requires a Reboot and while reboot only the restore actually happens - //code to restart computer - mPath.Path = ComputerWMIHelper.WMI_Path_CIM; - scope.Path = mPath; - ManagementClass OsWMIClass = new ManagementClass(ComputerWMIHelper.WMI_Class_OperatingSystem); - OsWMIClass.Scope = scope; - ObjectQuery objQuery = new ObjectQuery("Select * from " + ComputerWMIHelper.WMI_Class_OperatingSystem); - using (ManagementObjectSearcher results = new ManagementObjectSearcher(scope, objQuery)) - { - foreach (ManagementObject mobj in results.Get()) - { - using (mobj) - { - string[] param = { "" }; - mobj.InvokeMethod("Reboot", param); - } - } - } - } - } - catch (ManagementException e) - { - if (e.ErrorCode.ToString().Equals("NotFound") || e.ErrorCode.ToString().Equals("InvalidClass")) - { - Exception Ex = new ArgumentException(StringUtil.Format(ComputerResources.NotSupported)); - WriteError(new ErrorRecord(Ex, "RestoreComputerNotSupported", ErrorCategory.InvalidOperation, null)); - } - else - { - ErrorRecord errorRecord = new ErrorRecord(e, "GetWMIManagementException", ErrorCategory.InvalidOperation, null); - WriteError(errorRecord); - } - } - catch (COMException e) - { - if (string.IsNullOrEmpty(e.Message)) - { - Exception Ex = new ArgumentException(StringUtil.Format(ComputerResources.SystemRestoreServiceDisabled)); - WriteError(new ErrorRecord(Ex, "ServiceDisabled", ErrorCategory.InvalidOperation, null)); - } - else - { - ErrorRecord errorRecord = new ErrorRecord(e, "COMException", ErrorCategory.InvalidOperation, null); - WriteError(errorRecord); - } - } - } - - /// - /// to implement ^C - /// - protected override void StopProcessing() - { - if (WMIClass != null) - { - WMIClass.Dispose(); - } - } - -#endregion overrides - } -#endregion - -#region Add-Computer - - /// - /// Options for joining a computer to a domain - /// - [Flags] - public enum JoinOptions - { - /// - /// Create account on the domain - /// - AccountCreate = 0x2, - - /// - /// Join operation is part of an upgrade - /// - Win9XUpgrade = 0x10, - - /// - /// Perform an unsecure join - /// - UnsecuredJoin = 0x40, - - /// - /// Indicate that the password passed to the join operation is the local machine account password, not a user password. - /// It's valid only for unsecure join - /// - PasswordPass = 0x80, - - /// - /// Writing SPN and DNSHostName attributes on the computer object should be deferred until the rename operation that - /// follows the join operation - /// - DeferSPNSet = 0x100, - - /// - /// Join the target machine with a new name queried from the registry. This options is used if the rename has been called prior - /// to rebooting the machine - /// - JoinWithNewName = 0x400, - - /// - /// Use a readonly domain controller - /// - JoinReadOnly = 0x800, - - /// - /// Invoke during install - /// - InstallInvoke = 0x40000 - } - - /// - /// Adds the specified computer(s) to the Domain or Work Group. If the account - /// does not already exist on the domain, it also creates one (see notes for - /// implementation details). - /// If the computer is already joined to a domain, it can be moved to a new - /// domain (see notes for implementation details). - /// - [SuppressMessage("Microsoft.PowerShell", "PS1004AcceptForceParameterWhenCallingShouldContinue")] - [Cmdlet(VerbsCommon.Add, "Computer", SupportsShouldProcess = true, DefaultParameterSetName = DomainParameterSet, - HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135194", RemotingCapability = RemotingCapability.SupportedByCommand)] - [OutputType(typeof(ComputerChangeInfo))] - public class AddComputerCommand : PSCmdlet - { -#region parameter - - private const string DomainParameterSet = "Domain"; - private const string WorkgroupParameterSet = "Workgroup"; - - /// - /// Target computer names - /// - [Parameter(ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] - [ValidateNotNullOrEmpty] - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - public string[] ComputerName { get; set; } = { "localhost" }; - - /// - /// The local admin credential to the target computer - /// - [Parameter] - [Credential] - [ValidateNotNullOrEmpty] - public PSCredential LocalCredential { get; set; } - - /// - /// The domain credential used to unjoin a domain - /// - [Parameter(ParameterSetName = DomainParameterSet)] - [Credential] - [ValidateNotNullOrEmpty] - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] - public PSCredential UnjoinDomainCredential { get; set; } - - /// - /// The domain credential. - /// In DomainParameterSet, it is for the domain to join to. - /// In WorkgroupParameterSet, it is for the domain to disjoin from. - /// - [Parameter(ParameterSetName = DomainParameterSet, Mandatory = true)] - [Parameter(ParameterSetName = WorkgroupParameterSet)] - [Alias("DomainCredential")] - [Credential] - [ValidateNotNullOrEmpty] - public PSCredential Credential { get; set; } - - /// - /// Name of the domain to join - /// - [Parameter(Position = 0, Mandatory = true, ParameterSetName = DomainParameterSet)] - [Alias("DN", "Domain")] - [ValidateNotNullOrEmpty] - public String DomainName { get; set; } - - /// - /// The organization unit (OU). It's the path on the AD under which the new account will - /// be created - /// - [Parameter(ParameterSetName = DomainParameterSet)] - [Alias("OU")] - [ValidateNotNullOrEmpty] - public string OUPath { get; set; } - - /// - /// The name of a domain controller that performs the add. - /// - [Parameter(ParameterSetName = DomainParameterSet)] - [Alias("DC")] - [ValidateNotNullOrEmpty] - public string Server { get; set; } - - /// - /// Perform an unsecure join. - /// - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] - [Parameter(ParameterSetName = DomainParameterSet)] - public SwitchParameter Unsecure { get; set; } - - /// - /// Additional options for the "join domain" operation - /// - [Parameter(ParameterSetName = DomainParameterSet)] - public JoinOptions Options { get; set; } = JoinOptions.AccountCreate; - - /// - /// Name of the workgroup to join in. - /// - [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "WorkGroup")] - [Parameter(Position = 0, Mandatory = true, ParameterSetName = WorkgroupParameterSet)] - [Alias("WGN")] - [ValidateNotNullOrEmpty] - public string WorkgroupName { get; set; } - - /// - /// Restart the target computer - /// - [Parameter] - public SwitchParameter Restart { get; set; } = false; - - /// - /// Emit the output. - /// - [Parameter] - public SwitchParameter PassThru { get; set; } - - /// - /// New names for the target computers - /// - [Parameter(ValueFromPipelineByPropertyName = true)] - [ValidateNotNullOrEmpty] - public string NewName { get; set; } - - /// - /// To suppress ShouldContinue - /// - [Parameter] - public SwitchParameter Force - { - get { return _force; } - set { _force = value; } - } - private bool _force; - - private int _joinDomainflags = 1; - private bool _containsLocalHost = false; - private string _newNameForLocalHost = null; - - private readonly string _shortLocalMachineName = Dns.GetHostName(); - private readonly string _fullLocalMachineName = Dns.GetHostEntry("").HostName; - -#endregion parameter - -#region private - - /// - /// Unjoin the computer from its current domain - /// - /// In the DomainParameterSet, the UnjoinDomainCredential is our first choice to unjoin a domain. - /// But if the UnjoinDomainCredential is not specified, the DomainCredential will be our second - /// choice. This is to keep the backward compatibility. In Win7, we can do: - /// Add-Computer -DomainName domain1 -Credential $credForDomain1AndDomain2 - /// to switch the local machine that is currently in domain2 to domain1. - /// - /// Since DomainCredential has an alias "Credential", the same command should still work for the - /// new Add-Computer cmdlet. - /// - /// In the WorkgroupParameterSet, the UnjoinDomainCredential is the only choice. - /// - /// - /// - /// - /// - /// - /// - /// - private int UnjoinDomain(ManagementObject computerSystem, string computerName, string curDomainName, string dUserName, string dPassword) - { - ManagementBaseObject unjoinDomainParameter = computerSystem.GetMethodParameters("UnjoinDomainOrWorkgroup"); - unjoinDomainParameter.SetPropertyValue("UserName", dUserName); - unjoinDomainParameter.SetPropertyValue("Password", dPassword); - unjoinDomainParameter.SetPropertyValue("FUnjoinOptions", 4); // default option, disable the active directory - - ManagementBaseObject result = computerSystem.InvokeMethod("UnjoinDomainOrWorkgroup", unjoinDomainParameter, null); - Dbg.Diagnostics.Assert(result != null, "result cannot be null if the Unjoin method is invoked"); - int returnCode = Convert.ToInt32(result["ReturnValue"], CultureInfo.CurrentCulture); - if (returnCode != 0) - { - var ex = new Win32Exception(returnCode); - WriteErrorHelper(ComputerResources.FailToUnjoinDomain, "FailToUnjoinDomain", computerName, - ErrorCategory.OperationStopped, false, computerName, curDomainName, ex.Message); - } - return returnCode; - } - - /// - /// Join a domain from a workgroup - /// - /// - /// If a computer is already in a domain, we first unjoin it from its current domain, and - /// then do the join operation to the new domain. So when this method is invoked, we are - /// currently in a workgroup - /// - /// - /// - /// - /// - /// - private int JoinDomain(ManagementObject computerSystem, string computerName, string oldDomainName, string curWorkgroupName) - { - string joinDomainUserName = Credential != null ? Credential.UserName : null; - string joinDomainPassword = Credential != null ? Utils.GetStringFromSecureString(Credential.Password) : null; - - ManagementBaseObject joinDomainParameter = computerSystem.GetMethodParameters("JoinDomainOrWorkgroup"); - joinDomainParameter.SetPropertyValue("Name", DomainName); - joinDomainParameter.SetPropertyValue("UserName", joinDomainUserName); - joinDomainParameter.SetPropertyValue("Password", joinDomainPassword); - joinDomainParameter.SetPropertyValue("AccountOU", OUPath); - joinDomainParameter.SetPropertyValue("FJoinOptions", _joinDomainflags); - - ManagementBaseObject result = computerSystem.InvokeMethod("JoinDomainOrWorkgroup", joinDomainParameter, null); - Dbg.Diagnostics.Assert(result != null, "result cannot be null if the Join method is invoked"); - int returnCode = Convert.ToInt32(result["ReturnValue"], CultureInfo.CurrentCulture); - if (returnCode != 0) - { - var ex = new Win32Exception(returnCode); - string errMsg; - string errorId; - if (oldDomainName != null) - { - errMsg = StringUtil.Format(ComputerResources.FailToJoinNewDomainAfterUnjoinOldDomain, - computerName, oldDomainName, DomainName, ex.Message); - errorId = "FailToJoinNewDomainAfterUnjoinOldDomain"; - } - else - { - errMsg = StringUtil.Format(ComputerResources.FailToJoinDomainFromWorkgroup, computerName, - DomainName, curWorkgroupName, ex.Message); - errorId = "FailToJoinDomainFromWorkgroup"; - } - - WriteErrorHelper(errMsg, errorId, computerName, ErrorCategory.OperationStopped, false); - } - return returnCode; - } - - /// - /// Join in a new workgroup from the current workgroup - /// - /// - /// - /// - /// - private int JoinWorkgroup(ManagementObject computerSystem, string computerName, string oldDomainName) - { - ManagementBaseObject joinWorkgroupParam = computerSystem.GetMethodParameters("JoinDomainOrWorkgroup"); - joinWorkgroupParam.SetPropertyValue("Name", WorkgroupName); - joinWorkgroupParam.SetPropertyValue("UserName", null); - joinWorkgroupParam.SetPropertyValue("Password", null); - joinWorkgroupParam.SetPropertyValue("FJoinOptions", 0); // join a workgroup - - ManagementBaseObject result = computerSystem.InvokeMethod("JoinDomainOrWorkgroup", joinWorkgroupParam, null); - Dbg.Diagnostics.Assert(result != null, "result cannot be null if the Join method is invoked"); - int returnCode = Convert.ToInt32(result["ReturnValue"], CultureInfo.CurrentCulture); - if (returnCode != 0) - { - var ex = new Win32Exception(returnCode); - string errMsg; - if (oldDomainName != null) - { - errMsg = - StringUtil.Format(ComputerResources.FailToSwitchFromDomainToWorkgroup, computerName, - oldDomainName, WorkgroupName, ex.Message); - } - else - { - errMsg = StringUtil.Format(ComputerResources.FailToJoinWorkGroup, computerName, WorkgroupName, - ex.Message); - } - - WriteErrorHelper(errMsg, "FailToJoinWorkGroup", computerName, ErrorCategory.OperationStopped, false); - } - return returnCode; - } - - /// - /// Rename the computer in workgroup - /// - /// - /// - /// - /// - private int RenameComputer(ManagementObject computerSystem, string computerName, string newName) - { - string domainUserName = null; - string domainPassword = null; - - if (DomainName != null && Credential != null) - { - // The rename operation happens after the computer is joined to the new domain, so we should provide - // the domain user name and password to the rename operation - domainUserName = Credential.UserName; - domainPassword = Utils.GetStringFromSecureString(Credential.Password); - } - - ManagementBaseObject renameParameter = computerSystem.GetMethodParameters("Rename"); - renameParameter.SetPropertyValue("Name", newName); - renameParameter.SetPropertyValue("UserName", domainUserName); - renameParameter.SetPropertyValue("Password", domainPassword); - - ManagementBaseObject result = computerSystem.InvokeMethod("Rename", renameParameter, null); - Dbg.Diagnostics.Assert(result != null, "result cannot be null if the Rename method is invoked"); - int returnCode = Convert.ToInt32(result["ReturnValue"], CultureInfo.CurrentCulture); - if (returnCode != 0) - { - var ex = new Win32Exception(returnCode); - string errMsg; - string errorId; - if (WorkgroupName != null) - { - errMsg = StringUtil.Format(ComputerResources.FailToRenameAfterJoinWorkgroup, computerName, - WorkgroupName, newName, ex.Message); - errorId = "FailToRenameAfterJoinWorkgroup"; - } - else - { - errMsg = StringUtil.Format(ComputerResources.FailToRenameAfterJoinDomain, computerName, DomainName, - newName, ex.Message); - errorId = "FailToRenameAfterJoinDomain"; - } - - WriteErrorHelper(errMsg, errorId, computerName, ErrorCategory.OperationStopped, false); - } - return returnCode; - } - - /// - /// Helper method to write out non-terminating errors - /// - /// - /// - /// - /// - /// - /// - private void WriteErrorHelper(string resourceString, string errorId, object targetObj, ErrorCategory category, bool terminating, params object[] args) - { - string errMsg; - if (null == args || 0 == args.Length) - { - // Don't format in case the string contains literal curly braces - errMsg = resourceString; - } - else - { - errMsg = StringUtil.Format(resourceString, args); - } - - if (String.IsNullOrEmpty(errMsg)) - { - Dbg.Diagnostics.Assert(false, "Could not load text for error record '" + errorId + "'"); - } - - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), errorId, - category, targetObj); - if (terminating) - { - ThrowTerminatingError(error); - } - else - { - WriteError(error); - } - } - - private void DoAddComputerAction(string computer, string newName, bool isLocalhost, ConnectionOptions options, EnumerationOptions enumOptions, ObjectQuery computerSystemQuery) - { - int returnCode = 0; - bool success = false; - string computerName = isLocalhost ? _shortLocalMachineName : computer; - - if (ParameterSetName == DomainParameterSet) - { - string action = StringUtil.Format(ComputerResources.AddComputerActionDomain, DomainName); - if (!ShouldProcess(computerName, action)) - { - return; - } - } - else - { - string action = StringUtil.Format(ComputerResources.AddComputerActionWorkgroup, WorkgroupName); - if (!ShouldProcess(computerName, action)) - { - return; - } - } - - // Check the length of the new name - if (newName != null && newName.Length > ComputerWMIHelper.NetBIOSNameMaxLength) - { - string truncatedName = newName.Substring(0, ComputerWMIHelper.NetBIOSNameMaxLength); - string query = StringUtil.Format(ComputerResources.TruncateNetBIOSName, truncatedName); - string caption = ComputerResources.TruncateNetBIOSNameCaption; - if (!Force && !ShouldContinue(query, caption)) - { - return; - } - } - - // If LocalCred is given, use the local credential for WMI connection. Otherwise, use - // the current caller's context (Username = null, Password = null) - if (LocalCredential != null) - { - options.SecurePassword = LocalCredential.Password; - options.Username = ComputerWMIHelper.GetLocalAdminUserName(computerName, LocalCredential); - } - - // The local machine will always be processed in the very end. If the - // current target computer is the local machine, it's the last one to - // be processed, so we can safely set the Username and Password to be - // null. We cannot use a user credential when connecting to the local - // machine. - if (isLocalhost) - { - options.Username = null; - options.SecurePassword = null; - } - - ManagementScope scope = new ManagementScope(ComputerWMIHelper.GetScopeString(computer, ComputerWMIHelper.WMI_Path_CIM), options); - - try - { - using (var searcher = new ManagementObjectSearcher(scope, computerSystemQuery, enumOptions)) - { - foreach (ManagementObject computerSystem in searcher.Get()) - { - using (computerSystem) - { - // If we are not using the new computer name, check the length of the target machine name - string hostName = (string)computerSystem["DNSHostName"]; - if (newName == null && hostName.Length > ComputerWMIHelper.NetBIOSNameMaxLength) - { - string truncatedName = hostName.Substring(0, ComputerWMIHelper.NetBIOSNameMaxLength); - string query = StringUtil.Format(ComputerResources.TruncateNetBIOSName, truncatedName); - string caption = ComputerResources.TruncateNetBIOSNameCaption; - if (!Force && !ShouldContinue(query, caption)) - { - continue; - } - } - - if (newName != null && hostName.Equals(newName, StringComparison.OrdinalIgnoreCase)) - { - WriteErrorHelper( - ComputerResources.NewNameIsOldName, - "NewNameIsOldName", - newName, - ErrorCategory.InvalidArgument, - false, - computerName, newName); - continue; - } - - if (ParameterSetName == DomainParameterSet) - { - if ((bool)computerSystem["PartOfDomain"]) - { - string curDomainName = (string)LanguagePrimitives.ConvertTo(computerSystem["Domain"], typeof(string), CultureInfo.InvariantCulture); - string shortDomainName = ""; - if (curDomainName.Contains(".")) - { - int dotIndex = curDomainName.IndexOf(".", StringComparison.OrdinalIgnoreCase); - shortDomainName = curDomainName.Substring(0, dotIndex); - } - - // If the target computer is already in the specified domain, throw an error - if (curDomainName.Equals(DomainName, StringComparison.OrdinalIgnoreCase) || shortDomainName.Equals(DomainName, StringComparison.OrdinalIgnoreCase)) - { - WriteErrorHelper(ComputerResources.AddComputerToSameDomain, - "AddComputerToSameDomain", computerName, - ErrorCategory.InvalidOperation, false, computerName, DomainName); - continue; - } - - // Switch between domains - // If the UnjoinDomainCredential is not specified, we assume the DomainCredential can be used for both removing - // the computer from its current domain, and adding the computer to the new domain. This behavior is supported on - // Win7, we don't want to break it. - PSCredential credTobeUsed = UnjoinDomainCredential ?? Credential; - string unjoinDomainUserName = credTobeUsed != null ? credTobeUsed.UserName : null; - string unjoinDomainPassword = credTobeUsed != null ? Utils.GetStringFromSecureString(credTobeUsed.Password) : null; - - // Leave the current domain - returnCode = UnjoinDomain(computerSystem, computerName, curDomainName, unjoinDomainUserName, unjoinDomainPassword); - if (returnCode == 0) - { - // Successfully unjoin the old domain, join the computer to the new domain - returnCode = JoinDomain(computerSystem, computerName, curDomainName, null); - - if (returnCode == 0 && newName != null) - { - // Rename the computer in the new domain - returnCode = RenameComputer(computerSystem, computerName, newName); - } - } - - success = returnCode == 0; - } - else - { - // Add a workgroup computer to domain - string curWorkgroupName = (string)LanguagePrimitives.ConvertTo(computerSystem["Domain"], typeof(string), CultureInfo.InvariantCulture); - returnCode = JoinDomain(computerSystem, computerName, null, curWorkgroupName); - - if (returnCode == 0 && newName != null) - { - returnCode = RenameComputer(computerSystem, computerName, newName); - } - - success = returnCode == 0; - } - } - else // WorkgroupParameterSet - { - if ((bool)computerSystem["PartOfDomain"]) - { - // Remind the user to have local admin credential only if the computer is domain joined - string shouldContinueMsg = ComputerResources.RemoveComputerConfirm; - if (!Force && !ShouldContinue(shouldContinueMsg, null /* null = default caption */ )) - { - continue; - } - - // Leave the current domain - string curDomainName = (string)LanguagePrimitives.ConvertTo(computerSystem["Domain"], typeof(string), CultureInfo.InvariantCulture); - string dUserName = Credential != null ? Credential.UserName : null; - string dPassword = Credential != null ? Utils.GetStringFromSecureString(Credential.Password) : null; - - returnCode = UnjoinDomain(computerSystem, computerName, curDomainName, dUserName, dPassword); - if (returnCode == 0) - { - // Join the specified workgroup - returnCode = JoinWorkgroup(computerSystem, computerName, curDomainName); - if (returnCode == 0 && newName != null) - { - // Rename the computer - returnCode = RenameComputer(computerSystem, computerName, newName); - } - } - - success = returnCode == 0; - } - else // in workgroup - { - string curWorkgroup = (string)LanguagePrimitives.ConvertTo(computerSystem["Domain"], typeof(string), CultureInfo.InvariantCulture); - if (curWorkgroup.Equals(WorkgroupName, StringComparison.OrdinalIgnoreCase)) - { - WriteErrorHelper(ComputerResources.AddComputerToSameWorkgroup, - "AddComputerToSameWorkgroup", computerName, - ErrorCategory.InvalidOperation, false, computerName, WorkgroupName); - continue; - } - - // Join to another workgroup - returnCode = JoinWorkgroup(computerSystem, computerName, null); - if (returnCode == 0 && newName != null) - { - returnCode = RenameComputer(computerSystem, computerName, newName); - } - - success = returnCode == 0; - } - }// end of else -- WorkgroupParameterSet - - if (PassThru) - { - WriteObject(ComputerWMIHelper.GetComputerStatusObject(returnCode, computerName)); - } - } - }// end of foreach - - // If successful and the Restart parameter is specified, restart the computer - if (success && Restart) - { - object[] flags = new object[] { 6, 0 }; - RestartComputerCommand.RestartOneComputerUsingDcom(this, isLocalhost, computerName, flags, options); - } - - // If successful and the Restart parameter is not specified, write out warning - if (success && !Restart) - { - WriteWarning(StringUtil.Format(ComputerResources.RestartNeeded, null, computerName)); - } - } - } // end of try - catch (ManagementException ex) - { - WriteErrorHelper(ComputerResources.FailToConnectToComputer, "AddComputerException", computerName, - ErrorCategory.OperationStopped, false, computerName, ex.Message); - } - catch (COMException ex) - { - WriteErrorHelper(ComputerResources.FailToConnectToComputer, "AddComputerException", computerName, - ErrorCategory.OperationStopped, false, computerName, ex.Message); - } - catch (UnauthorizedAccessException ex) - { - WriteErrorHelper(ComputerResources.FailToConnectToComputer, "AddComputerException", computerName, - ErrorCategory.OperationStopped, false, computerName, ex.Message); - } - } - - private string ValidateComputerName(string computer, bool validateNewName) - { - ErrorRecord error = null; - string targetComputer = ComputerWMIHelper.ValidateComputerName(computer, _shortLocalMachineName, _fullLocalMachineName, ref error); - if (targetComputer == null) - { - if (error != null) - { - WriteError(error); - } - return null; - } - - bool isLocalhost = targetComputer.Equals(ComputerWMIHelper.localhostStr, StringComparison.OrdinalIgnoreCase); - - if (validateNewName && NewName != null) - { - if (!ComputerWMIHelper.IsComputerNameValid(NewName)) - { - WriteErrorHelper( - ComputerResources.InvalidNewName, - "InvalidNewName", - NewName, - ErrorCategory.InvalidArgument, - false, - isLocalhost ? _shortLocalMachineName : targetComputer, NewName); - - return null; - } - } - - return targetComputer; - } - -#endregion private - -#region override - - /// - /// BeginProcessing method - /// - protected override void BeginProcessing() - { - if (ParameterSetName == DomainParameterSet) - { - if ((Options & JoinOptions.PasswordPass) != 0 && (Options & JoinOptions.UnsecuredJoin) == 0) - { - WriteErrorHelper(ComputerResources.InvalidJoinOptions, "InvalidJoinOptions", Options, - ErrorCategory.InvalidArgument, true, JoinOptions.PasswordPass.ToString(), - JoinOptions.UnsecuredJoin.ToString()); - } - - if ((Options & JoinOptions.AccountCreate) != 0) - { - _joinDomainflags |= (int)JoinOptions.AccountCreate; - } - if ((Options & JoinOptions.Win9XUpgrade) != 0) - { - _joinDomainflags |= (int)JoinOptions.Win9XUpgrade; - } - if ((Options & JoinOptions.UnsecuredJoin) != 0) - { - _joinDomainflags |= (int)JoinOptions.UnsecuredJoin; - } - if ((Options & JoinOptions.PasswordPass) != 0) - { - _joinDomainflags |= (int)JoinOptions.PasswordPass; - } - if ((Options & JoinOptions.DeferSPNSet) != 0) - { - _joinDomainflags |= (int)JoinOptions.DeferSPNSet; - } - if ((Options & JoinOptions.JoinWithNewName) != 0) - { - _joinDomainflags |= (int)JoinOptions.JoinWithNewName; - } - if ((Options & JoinOptions.JoinReadOnly) != 0) - { - _joinDomainflags |= (int)JoinOptions.JoinReadOnly; - } - if ((Options & JoinOptions.InstallInvoke) != 0) - { - _joinDomainflags |= (int)JoinOptions.InstallInvoke; - } - - if (Unsecure) - { - _joinDomainflags |= (int)(JoinOptions.UnsecuredJoin | JoinOptions.PasswordPass); - } - - if (Server != null) - { - // It's the name of a domain controller. We need to check if the specified domain controller actually exists - try - { - Dns.GetHostEntry(Server); - } - catch (Exception) - { - WriteErrorHelper(ComputerResources.CannotResolveServerName, "AddressResolutionException", - Server, ErrorCategory.InvalidArgument, true, Server); - } - DomainName = DomainName + "\\" + Server; - } - } - } - - /// - /// ProcessRecord method - /// - protected override void ProcessRecord() - { - if (NewName != null && ComputerName.Length != 1) - { - WriteErrorHelper(ComputerResources.CannotRenameMultipleComputers, "CannotRenameMultipleComputers", - NewName, ErrorCategory.InvalidArgument, false); - return; - } - - // If LocalCred is not provided, we use the current caller's context - ConnectionOptions options = new ConnectionOptions - { - Authentication = AuthenticationLevel.PacketPrivacy, - Impersonation = ImpersonationLevel.Impersonate, - EnablePrivileges = true - }; - - EnumerationOptions enumOptions = new EnumerationOptions { UseAmendedQualifiers = true, DirectRead = true }; - ObjectQuery computerSystemQuery = new ObjectQuery("select * from " + ComputerWMIHelper.WMI_Class_ComputerSystem); - - int oldJoinDomainFlags = _joinDomainflags; - if (NewName != null && ParameterSetName == DomainParameterSet) - { - // We rename the computer after it's joined to the target domain, so writing SPN and DNSHostName attributes - // on the computer object should be deferred until the rename operation that follows the join operation - _joinDomainflags |= (int)JoinOptions.DeferSPNSet; - } - - try - { - foreach (string computer in ComputerName) - { - string targetComputer = ValidateComputerName(computer, NewName != null); - if (targetComputer == null) - { - continue; - } - - bool isLocalhost = targetComputer.Equals("localhost", StringComparison.OrdinalIgnoreCase); - if (isLocalhost) - { - if (!_containsLocalHost) - _containsLocalHost = true; - _newNameForLocalHost = NewName; - - continue; - } - - DoAddComputerAction(targetComputer, NewName, false, options, enumOptions, computerSystemQuery); - }// end of foreach - } - finally - { - // Reverting the domainflags to previous status if DeferSPNSet is added to the domain flags. - if (NewName != null && ParameterSetName == DomainParameterSet) - { - _joinDomainflags = oldJoinDomainFlags; - } - } - }// end of ProcessRecord - - /// - /// EndProcessing method - /// - protected override void EndProcessing() - { - if (!_containsLocalHost) return; - - // If LocalCred is not provided, we use the current caller's context - ConnectionOptions options = new ConnectionOptions - { - Authentication = AuthenticationLevel.PacketPrivacy, - Impersonation = ImpersonationLevel.Impersonate, - EnablePrivileges = true - }; - - EnumerationOptions enumOptions = new EnumerationOptions { UseAmendedQualifiers = true, DirectRead = true }; - ObjectQuery computerSystemQuery = new ObjectQuery("select * from " + ComputerWMIHelper.WMI_Class_ComputerSystem); - - DoAddComputerAction("localhost", _newNameForLocalHost, true, options, enumOptions, computerSystemQuery); - } - -#endregion override - }//End Class - -#endregion Add-Computer - -#region RemoveComputer - - /// - /// Removes the Specified Computer(s) from the relevant Domain or Work Group - /// - - [Cmdlet(VerbsCommon.Remove, "Computer", SupportsShouldProcess = true, DefaultParameterSetName = LocalParameterSet, - HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135246", RemotingCapability = RemotingCapability.SupportedByCommand)] - [OutputType(typeof(ComputerChangeInfo))] - public class RemoveComputerCommand : PSCmdlet - { -#region "Parameters and Private Data" - - private const string LocalParameterSet = "Local"; - private const string RemoteParameterSet = "Remote"; - - /// - /// The domain credential is used for authenticating to the domain controller. - /// - [Parameter(ParameterSetName = RemoteParameterSet, Mandatory = true)] - [Parameter(Position = 0, ParameterSetName = LocalParameterSet)] - [Alias("Credential")] - [ValidateNotNullOrEmpty] - [Credential] - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] - public PSCredential UnjoinDomainCredential { get; set; } - - /// - /// The local admin credential for authenticating to the target computer - /// - [Parameter(ParameterSetName = RemoteParameterSet)] - [ValidateNotNullOrEmpty] - [Credential] - public PSCredential LocalCredential { get; set; } - - /// - /// Restart parameter - /// - [Parameter] - public SwitchParameter Restart { get; set; } = false; - - /// - /// The target computer names to remove from the domain - /// - [Parameter(ParameterSetName = RemoteParameterSet, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - public string[] ComputerName { get; set; } = { "localhost" }; - - /// - /// Force parameter (to suppress the shouldprocess and shouldcontinue) - /// - [Parameter] - public SwitchParameter Force - { - get { return _force; } - set { _force = value; } - } - private bool _force; - - /// - /// Only emit if passthru is specified. One bool/string pair for each - /// computer that was joined. Bool = success/failure. String = ComputerName. - /// - [Parameter] - public SwitchParameter PassThru { get; set; } - - /// - /// Specify the workgroup name to join in if the target machine is removed from - /// the domain - /// - [Parameter] - [ValidateNotNullOrEmpty] - public string WorkgroupName { get; set; } = "WORKGROUP"; - - private bool _containsLocalHost = false; - private readonly string _shortLocalMachineName = Dns.GetHostName(); - private readonly string _fullLocalMachineName = Dns.GetHostEntry("").HostName; - -#endregion "Parameters and Private Data" - -#region "Private Methods" - - private void DoRemoveComputerAction(string computer, bool isLocalhost, ConnectionOptions options, EnumerationOptions enumOptions, ObjectQuery computerSystemQuery) - { - bool successful = false; - string computerName = isLocalhost ? _shortLocalMachineName : computer; - - if (!ShouldProcess(computerName)) - { - return; - } - - // If LocalCred is given, use the local credential for WMI connection - if (LocalCredential != null) - { - options.SecurePassword = LocalCredential.Password; - options.Username = ComputerWMIHelper.GetLocalAdminUserName(computerName, LocalCredential); - } - - // The local machine will always be processed in the very end. If the - // current target computer is the local machine, it's the last one to - // be processed, so we can safely set the Username and Password to be - // null. We cannot use a user credential when connecting to the local - // machine. - if (isLocalhost) - { - options.Username = null; - options.SecurePassword = null; - } - - ManagementScope scope = new ManagementScope(ComputerWMIHelper.GetScopeString(computer, ComputerWMIHelper.WMI_Path_CIM), options); - try - { - using (var searcher = new ManagementObjectSearcher(scope, computerSystemQuery, enumOptions)) - { - foreach (ManagementObject computerSystem in searcher.Get()) - { - using (computerSystem) - { - if (!(bool)computerSystem["PartOfDomain"]) - { - // Not in a domain, throw out non-terminating error - string errMsg = StringUtil.Format(ComputerResources.ComputerNotInDomain, computerName); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "ComputerNotInDomain", ErrorCategory.InvalidOperation, computerName); - WriteError(error); - continue; - } - - // Remind the user to have local admin credential only if the computer is domain joined - string shouldContinueMsg = ComputerResources.RemoveComputerConfirm; - if (!Force && !ShouldContinue(shouldContinueMsg, null /* null = default caption */ )) - { - continue; - } - - int returnCode = 0; - string curDomainName = (string)LanguagePrimitives.ConvertTo(computerSystem["Domain"], typeof(string), CultureInfo.InvariantCulture); - string dUserName = UnjoinDomainCredential != null ? UnjoinDomainCredential.UserName : null; - string dPassword = UnjoinDomainCredential != null ? Utils.GetStringFromSecureString(UnjoinDomainCredential.Password) : null; - - ManagementBaseObject unjoinParameter = computerSystem.GetMethodParameters("UnjoinDomainOrWorkgroup"); - unjoinParameter.SetPropertyValue("UserName", dUserName); - unjoinParameter.SetPropertyValue("Password", dPassword); - unjoinParameter.SetPropertyValue("FUnjoinOptions", 4); // default option, disable the active directory account - - ManagementBaseObject result = computerSystem.InvokeMethod("UnjoinDomainOrWorkgroup", unjoinParameter, null); - Dbg.Diagnostics.Assert(result != null, "result cannot be null if the Unjoin method is invoked"); - returnCode = Convert.ToInt32(result["ReturnValue"], CultureInfo.CurrentCulture); - - // Error code 1355 - The specified domain either does not exist or could not be contacted. - // This might happen when the old domain is gone or unreachable. - // Error code 53 - The network path was not found. - // This might happen when the network is not available. - if ((returnCode == 1355 || returnCode == 53) && Force) - { - // When -Force is specified, we unjoin the domain without disable the AD account - unjoinParameter.SetPropertyValue("FUnjoinOptions", 0); - result = computerSystem.InvokeMethod("UnjoinDomainOrWorkgroup", unjoinParameter, null); - Dbg.Diagnostics.Assert(result != null, "result cannot be null if the Unjoin method is invoked"); - returnCode = Convert.ToInt32(result["ReturnValue"], CultureInfo.CurrentCulture); - } - - if (returnCode != 0) - { - var ex = new Win32Exception(returnCode); - string errMsg = StringUtil.Format(ComputerResources.FailToUnjoinDomain, computerName, curDomainName, ex.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "FailToUnjoinDomain", ErrorCategory.OperationStopped, computerName); - WriteError(error); - } - else - { - // Join into the specified workgroup if it's given - successful = true; - if (WorkgroupName != null) - { - ManagementBaseObject joinParameter = computerSystem.GetMethodParameters("JoinDomainOrWorkgroup"); - joinParameter.SetPropertyValue("Name", WorkgroupName); - joinParameter.SetPropertyValue("Password", null); - joinParameter.SetPropertyValue("UserName", null); - joinParameter.SetPropertyValue("FJoinOptions", 0); // Join in a workgroup - - result = computerSystem.InvokeMethod("JoinDomainOrWorkgroup", joinParameter, null); - Dbg.Diagnostics.Assert(result != null, "result cannot be null if the Join method is invoked"); - returnCode = Convert.ToInt32(result["ReturnValue"], CultureInfo.CurrentCulture); - if (returnCode != 0) - { - var ex = new Win32Exception(returnCode); - string errMsg = StringUtil.Format(ComputerResources.FailToSwitchFromDomainToWorkgroup, computerName, curDomainName, WorkgroupName, ex.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "FailToJoinWorkGroup", ErrorCategory.OperationStopped, computerName); - WriteError(error); - } - } - } - - if (PassThru) - { - WriteObject(ComputerWMIHelper.GetComputerStatusObject(returnCode, computerName)); - } - } - } - } - - // If successful and the Restart parameter is specified, restart the computer - if (successful && Restart) - { - object[] flags = new object[] { 6, 0 }; - RestartComputerCommand.RestartOneComputerUsingDcom(this, isLocalhost, computerName, flags, options); - } - - // If successful and the Restart parameter is not specified, write out warning - if (successful && !Restart) - { - WriteWarning(StringUtil.Format(ComputerResources.RestartNeeded, null, computerName)); - } - } - catch (ManagementException ex) - { - string errMsg = StringUtil.Format(ComputerResources.FailToConnectToComputer, computerName, ex.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "RemoveComputerException", ErrorCategory.OperationStopped, computerName); - WriteError(error); - } - catch (COMException ex) - { - string errMsg = StringUtil.Format(ComputerResources.FailToConnectToComputer, computerName, ex.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "RemoveComputerException", ErrorCategory.OperationStopped, computerName); - WriteError(error); - } - catch (UnauthorizedAccessException ex) - { - string errMsg = StringUtil.Format(ComputerResources.FailToConnectToComputer, computerName, ex.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "RemoveComputerException", ErrorCategory.OperationStopped, computerName); - WriteError(error); - } - } - - private string ValidateComputerName(string computer) - { - ErrorRecord error = null; - string targetComputer = ComputerWMIHelper.ValidateComputerName(computer, _shortLocalMachineName, _fullLocalMachineName, ref error); - if (targetComputer == null) - { - if (error != null) - { - WriteError(error); - } - return null; - } - - return targetComputer; - } - -#endregion "Private Methods" - -#region "Override Methods" - - /// - /// ProcessRecord method. - /// - protected override void ProcessRecord() - { - // If both LocalCred and DomainCred are not provided, we use the default options - ConnectionOptions options = new ConnectionOptions - { - Authentication = AuthenticationLevel.PacketPrivacy, - Impersonation = ImpersonationLevel.Impersonate, - EnablePrivileges = true - }; - - // For Remove-Computer, usually the domain credential is also the local admin credential - // for the target computer. So use the local credential if given, otherwise use the domain - // credential to connect to the target machine. - // If the LocalCred is not given but the DomainCred is available, use the DomainCred for WMI connection. - if (LocalCredential == null && UnjoinDomainCredential != null) - { - options.SecurePassword = UnjoinDomainCredential.Password; - options.Username = UnjoinDomainCredential.UserName; - } - - EnumerationOptions enumOptions = new EnumerationOptions { UseAmendedQualifiers = true, DirectRead = true }; - ObjectQuery computerSystemQuery = new ObjectQuery("select * from " + ComputerWMIHelper.WMI_Class_ComputerSystem); - - foreach (string computer in ComputerName) - { - string targetComputer = ValidateComputerName(computer); - if (targetComputer == null) - { - continue; - } - - bool isLocalhost = targetComputer.Equals("localhost", StringComparison.OrdinalIgnoreCase); - if (isLocalhost) - { - if (!_containsLocalHost) - _containsLocalHost = true; - - continue; - } - - DoRemoveComputerAction(computer, false, options, enumOptions, computerSystemQuery); - } - }//End ProcessRecord() - - /// - /// EndProcessing method: deal with the local computer in the end - /// - protected override void EndProcessing() - { - if (!_containsLocalHost) return; - - // If both LocalCred and DomainCred are not provided, we use the default options - ConnectionOptions options = new ConnectionOptions - { - Authentication = AuthenticationLevel.PacketPrivacy, - Impersonation = ImpersonationLevel.Impersonate, - EnablePrivileges = true - }; - - // For Remove-Computer, usually the domain credential is also the local admin credential - // for the target computer. So use the local credential if given, otherwise use the domain - // credential to connect to the target machine. - // If the LocalCred is not given but the DomainCred is available, use the DomainCred for WMI connection. - if (LocalCredential == null && UnjoinDomainCredential != null) - { - options.SecurePassword = UnjoinDomainCredential.Password; - options.Username = UnjoinDomainCredential.UserName; - } - - EnumerationOptions enumOptions = new EnumerationOptions { UseAmendedQualifiers = true, DirectRead = true }; - ObjectQuery computerSystemQuery = new ObjectQuery("select * from " + ComputerWMIHelper.WMI_Class_ComputerSystem); - - DoRemoveComputerAction("localhost", true, options, enumOptions, computerSystemQuery); - } - -#endregion "Override Methods" - }//End Class - -#endregion Remove-Computer - -#endif - -#region Rename-Computer - - /// - /// Renames a domain computer and its corresponding domain account or a - /// workgroup computer. Use this command to rename domain workstations and local - /// machines only. It cannot be used to rename Domain Controllers. - /// - - [Cmdlet(VerbsCommon.Rename, "Computer", SupportsShouldProcess = true, - HelpUri = "https://go.microsoft.com/fwlink/?LinkID=219990", RemotingCapability = RemotingCapability.SupportedByCommand)] - public class RenameComputerCommand : PSCmdlet - { -#region Private Members - - private bool _containsLocalHost = false; - private string _newNameForLocalHost = null; - - private TransportProtocol _transportProtocol = TransportProtocol.DCOM; - - private readonly string _shortLocalMachineName = Dns.GetHostName(); - private readonly string _fullLocalMachineName = Dns.GetHostEntryAsync("").Result.HostName; - -#endregion - -#region Parameters - - /// - /// Target computers to rename - /// - [Parameter(ValueFromPipelineByPropertyName = true)] - [ValidateNotNullOrEmpty] - public string ComputerName { get; set; } = "localhost"; - - /// - /// Emit the output. - /// - //[Alias("Restart")] - [Parameter] - public SwitchParameter PassThru { get; set; } - - /// - /// The domain credential of the domain the target computer joined - /// - [Parameter] - [ValidateNotNullOrEmpty] - [Credential] - public PSCredential DomainCredential { get; set; } - - /// - /// The administrator credential of the target computer - /// - [Parameter] - [ValidateNotNullOrEmpty] - [Credential] - public PSCredential LocalCredential { get; set; } - - /// - /// New names for the target computers - /// - [Parameter(Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true)] - [ValidateNotNullOrEmpty] - public string NewName { get; set; } - - /// - /// Suppress the ShouldContinue - /// - [Parameter] - public SwitchParameter Force - { - get { return _force; } - set { _force = value; } - } - private bool _force; - - /// - /// To restart the target computer after rename it - /// - [Parameter] - public SwitchParameter Restart - { - get { return _restart; } - set { _restart = value; } - } - private bool _restart; - - /// - /// The authentication options for CIM_WSMan connection - /// - [Parameter] - [ValidateSet( - "Default", - "Basic", - "Negotiate", // can be used with and without credential (without -> PSRP mapped to NegotiateWithImplicitCredential) - "CredSSP", - "Digest", - "Kerberos")] // can be used with and without credential (not sure about implications) - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] - public string WsmanAuthentication { get; set; } = "Default"; - - /// - /// Specify the protocol to use - /// - [Parameter] - [ValidateSet(ComputerWMIHelper.DcomProtocol, ComputerWMIHelper.WsmanProtocol)] - public string Protocol { get; set; } = -#if CORECLR - //CoreClr does not support DCOM protocol - // This change makes sure that the the command works seamlessly if user did not explicitly entered the protocol - ComputerWMIHelper.WsmanProtocol; -#else - ComputerWMIHelper.DcomProtocol; -#endif - -#endregion - -#region "Private Methods" - - /// - /// Check to see if the target computer is the local machine - /// - private string ValidateComputerName() - { - // Validate target name. - ErrorRecord targetError = null; - string targetComputer = ComputerWMIHelper.ValidateComputerName(ComputerName, _shortLocalMachineName, _fullLocalMachineName, ref targetError); - if (targetComputer == null) - { - if (targetError != null) - { - WriteError(targetError); - } - return null; - } - - // Validate *new* name. Validate the format of the new name. Check if the old name is the same as the - // new name later. - if (!ComputerWMIHelper.IsComputerNameValid(NewName)) - { - bool isLocalhost = targetComputer.Equals(ComputerWMIHelper.localhostStr, StringComparison.OrdinalIgnoreCase); - string errMsg = StringUtil.Format(ComputerResources.InvalidNewName, isLocalhost ? _shortLocalMachineName : targetComputer, NewName); - ErrorRecord error = new ErrorRecord( - new InvalidOperationException(errMsg), "InvalidNewName", - ErrorCategory.InvalidArgument, NewName); - WriteError(error); - return null; - } - - return targetComputer; - } - - private void DoRenameComputerAction(string computer, string newName, bool isLocalhost) - { - string computerName = isLocalhost ? _shortLocalMachineName : computer; - - if (!ShouldProcess(computerName)) - { - return; - } - - // Check the length of the new name - if (newName != null && newName.Length > ComputerWMIHelper.NetBIOSNameMaxLength) - { - string truncatedName = newName.Substring(0, ComputerWMIHelper.NetBIOSNameMaxLength); - string query = StringUtil.Format(ComputerResources.TruncateNetBIOSName, truncatedName); - string caption = ComputerResources.TruncateNetBIOSNameCaption; - if (!Force && !ShouldContinue(query, caption)) - { - return; - } - } - - switch (_transportProtocol) - { - case TransportProtocol.WSMan: - DoRenameComputerWsman(computer, computerName, newName, isLocalhost); - break; -#if !CORECLR - case TransportProtocol.DCOM: - DoRenameComputerDcom(computer, computerName, newName, isLocalhost); - break; -#endif - } - } - - private void DoRenameComputerWsman(string computer, string computerName, string newName, bool isLocalhost) - { - bool successful = false; - PSCredential credToUse = isLocalhost ? null : (LocalCredential ?? DomainCredential); - - try - { - using (CancellationTokenSource cancelTokenSource = new CancellationTokenSource()) - using (CimSession cimSession = RemoteDiscoveryHelper.CreateCimSession(computer, credToUse, WsmanAuthentication, cancelTokenSource.Token, this)) - { - var operationOptions = new CimOperationOptions - { - Timeout = TimeSpan.FromMilliseconds(10000), - CancellationToken = cancelTokenSource.Token, - //This prefix works against all versions of the WinRM server stack, both win8 and win7 - ResourceUriPrefix = new Uri(ComputerWMIHelper.CimUriPrefix) - }; - - IEnumerable mCollection = cimSession.QueryInstances( - ComputerWMIHelper.CimOperatingSystemNamespace, - ComputerWMIHelper.CimQueryDialect, - "Select * from " + ComputerWMIHelper.WMI_Class_ComputerSystem, - operationOptions); - - foreach (CimInstance cimInstance in mCollection) - { - var oldName = cimInstance.CimInstanceProperties["DNSHostName"].Value.ToString(); - if (oldName.Equals(newName, StringComparison.OrdinalIgnoreCase)) - { - string errMsg = StringUtil.Format(ComputerResources.NewNameIsOldName, computerName, newName); - ErrorRecord error = new ErrorRecord( - new InvalidOperationException(errMsg), "NewNameIsOldName", - ErrorCategory.InvalidArgument, newName); - WriteError(error); - - continue; - } - - // If the target computer is in a domain, always use the DomainCred. If the DomainCred is not given, - // use null for UserName and Password, so the context of the caller will be used. - // If the target computer is not in a domain, just use null for the UserName and Password - string dUserName = null; - string dPassword = null; - if (((bool)cimInstance.CimInstanceProperties["PartOfDomain"].Value) && (DomainCredential != null)) - { - dUserName = DomainCredential.UserName; - dPassword = Utils.GetStringFromSecureString(DomainCredential.Password); - } - - var methodParameters = new CimMethodParametersCollection(); - methodParameters.Add(CimMethodParameter.Create( - "Name", - newName, - Microsoft.Management.Infrastructure.CimType.String, - CimFlags.None)); - - methodParameters.Add(CimMethodParameter.Create( - "UserName", - dUserName, - Microsoft.Management.Infrastructure.CimType.String, - (dUserName == null) ? CimFlags.NullValue : CimFlags.None)); - - methodParameters.Add( - CimMethodParameter.Create( - "Password", - dPassword, - Microsoft.Management.Infrastructure.CimType.String, - (dPassword == null) ? CimFlags.NullValue : CimFlags.None)); - - CimMethodResult result = cimSession.InvokeMethod( - ComputerWMIHelper.CimOperatingSystemNamespace, - cimInstance, - "Rename", - methodParameters, - operationOptions); - - int retVal = Convert.ToInt32(result.ReturnValue.Value, CultureInfo.CurrentCulture); - if (retVal != 0) - { - var ex = new Win32Exception(retVal); - string errMsg = StringUtil.Format(ComputerResources.FailToRename, computerName, newName, ex.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "FailToRenameComputer", ErrorCategory.OperationStopped, computerName); - WriteError(error); - } - else - { - successful = true; - } - - if (PassThru) - { - WriteObject(ComputerWMIHelper.GetRenameComputerStatusObject(retVal, newName, computerName)); - } - - if (successful) - { - if (_restart) - { - // If successful and the Restart parameter is specified, restart the computer - object[] flags = new object[] { 6, 0 }; - ComputerWMIHelper.InvokeWin32ShutdownUsingWsman( - this, - isLocalhost, - computerName, - flags, - credToUse, - WsmanAuthentication, - ComputerResources.RestartcomputerFailed, - "RestartcomputerFailed", - cancelTokenSource.Token); - } - else - { - WriteWarning(StringUtil.Format(ComputerResources.RestartNeeded, null, computerName)); - } - } - } // end foreach - } // end using - } - catch (CimException ex) - { - string errMsg = StringUtil.Format(ComputerResources.FailToConnectToComputer, computerName, ex.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "RenameComputerException", - ErrorCategory.OperationStopped, computerName); - WriteError(error); - } - catch (Exception ex) - { - string errMsg = StringUtil.Format(ComputerResources.FailToConnectToComputer, computerName, ex.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "RenameComputerException", - ErrorCategory.OperationStopped, computerName); - WriteError(error); - } - } - -#if !CORECLR - private void DoRenameComputerDcom(string computer, string computerName, string newName, bool isLocalhost) - { - EnumerationOptions enumOptions = new EnumerationOptions { UseAmendedQualifiers = true, DirectRead = true }; - ObjectQuery computerSystemQuery = new ObjectQuery("select * from " + ComputerWMIHelper.WMI_Class_ComputerSystem); - - // If both LocalCred and DomainCred are not provided, we use the default options - ConnectionOptions options = new ConnectionOptions - { - Authentication = AuthenticationLevel.PacketPrivacy, - Impersonation = ImpersonationLevel.Impersonate, - EnablePrivileges = true - }; - - if (isLocalhost) - { - options.Username = null; - options.SecurePassword = null; - } - // If the LocalCred is not given but the DomainCred is available, use the DomainCred for WMI connection. - // If LocalCred is given, use the local credential for WMI connection - else if (LocalCredential != null) - { - options.SecurePassword = LocalCredential.Password; - options.Username = ComputerWMIHelper.GetLocalAdminUserName(computerName, LocalCredential); - } - else if (DomainCredential != null) - { - options.SecurePassword = DomainCredential.Password; - options.Username = DomainCredential.UserName; - } - - bool successful = false; - ManagementScope scope = new ManagementScope(ComputerWMIHelper.GetScopeString(computer, ComputerWMIHelper.WMI_Path_CIM), options); - try - { - using (var searcher = new ManagementObjectSearcher(scope, computerSystemQuery, enumOptions)) - { - foreach (ManagementObject computerSystem in searcher.Get()) - { - using (computerSystem) - { - string oldName = (string)computerSystem["DNSHostName"]; - if (oldName.Equals(newName, StringComparison.OrdinalIgnoreCase)) - { - string errMsg = StringUtil.Format(ComputerResources.NewNameIsOldName, computerName, newName); - ErrorRecord error = new ErrorRecord( - new InvalidOperationException(errMsg), "NewNameIsOldName", - ErrorCategory.InvalidArgument, newName); - WriteError(error); - continue; - } - - string dUserName = null; - string dPassword = null; - if ((bool)computerSystem["PartOfDomain"]) - { - // If the target computer is in a domain, always use the DomainCred. If the DomainCred is not given, - // use null for UserName and Password, so the context of the caller will be used. - dUserName = DomainCredential != null ? DomainCredential.UserName : null; - dPassword = DomainCredential != null ? Utils.GetStringFromSecureString(DomainCredential.Password) : null; - } - // If the target computer is not in a domain, just use null for the UserName and Password - - ManagementBaseObject renameParameter = computerSystem.GetMethodParameters("Rename"); - renameParameter.SetPropertyValue("Name", newName); - renameParameter.SetPropertyValue("UserName", dUserName); - renameParameter.SetPropertyValue("Password", dPassword); - - ManagementBaseObject result = computerSystem.InvokeMethod("Rename", renameParameter, null); - Dbg.Diagnostics.Assert(result != null, "result cannot be null if the Rename method is invoked"); - int retVal = Convert.ToInt32(result["ReturnValue"], CultureInfo.CurrentCulture); - if (retVal != 0) - { - var ex = new Win32Exception(retVal); - string errMsg = StringUtil.Format(ComputerResources.FailToRename, computerName, newName, ex.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "FailToRenameComputer", ErrorCategory.OperationStopped, computerName); - WriteError(error); - } - else - { - successful = true; - } - - if (PassThru) - { - WriteObject(ComputerWMIHelper.GetRenameComputerStatusObject(retVal, newName, computerName)); - } - } - } - } - - // If successful and the Restart parameter is specified, restart the computer - if (successful && _restart) - { - object[] flags = new object[] { 6, 0 }; - RestartComputerCommand.RestartOneComputerUsingDcom(this, isLocalhost, computerName, flags, options); - } - - // If successful and the Restart parameter is not specified, write out warning - if (successful && !_restart) - { - WriteWarning(StringUtil.Format(ComputerResources.RestartNeeded, null, computerName)); - } - } - catch (ManagementException ex) - { - string errMsg = StringUtil.Format(ComputerResources.FailToConnectToComputer, computerName, ex.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "RenameComputerException", - ErrorCategory.OperationStopped, computerName); - WriteError(error); - } - catch (COMException ex) - { - string errMsg = StringUtil.Format(ComputerResources.FailToConnectToComputer, computerName, ex.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "RenameComputerException", - ErrorCategory.OperationStopped, computerName); - WriteError(error); - } - catch (UnauthorizedAccessException ex) - { - string errMsg = StringUtil.Format(ComputerResources.FailToConnectToComputer, computerName, ex.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "RenameComputerException", - ErrorCategory.OperationStopped, computerName); - WriteError(error); - } - } -#endif - -#endregion "Private Methods" - -#region "Override Methods" - - /// - /// Begin Processing - /// - protected override void BeginProcessing() - { - base.BeginProcessing(); - - bool haveWsmanAuthenticationParam = this.MyInvocation.BoundParameters.ContainsKey("WsmanAuthentication"); - bool haveProtocolParam = this.MyInvocation.BoundParameters.ContainsKey("Protocol"); - _transportProtocol = (this.Protocol.Equals(ComputerWMIHelper.WsmanProtocol, StringComparison.OrdinalIgnoreCase) || (haveWsmanAuthenticationParam && !haveProtocolParam)) ? - TransportProtocol.WSMan : TransportProtocol.DCOM; - - // Verify parameter set - if ((_transportProtocol == TransportProtocol.DCOM) && haveWsmanAuthenticationParam) - { - ThrowTerminatingError( - new ErrorRecord( - new PSArgumentException(ComputerResources.RenameCommandWsmanAuthParamConflict), - "InvalidParameter", - ErrorCategory.InvalidArgument, - this)); - } - -#if CORECLR - // DCOM Authentication is not supported for CoreCLR. Throw an error - // and request that the user specify WSMan Authentication. - if (_transportProtocol == TransportProtocol.DCOM) - { - PSArgumentException ex = new PSArgumentException(ComputerResources.InvalidParameterDCOMNotSupported); - ThrowTerminatingError(new ErrorRecord(ex, "InvalidParameterDCOMNotSupported", ErrorCategory.InvalidArgument, null)); - } -#endif - } - - /// - /// ProcessRecord method. - /// - protected override void ProcessRecord() - { - string targetComputer = ValidateComputerName(); - if (targetComputer == null) return; - - bool isLocalhost = targetComputer.Equals("localhost", StringComparison.OrdinalIgnoreCase); - if (isLocalhost) - { - if (!_containsLocalHost) - _containsLocalHost = true; - _newNameForLocalHost = NewName; - - return; - } - - DoRenameComputerAction(targetComputer, NewName, false); - } - - /// - /// EndProcessing method - /// - protected override void EndProcessing() - { - if (!_containsLocalHost) return; - - DoRenameComputerAction("localhost", _newNameForLocalHost, true); - } - -#endregion "Override Methods" - } - -#endregion Rename-Computer - -#if !CORECLR - -#region Test-ComputerSecureChannel - - - /// - /// This cmdlet queries the status of trust relationships and will remove and - /// rebuild the trust if specified. - /// - - [Cmdlet(VerbsDiagnostic.Test, "ComputerSecureChannel", SupportsShouldProcess = true, HelpUri = "https://go.microsoft.com/fwlink/?LinkID=137749")] - [OutputType(typeof(Boolean))] - public class TestComputerSecureChannelCommand : PSCmdlet - { -#region Parameters - - /// - /// Repair the secure channel between the local machine with the domain, if it's broken - /// - [Parameter] - public SwitchParameter Repair { get; set; } - - /// - /// The trusted domain controller to operate "Repair" on. - /// - [Parameter, ValidateNotNullOrEmpty] - public string Server { get; set; } - - /// - /// The domain credential for authenticating to the domain the local machine joined - /// - [Parameter, ValidateNotNullOrEmpty, Credential] - public PSCredential Credential { get; set; } - - private const uint NETLOGON_CONTROL_REDISCOVER = 5; - private const uint NETLOGON_CONTROL_TC_QUERY = 6; - private const uint NETLOGON_INFO_2 = 2; - -#endregion Parameters - -#region "Private Methods" - - [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", Justification = "Return results are used in debug asserts.")] - private bool VerifySecureChannel(string domain, string localMachineName) - { - IntPtr queryInfo = IntPtr.Zero; - IntPtr domainPtr = Marshal.StringToCoTaskMemAuto(domain); - bool scInGoodState = false; - - try - { - int errorCode = SAMAPI.I_NetLogonControl2(null, NETLOGON_CONTROL_TC_QUERY, NETLOGON_INFO_2, ref domainPtr, out queryInfo); - - if (errorCode != 0) - { - var ex = new Win32Exception(errorCode); - string errMsg = StringUtil.Format(ComputerResources.FailToTestSecureChannel, ex.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "FailToTestSecureChannel", - ErrorCategory.OperationStopped, localMachineName); - ThrowTerminatingError(error); - } - - var infoData = (SAMAPI.NetLogonInfo2)Marshal.PtrToStructure(queryInfo, typeof(SAMAPI.NetLogonInfo2)); - scInGoodState = infoData.PdcConnectionStatus == 0; - } - finally - { - if (domainPtr != IntPtr.Zero) - { - Marshal.FreeCoTaskMem(domainPtr); - } - if (queryInfo != IntPtr.Zero) - { - int freeResult = SAMAPI.NetApiBufferFree(queryInfo); - Dbg.Diagnostics.Assert(freeResult == 0, "NetApiBufferFree returned non-zero value"); - } - } - - return scInGoodState; - } - - [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", Justification = "Return results are used in debug asserts.")] - private bool ResetSecureChannel(string domain) - { - IntPtr queryInfo = IntPtr.Zero; - IntPtr domainPtr = Marshal.StringToCoTaskMemAuto(domain); - bool scInGoodState = false; - - try - { - int errorCode = SAMAPI.I_NetLogonControl2(null, NETLOGON_CONTROL_REDISCOVER, NETLOGON_INFO_2, ref domainPtr, out queryInfo); - if (errorCode == 0) - { - var infoData = (SAMAPI.NetLogonInfo2)Marshal.PtrToStructure(queryInfo, typeof(SAMAPI.NetLogonInfo2)); - scInGoodState = infoData.TrustedDcName != null; - } - } - finally - { - if (domainPtr != IntPtr.Zero) - { - Marshal.FreeCoTaskMem(domainPtr); - } - if (queryInfo != IntPtr.Zero) - { - int freeResult = SAMAPI.NetApiBufferFree(queryInfo); - Dbg.Diagnostics.Assert(freeResult == 0, "NetApiBufferFree returned non-zero value"); - } - } - - return scInGoodState; - } - -#endregion "Private Methods" - -#region "Override Methods" - - /// - /// BeginProcessing method - /// - protected override void BeginProcessing() - { - if (Server != null) - { - if (Server.Length == 1 && Server[0] == '.') - { - Server = "localhost"; - } - - try - { - string resolveFullName = Dns.GetHostEntry(Server).HostName; - } - catch (Exception exception) - { - string errMsg = StringUtil.Format(ComputerResources.CannotResolveComputerName, Server, exception.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "AddressResolutionException", ErrorCategory.InvalidArgument, Server); - ThrowTerminatingError(error); - } - } - } - - - /// - /// ProcessRecord method. - /// Suppress the message about NetApiBufferFree. The retuned results are - /// actually used, but only in checked builds - /// - [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults")] - protected override void ProcessRecord() - { - string localMachineName = Dns.GetHostName(); - string domain = null; - Exception exception = null; - - if (!ShouldProcess(localMachineName)) - { - return; - } - - try - { - ManagementObject computerSystemInstance = new ManagementObject("Win32_ComputerSystem.Name=\"" + localMachineName + "\""); - if (!(bool)computerSystemInstance["PartOfDomain"]) - { - string errMsg = ComputerResources.TestComputerNotInDomain; - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "ComputerNotInDomain", - ErrorCategory.InvalidOperation, localMachineName); - ThrowTerminatingError(error); - } - domain = (string)LanguagePrimitives.ConvertTo(computerSystemInstance["Domain"], typeof(string), CultureInfo.InvariantCulture); - } - catch (ManagementException ex) - { - exception = ex; - } - catch (COMException ex) - { - exception = ex; - } - catch (UnauthorizedAccessException ex) - { - exception = ex; - } - if (exception != null) - { - string errMsg = StringUtil.Format(ComputerResources.FailToGetDomainInformation, exception.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "FailToGetDomainInformation", - ErrorCategory.OperationStopped, localMachineName); - ThrowTerminatingError(error); - } - - Dbg.Diagnostics.Assert(domain != null, "domain should not be null at this point"); - bool scInGoodState = false; - string verboseMsg = null; - if (Repair) - { - ResetComputerMachinePasswordCommand. - ResetMachineAccountPassword(domain, localMachineName, Server, Credential, this); - - scInGoodState = ResetSecureChannel(domain); - verboseMsg = scInGoodState - ? StringUtil.Format(ComputerResources.RepairSecureChannelSucceed, domain) - : StringUtil.Format(ComputerResources.RepairSecureChannelFail, domain); - } - else - { - scInGoodState = VerifySecureChannel(domain, localMachineName); - verboseMsg = scInGoodState - ? StringUtil.Format(ComputerResources.SecureChannelAlive, domain) - : StringUtil.Format(ComputerResources.SecureChannelBroken, domain); - } - - WriteObject(scInGoodState); - WriteVerbose(verboseMsg); - } - -#endregion "Override Methods" - }//End Class - - -#endregion - -#region Reset-ComputerMachinePassword - /// - /// Resets the computer machine password used to authenticate with DCs. - /// - - [Cmdlet(VerbsCommon.Reset, "ComputerMachinePassword", - SupportsShouldProcess = true, HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135252")] - public class ResetComputerMachinePasswordCommand : PSCmdlet - { -#region "Parameter and PrivateData" + public string WsmanAuthentication { get; set; } = "Default"; /// - /// The following is the definition of the input parameter "Server". - /// Specifies the name of the domain controller to use for setting the machine - /// account password. + /// The following is the definition of the input parameter "ComputerName". + /// Value of the address requested. The form of the value can be either the + /// computer name ("wxyz1234"), IPv4 address ("192.168.177.124"), or IPv6 + /// address ("2010:836B:4179::836B:4179"). /// - [Parameter] + [Parameter(Position = 0, ValueFromPipelineByPropertyName = true)] [ValidateNotNullOrEmpty] - public string Server { get; set; } + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] + [Alias("CN", "__SERVER", "Server", "IPAddress")] + public String[] ComputerName { get; set; } = new string[] { "." }; /// - /// The domain credential for authenticating to the domain the local machine joined + /// The following is the definition of the input parameter "Credential". + /// Specifies a user account that has permission to perform this action. Type a + /// user-name, such as "User01" or "Domain01\User01", or enter a PSCredential + /// object, such as one from the Get-Credential cmdlet /// - [Parameter] + [Parameter(Position = 1)] [ValidateNotNullOrEmpty] [Credential] public PSCredential Credential { get; set; } - private const uint STATUS_ACCESS_DENIED = 0xc0000022; - private const uint STATUS_OBJECT_NAME_NOT_FOUND = 0xc0000034; - - private const uint SECRET_SET_VALUE = 0x00000001; - private const uint SECRET_QUERY_VALUE = 0x00000002; - - // This number comes from the GenerateRandomPassword implementation of NetDom.exe. - // There is a reason behind this number. - private const int PasswordLength = 120; - private const string SecretKey = "$MACHINE.ACC"; + /// + /// Force the operation to take place if possible + /// + [Parameter] + public SwitchParameter Force { get; set; } = false; -#endregion "Parameter and PrivateData" + #endregion "parameters" -#region "Private Methods" +#region "IDisposable Members" /// - /// Throw out terminating error for LSA function invocations + /// Dispose Method /// - /// - /// - private static void ThrowOutLsaError(uint ret, PSCmdlet cmdlet) + public void Dispose() { - var ex = new Win32Exception(SAMAPI.LsaNtStatusToWinError((int)ret)); - string errMsg = StringUtil.Format(ComputerResources.FailToResetPasswordOnLocalMachine, ex.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "FailToResetPasswordOnLocalMachine", - ErrorCategory.OperationStopped, Dns.GetHostName()); - cmdlet.ThrowTerminatingError(error); + try + { + _cancel.Dispose(); + } + catch (ObjectDisposedException) { } } -#endregion "Private Methods" +#endregion "IDisposable Members" -#region "Internal Methods" +#region "Overrides" /// - /// Reset machine account password + /// ProcessRecord /// - /// - /// - /// - /// - /// - [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", Justification = "Return results are used in debug asserts.")] - internal static void ResetMachineAccountPassword(string domain, string localMachineName, string server, PSCredential credential, PSCmdlet cmdlet) + [SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling")] + protected override void ProcessRecord() { - // Get domain directory entry and reset the password on the machine account of the local machine - string newPassword = null; - string domainOrServerName = server ?? domain; + object[] flags = new object[] { 1, 0 }; + if (Force.IsPresent) + flags[0] = forcedShutdown; - try - { - string dUserName = credential != null ? credential.UserName : null; - string dPassword = credential != null ? Utils.GetStringFromSecureString(credential.Password) : null; - - using (var domainEntry = new DirectoryEntry( - "LDAP://" + domainOrServerName, - dUserName, - dPassword, - AuthenticationTypes.Secure)) - { - using (var searcher = new DirectorySearcher(domainEntry)) - { - searcher.Filter = "(&(objectClass=computer)(|(cn=" + localMachineName + ")(dn=" + localMachineName + ")))"; - SearchResult result = searcher.FindOne(); + ProcessWSManProtocol(flags); + }//End Processrecord - if (result == null) - { - string format = server != null - ? ComputerResources.CannotFindMachineAccountFromServer - : ComputerResources.CannotFindMachineAccountFromDomain; - string errMsg = StringUtil.Format(format, domainOrServerName); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "CannotFindMachineAccount", - ErrorCategory.OperationStopped, localMachineName); - cmdlet.ThrowTerminatingError(error); - } - else - { - // Generate a random password of length 120, and reset the password on the machine account - using (var targetEntry = result.GetDirectoryEntry()) - { - newPassword = ComputerWMIHelper.GetRandomPassword(PasswordLength); - targetEntry.Invoke("SetPassword", new object[] { newPassword }); - targetEntry.Properties["LockOutTime"].Value = 0; - } - } - } - } - } - catch (DirectoryServicesCOMException ex) - { - string errMsg = StringUtil.Format(ComputerResources.FailToResetPasswordOnDomain, ex.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "FailToResetPasswordOnDomain", - ErrorCategory.OperationStopped, localMachineName); - cmdlet.ThrowTerminatingError(error); - } - catch (TargetInvocationException ex) - { - string errMsg = StringUtil.Format(ComputerResources.FailToResetPasswordOnDomain, ex.InnerException.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "FailToResetPasswordOnDomain", - ErrorCategory.OperationStopped, localMachineName); - cmdlet.ThrowTerminatingError(error); - } - catch (COMException ex) + /// + /// to implement ^C + /// + protected override void StopProcessing() + { + try { - string errMsg = StringUtil.Format(ComputerResources.FailToResetPasswordOnDomain, ex.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "FailToResetPasswordOnDomain", - ErrorCategory.OperationStopped, localMachineName); - cmdlet.ThrowTerminatingError(error); + _cancel.Cancel(); } + catch (ObjectDisposedException) { } + catch (AggregateException) { } + } - // Set the same password to the local machine - Dbg.Diagnostics.Assert(newPassword != null, "the newPassword should not be null at this point"); - - // A direct translation of function NetpManageMachineSecret2 in //depot/winmain/ds/netapi/netjoin/joinutl.c - // Initialize the LSA_OBJECT_ATTRIBUTES - var lsaAttr = new SAMAPI.LSA_OBJECT_ATTRIBUTES(); - lsaAttr.RootDirectory = IntPtr.Zero; - lsaAttr.ObjectName = IntPtr.Zero; - lsaAttr.Attributes = 0; - lsaAttr.SecurityDescriptor = IntPtr.Zero; - lsaAttr.SecurityQualityOfService = IntPtr.Zero; - lsaAttr.Length = Marshal.SizeOf(typeof(SAMAPI.LSA_OBJECT_ATTRIBUTES)); - - // Initialize the policy handle and secret handle - IntPtr policyHandle = IntPtr.Zero; - IntPtr secretHandle = IntPtr.Zero; - - // Initialize variables for LsaQuerySecret call - IntPtr currentPassword = IntPtr.Zero; - - // Declare the key, newData and currentData - var key = new SAMAPI.LSA_UNICODE_STRING { Buffer = IntPtr.Zero }; - var newData = new SAMAPI.LSA_UNICODE_STRING { Buffer = IntPtr.Zero }; +#endregion "Overrides" - // Initialize the systemName for the localhost - var localhost = new SAMAPI.LSA_UNICODE_STRING(); - localhost.Buffer = IntPtr.Zero; - localhost.Length = 0; - localhost.MaximumLength = 0; +#region Private Methods - try + private void ProcessWSManProtocol(object[] flags) + { + foreach (string computer in ComputerName) { - // Open the LSA policy - uint ret = SAMAPI.LsaOpenPolicy(ref localhost, ref lsaAttr, (int)SAMAPI.LSA_ACCESS.AllAccess, out policyHandle); - if (ret == STATUS_ACCESS_DENIED) - { - string errMsg = ComputerResources.NeedAdminPrivilegeToResetPassword; - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "UnauthorizedAccessException", - ErrorCategory.InvalidOperation, localMachineName); - cmdlet.ThrowTerminatingError(error); - } - if (ret != 0) - { - ThrowOutLsaError(ret, cmdlet); - } + string compname = string.Empty; + string strLocal = string.Empty; + bool isLocalHost = false; - // Initialize secret key, new secret - SAMAPI.InitLsaString(SecretKey, ref key); - SAMAPI.InitLsaString(newPassword, ref newData); - bool secretCreated = false; + if (_cancel.Token.IsCancellationRequested) { break; } - // Open the secret. If the secret is not found, create the secret - ret = SAMAPI.LsaOpenSecret(policyHandle, ref key, SECRET_SET_VALUE | SECRET_QUERY_VALUE, out secretHandle); - if (ret == STATUS_OBJECT_NAME_NOT_FOUND) + if ((computer.Equals("localhost", StringComparison.CurrentCultureIgnoreCase)) || (computer.Equals(".", StringComparison.OrdinalIgnoreCase))) { - ret = SAMAPI.LsaCreateSecret(policyHandle, ref key, SECRET_SET_VALUE, out secretHandle); - secretCreated = true; + compname = Dns.GetHostName(); + strLocal = "localhost"; + isLocalHost = true; } - if (ret != 0) + else { - ThrowOutLsaError(ret, cmdlet); + compname = computer; } - SAMAPI.LSA_UNICODE_STRING currentData; - // Get the current password - if (secretCreated) + if (!ShouldProcess(StringUtil.Format(ComputerResources.DoubleComputerName, strLocal, compname))) { - // Use the new password as the current one - currentData = newData; + continue; } else { - // Query for the current password - ret = SAMAPI.LsaQuerySecret(secretHandle, out currentPassword, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); - if (ret != 0) - { - ThrowOutLsaError(ret, cmdlet); - } - - currentData = (SAMAPI.LSA_UNICODE_STRING)Marshal.PtrToStructure(currentPassword, typeof(SAMAPI.LSA_UNICODE_STRING)); - } - - ret = SAMAPI.LsaSetSecret(secretHandle, ref newData, ref currentData); - if (ret != 0) - { - ThrowOutLsaError(ret, cmdlet); + ComputerWMIHelper.InvokeWin32ShutdownUsingWsman( + this, + isLocalHost, + compname, + flags, + Credential, + WsmanAuthentication, + ComputerResources.StopcomputerFailed, + "StopComputerException", + _cancel.Token); } } - finally - { - // Release pointers - if (currentPassword != IntPtr.Zero) - { - int releaseResult = SAMAPI.LsaFreeMemory(currentPassword); - Dbg.Diagnostics.Assert(releaseResult == 0, "LsaFreeMemory returned non-zero value"); - } + } - // Release handles - if (policyHandle != IntPtr.Zero) - { - int releaseResult = SAMAPI.LsaClose(policyHandle); - Dbg.Diagnostics.Assert(releaseResult == 0, "LsaClose returned non-zero value"); - } +#endregion + } - if (secretHandle != IntPtr.Zero) - { - int releaseResult = SAMAPI.LsaClose(secretHandle); - Dbg.Diagnostics.Assert(releaseResult == 0, "LsaClose returned non-zero value"); - } +#endregion - // Release LSA_UNICODE_STRING - SAMAPI.FreeLsaString(ref key); - SAMAPI.FreeLsaString(ref newData); - } +#region Rename-Computer + + /// + /// Renames a domain computer and its corresponding domain account or a + /// workgroup computer. Use this command to rename domain workstations and local + /// machines only. It cannot be used to rename Domain Controllers. + /// + + [Cmdlet(VerbsCommon.Rename, "Computer", SupportsShouldProcess = true, + HelpUri = "https://go.microsoft.com/fwlink/?LinkID=219990", RemotingCapability = RemotingCapability.SupportedByCommand)] + public class RenameComputerCommand : PSCmdlet + { +#region Private Members + + private bool _containsLocalHost = false; + private string _newNameForLocalHost = null; + + private readonly string _shortLocalMachineName = Dns.GetHostName(); + private readonly string _fullLocalMachineName = Dns.GetHostEntryAsync("").Result.HostName; + +#endregion + +#region Parameters + + /// + /// Target computers to rename + /// + [Parameter(ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + public string ComputerName { get; set; } = "localhost"; + + /// + /// Emit the output. + /// + //[Alias("Restart")] + [Parameter] + public SwitchParameter PassThru { get; set; } + + /// + /// The domain credential of the domain the target computer joined + /// + [Parameter] + [ValidateNotNullOrEmpty] + [Credential] + public PSCredential DomainCredential { get; set; } + + /// + /// The administrator credential of the target computer + /// + [Parameter] + [ValidateNotNullOrEmpty] + [Credential] + public PSCredential LocalCredential { get; set; } + + /// + /// New names for the target computers + /// + [Parameter(Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + public string NewName { get; set; } + + /// + /// Suppress the ShouldContinue + /// + [Parameter] + public SwitchParameter Force + { + get { return _force; } + set { _force = value; } } + private bool _force; -#endregion "Internal Methods" + /// + /// To restart the target computer after rename it + /// + [Parameter] + public SwitchParameter Restart + { + get { return _restart; } + set { _restart = value; } + } + private bool _restart; -#region "Override Methods" + /// + /// The authentication options for CIM_WSMan connection + /// + [Parameter] + [ValidateSet( + "Default", + "Basic", + "Negotiate", // can be used with and without credential (without -> PSRP mapped to NegotiateWithImplicitCredential) + "CredSSP", + "Digest", + "Kerberos")] // can be used with implicit or explicit credential + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] + public string WsmanAuthentication { get; set; } = "Default"; + +#endregion + +#region "Private Methods" /// - /// BeginProcessing method. + /// Check to see if the target computer is the local machine /// - protected override void BeginProcessing() + private string ValidateComputerName() { - if (Server != null) + // Validate target name. + ErrorRecord targetError = null; + string targetComputer = ComputerWMIHelper.ValidateComputerName(ComputerName, _shortLocalMachineName, _fullLocalMachineName, ref targetError); + if (targetComputer == null) { - if (Server.Length == 1 && Server[0] == '.') + if (targetError != null) { - Server = "localhost"; + WriteError(targetError); } + return null; + } - try - { - string resolveFullName = Dns.GetHostEntry(Server).HostName; - } - catch (Exception exception) - { - string errMsg = StringUtil.Format(ComputerResources.CannotResolveComputerName, Server, exception.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "AddressResolutionException", ErrorCategory.InvalidArgument, Server); - ThrowTerminatingError(error); - } + // Validate *new* name. Validate the format of the new name. Check if the old name is the same as the + // new name later. + if (!ComputerWMIHelper.IsComputerNameValid(NewName)) + { + bool isLocalhost = targetComputer.Equals(ComputerWMIHelper.localhostStr, StringComparison.OrdinalIgnoreCase); + string errMsg = StringUtil.Format(ComputerResources.InvalidNewName, isLocalhost ? _shortLocalMachineName : targetComputer, NewName); + ErrorRecord error = new ErrorRecord( + new InvalidOperationException(errMsg), "InvalidNewName", + ErrorCategory.InvalidArgument, NewName); + WriteError(error); + return null; } - }//End BeginProcessing() - /// - /// ProcessRecord method - /// Suppress the message about LsaFreeMemory and LsaClose. The retuned results are - /// actually used, but only in checked builds - /// - [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults")] - protected override void ProcessRecord() + return targetComputer; + } + + private void DoRenameComputerAction(string computer, string newName, bool isLocalhost) { - // Not to use Environment.MachineName to avoid the injection attack - string localMachineName = Dns.GetHostName(); - string domainName = null; - Exception exception = null; + string computerName = isLocalhost ? _shortLocalMachineName : computer; - if (!ShouldProcess(localMachineName)) + if (!ShouldProcess(computerName)) { return; } - try + // Check the length of the new name + if (newName != null && newName.Length > ComputerWMIHelper.NetBIOSNameMaxLength) { - ManagementObject computerSystemInstance = new ManagementObject("Win32_ComputerSystem.Name=\"" + localMachineName + "\""); - if (!(bool)computerSystemInstance["PartOfDomain"]) + string truncatedName = newName.Substring(0, ComputerWMIHelper.NetBIOSNameMaxLength); + string query = StringUtil.Format(ComputerResources.TruncateNetBIOSName, truncatedName); + string caption = ComputerResources.TruncateNetBIOSNameCaption; + if (!Force && !ShouldContinue(query, caption)) { - string errMsg = ComputerResources.ResetComputerNotInDomain; - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "ComputerNotInDomain", - ErrorCategory.InvalidOperation, localMachineName); - ThrowTerminatingError(error); + return; } - domainName = (string)LanguagePrimitives.ConvertTo(computerSystemInstance["Domain"], typeof(string), CultureInfo.InvariantCulture); - } - catch (ManagementException ex) - { - exception = ex; - } - catch (COMException ex) - { - exception = ex; - } - catch (UnauthorizedAccessException ex) - { - exception = ex; - } - if (exception != null) - { - string errMsg = StringUtil.Format(ComputerResources.FailToGetDomainInformation, exception.Message); - ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "FailToGetDomainInformation", - ErrorCategory.OperationStopped, localMachineName); - ThrowTerminatingError(error); } - // Get domain directory entry and reset the password on the machine account of the local machine - Dbg.Diagnostics.Assert(domainName != null, "domainOrServerName should not be null at this point"); - ResetMachineAccountPassword(domainName, localMachineName, Server, Credential, this); + DoRenameComputerWsman(computer, computerName, newName, isLocalhost); } -#endregion "Override Methods" - }//End Class + private void DoRenameComputerWsman(string computer, string computerName, string newName, bool isLocalhost) + { + bool successful = false; + int retVal; + PSCredential credToUse = isLocalhost ? null : (LocalCredential ?? DomainCredential); -#endregion Reset-ComputerMachinePassword + try + { + using (CancellationTokenSource cancelTokenSource = new CancellationTokenSource()) + using (CimSession cimSession = RemoteDiscoveryHelper.CreateCimSession(computer, credToUse, WsmanAuthentication, cancelTokenSource.Token, this)) + { + var operationOptions = new CimOperationOptions + { + Timeout = TimeSpan.FromMilliseconds(10000), + CancellationToken = cancelTokenSource.Token, + //This prefix works against all versions of the WinRM server stack, both win8 and win7 + ResourceUriPrefix = new Uri(ComputerWMIHelper.CimUriPrefix) + }; -#region SAMCmdletsHelper + IEnumerable mCollection = cimSession.QueryInstances( + ComputerWMIHelper.CimOperatingSystemNamespace, + ComputerWMIHelper.CimQueryDialect, + "Select * from " + ComputerWMIHelper.WMI_Class_ComputerSystem, + operationOptions); - /// - /// the static class for calling the the NetJoinDomain function. - /// - internal static class SAMAPI - { - /// - /// Structure for the LSA unicode string - /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - internal struct LSA_UNICODE_STRING - { - internal ushort Length; - internal ushort MaximumLength; - [SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources")] - internal IntPtr Buffer; - } + foreach (CimInstance cimInstance in mCollection) + { + var oldName = cimInstance.CimInstanceProperties["DNSHostName"].Value.ToString(); + if (oldName.Equals(newName, StringComparison.OrdinalIgnoreCase)) + { + string errMsg = StringUtil.Format(ComputerResources.NewNameIsOldName, computerName, newName); + ErrorRecord error = new ErrorRecord( + new InvalidOperationException(errMsg), "NewNameIsOldName", + ErrorCategory.InvalidArgument, newName); + WriteError(error); - /// - /// Structure for the LSA object attributes - /// - [StructLayout(LayoutKind.Sequential)] - internal struct LSA_OBJECT_ATTRIBUTES - { - internal int Length; - internal IntPtr RootDirectory; - internal IntPtr ObjectName; - internal int Attributes; - internal IntPtr SecurityDescriptor; - internal IntPtr SecurityQualityOfService; - } + continue; + } - /// - /// The LSA access mask - /// - internal enum LSA_ACCESS - { - Read = 0x20006, - AllAccess = 0x00F0FFF, - Execute = 0X20801, - Write = 0X207F8 - } + // If the target computer is in a domain, always use the DomainCred. If the DomainCred is not given, + // use null for UserName and Password, so the context of the caller will be used. + // If the target computer is not in a domain, just use null for the UserName and Password + string dUserName = null; + string dPassword = null; + if (((bool)cimInstance.CimInstanceProperties["PartOfDomain"].Value) && (DomainCredential != null)) + { + dUserName = DomainCredential.UserName; + dPassword = Utils.GetStringFromSecureString(DomainCredential.Password); + } - /// - /// LsaOpenPolicy function - /// - /// - /// - /// - /// - /// - [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - internal static extern uint LsaOpenPolicy( - ref LSA_UNICODE_STRING systemName, - ref LSA_OBJECT_ATTRIBUTES objectAttributes, - uint desiredAccess, - out IntPtr policyHandle); + var methodParameters = new CimMethodParametersCollection(); + methodParameters.Add(CimMethodParameter.Create( + "Name", + newName, + Microsoft.Management.Infrastructure.CimType.String, + CimFlags.None)); - /// - /// LsaOpenSecret function - /// - /// - /// - /// - /// - /// - [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - internal static extern uint LsaOpenSecret( - IntPtr policyHandle, - ref LSA_UNICODE_STRING secretName, - uint accessMask, - out IntPtr secretHandle); + methodParameters.Add(CimMethodParameter.Create( + "UserName", + dUserName, + Microsoft.Management.Infrastructure.CimType.String, + (dUserName == null) ? CimFlags.NullValue : CimFlags.None)); - /// - /// LsaCreateSecret function - /// - /// - /// - /// - /// - /// - [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - internal static extern uint LsaCreateSecret( - IntPtr policyHandle, - ref LSA_UNICODE_STRING secretName, - uint desiredAccess, - out IntPtr secretHandle); + methodParameters.Add( + CimMethodParameter.Create( + "Password", + dPassword, + Microsoft.Management.Infrastructure.CimType.String, + (dPassword == null) ? CimFlags.NullValue : CimFlags.None)); - /// - /// LsaQuerySecret function - /// - /// - /// - /// - /// - /// - /// - [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - internal static extern uint LsaQuerySecret( - IntPtr secretHandle, - out IntPtr currentValue, - IntPtr currentValueSetTime, - IntPtr oldValue, - IntPtr oldValueSetTime); + if ( ! InternalTestHooks.TestRenameComputer ) + { + CimMethodResult result = cimSession.InvokeMethod( + ComputerWMIHelper.CimOperatingSystemNamespace, + cimInstance, + "Rename", + methodParameters, + operationOptions); + + retVal = Convert.ToInt32(result.ReturnValue.Value, CultureInfo.CurrentCulture); + } + else + { + retVal = InternalTestHooks.TestRenameComputerResults; + } - /// - /// LsaSetSecret function - /// - /// - /// - /// - /// - [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - internal static extern uint LsaSetSecret( - IntPtr secretHandle, - ref LSA_UNICODE_STRING currentValue, - ref LSA_UNICODE_STRING oldValue); + if (retVal != 0) + { + var ex = new Win32Exception(retVal); + string errMsg = StringUtil.Format(ComputerResources.FailToRename, computerName, newName, ex.Message); + ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "FailToRenameComputer", ErrorCategory.OperationStopped, computerName); + WriteError(error); + } + else + { + successful = true; + } - /// - /// LsaNtStatusToWinError function - /// - /// - /// - [DllImport("advapi32")] - internal static extern int LsaNtStatusToWinError(int ntStatus); + if (PassThru) + { + WriteObject(ComputerWMIHelper.GetRenameComputerStatusObject(retVal, newName, computerName)); + } - /// - /// LsaClose function - /// - /// - /// - [DllImport("advapi32")] - internal static extern int LsaClose(IntPtr policyHandle); + if (successful) + { + if (_restart) + { + // If successful and the Restart parameter is specified, restart the computer + object[] flags = new object[] { 6, 0 }; + ComputerWMIHelper.InvokeWin32ShutdownUsingWsman( + this, + isLocalhost, + computerName, + flags, + credToUse, + WsmanAuthentication, + ComputerResources.RestartcomputerFailed, + "RestartcomputerFailed", + cancelTokenSource.Token); + } + else + { + WriteWarning(StringUtil.Format(ComputerResources.RestartNeeded, null, computerName)); + } + } + } // end foreach + } // end using + } + catch (CimException ex) + { + string errMsg = StringUtil.Format(ComputerResources.FailToConnectToComputer, computerName, ex.Message); + ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "RenameComputerException", + ErrorCategory.OperationStopped, computerName); + WriteError(error); + } + catch (Exception ex) + { + string errMsg = StringUtil.Format(ComputerResources.FailToConnectToComputer, computerName, ex.Message); + ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "RenameComputerException", + ErrorCategory.OperationStopped, computerName); + WriteError(error); + } + } - /// - /// LsaFreeMemory function - /// - /// - /// - [DllImport("advapi32")] - internal static extern int LsaFreeMemory(IntPtr buffer); +#endregion "Private Methods" - /// - /// Initialize a LSA_UNICODE_STRING - /// - /// - /// - /// - internal static void InitLsaString(string s, ref LSA_UNICODE_STRING lus) - { - // Unicode strings max 32KB. The max value for MaximumLength should be ushort.MaxValue-1 - // because UnicodeEncoding.CharSize is 2. So the length of the string s should not be larger - // than (ushort.MaxValue - 1)/UnicodeEncoding.CharSize - 1, which is 0x7ffe (32766) - ushort maxLength = (ushort.MaxValue - 1) / UnicodeEncoding.CharSize - 1; - if (s.Length > maxLength) - throw new ArgumentException("String too long"); - lus.Buffer = Marshal.StringToHGlobalUni(s); - lus.Length = (ushort)(s.Length * UnicodeEncoding.CharSize); - lus.MaximumLength = (ushort)((s.Length + 1) * UnicodeEncoding.CharSize); - } +#region "Override Methods" /// - /// Free the LSA_UNICODE_STRING + /// ProcessRecord method. /// - /// - internal static void FreeLsaString(ref LSA_UNICODE_STRING s) + protected override void ProcessRecord() { - if (s.Buffer == IntPtr.Zero) return; + string targetComputer = ValidateComputerName(); + if (targetComputer == null) return; - Marshal.FreeHGlobal(s.Buffer); - s.Buffer = IntPtr.Zero; - } + bool isLocalhost = targetComputer.Equals("localhost", StringComparison.OrdinalIgnoreCase); + if (isLocalhost) + { + if (!_containsLocalHost) + _containsLocalHost = true; + _newNameForLocalHost = NewName; - /// - /// The NETLOGON_INFO_2 struct used for function I_NetLogonControl2 - /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] - internal struct NetLogonInfo2 - { - internal uint Flags; - /// - /// Secure channel status with the primary domain controller - /// - internal uint PdcConnectionStatus; - /// - /// Name of the trusted domain controller - /// - internal string TrustedDcName; - /// - /// Secure channel status with the specified trusted domain controller - /// - internal uint TdcConnectionStatus; + return; + } + + DoRenameComputerAction(targetComputer, NewName, false); } /// - /// To Reset a password for a computer in domain. + /// EndProcessing method /// - [DllImport("netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - internal static extern int I_NetLogonControl2( - [In] string lpServerName, - uint lpFunctionCode, - uint lpQueryLevel, - ref IntPtr lpInputData, - out IntPtr queryInformation); - + protected override void EndProcessing() + { + if (!_containsLocalHost) return; - [DllImport("Netapi32.dll", SetLastError = true)] - internal static extern int NetApiBufferFree(IntPtr Buffer); + DoRenameComputerAction("localhost", _newNameForLocalHost, true); + } - internal const int WorkGroupMachine = 2692; - internal const int MaxMachineNameLength = 15; +#endregion "Override Methods" } -#endregion - -#endif +#endregion Rename-Computer #region "Public API" /// @@ -6423,16 +1744,6 @@ internal static class ComputerWMIHelper /// internal const string SE_REMOTE_SHUTDOWN_NAME = "SeRemoteShutdownPrivilege"; - /// - /// DCOM protocol - /// - internal const string DcomProtocol = "DCOM"; - - /// - /// WSMan protocol - /// - internal const string WsmanProtocol = "WSMan"; - /// /// CimUriPrefix /// @@ -6458,7 +1769,6 @@ internal static class ComputerWMIHelper /// internal const string localhostStr = "localhost"; - /// /// Get the local admin user name from a local NetworkCredential /// @@ -6513,31 +1823,6 @@ internal static string GetRandomPassword(int passwordLength) return new string(chars); } -#if !CORECLR // TODO:CORECLR Remove once ported to MI .Net - - /// - /// Get the Connection Options - /// - /// - /// - /// - /// - internal static ConnectionOptions GetConnectionOptions(AuthenticationLevel Authentication, ImpersonationLevel Impersonation, PSCredential Credential) - { - ConnectionOptions options = new ConnectionOptions(); - options.Authentication = Authentication; - options.EnablePrivileges = true; - options.Impersonation = Impersonation; - if (Credential != null) - { - options.Username = Credential.UserName; - options.SecurePassword = Credential.Password; - } - return options; - } - -#endif - /// /// Gets the Scope /// @@ -6679,7 +1964,6 @@ internal static RenameComputerChangeInfo GetRenameComputerStatusObject(int error return renamecomputerchangeinfo; } - internal static void WriteNonTerminatingError(int errorcode, PSCmdlet cmdlet, string computername) { Win32Exception ex = new Win32Exception(errorcode); @@ -6806,6 +2090,7 @@ internal static bool InvokeWin32ShutdownUsingWsman( using (CimSession cimSession = RemoteDiscoveryHelper.CreateCimSession(targetMachine, credInUse, authInUse, cancelToken, cmdlet)) { var methodParameters = new CimMethodParametersCollection(); + int retVal; methodParameters.Add(CimMethodParameter.Create( "Flags", flags[0], @@ -6818,14 +2103,22 @@ internal static bool InvokeWin32ShutdownUsingWsman( Microsoft.Management.Infrastructure.CimType.SInt32, CimFlags.None)); - CimMethodResult result = cimSession.InvokeMethod( - ComputerWMIHelper.CimOperatingSystemNamespace, - ComputerWMIHelper.WMI_Class_OperatingSystem, - ComputerWMIHelper.CimOperatingSystemShutdownMethod, - methodParameters, - operationOptions); + if ( ! InternalTestHooks.TestStopComputer ) + { + CimMethodResult result = cimSession.InvokeMethod( + ComputerWMIHelper.CimOperatingSystemNamespace, + ComputerWMIHelper.WMI_Class_OperatingSystem, + ComputerWMIHelper.CimOperatingSystemShutdownMethod, + methodParameters, + operationOptions); + + retVal = Convert.ToInt32(result.ReturnValue.Value, CultureInfo.CurrentCulture); + } + else + { + retVal = InternalTestHooks.TestStopComputerResults; + } - int retVal = Convert.ToInt32(result.ReturnValue.Value, CultureInfo.CurrentCulture); if (retVal != 0) { var ex = new Win32Exception(retVal); @@ -6935,15 +2228,6 @@ internal static string ValidateComputerName( } #endregion Helper -#region Internal Enums - - internal enum TransportProtocol - { - DCOM = 1, - WSMan = 2 - } - -#endregion }//End namespace #endif diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/ContentCommandBase.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/ContentCommandBase.cs index b53c46731f3..f82be5f916f 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/ContentCommandBase.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/ContentCommandBase.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; @@ -348,7 +347,6 @@ public PSObject AttachNotes(PSObject content) } // AttachNotes } // ContentPathsCache - /// /// A struct to hold the path information and the content readers/writers /// for an item. @@ -410,7 +408,6 @@ internal void CloseContent(List contentHolders, bool disposing) holder.PathInfo.Path, e); - // Log a provider health event MshLog.LogProviderHealthEvent( @@ -448,7 +445,6 @@ internal void CloseContent(List contentHolders, bool disposing) holder.PathInfo.Path, e); - // Log a provider health event MshLog.LogProviderHealthEvent( diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/ControlPanelItemCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/ControlPanelItemCommand.cs index 54c95b9c16e..8c8dcbe2e26 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/ControlPanelItemCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/ControlPanelItemCommand.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/ConvertPathCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/ConvertPathCommand.cs index dd3d3d90502..06ea2fc7924 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/ConvertPathCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/ConvertPathCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Collections.ObjectModel; using System.Management.Automation; @@ -126,7 +125,6 @@ protected override void ProcessRecord() } // ProcessRecord #endregion Command code - } // ConvertPathCommand } // namespace Microsoft.PowerShell.Commands diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/CopyPropertyCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/CopyPropertyCommand.cs index b2b90c63b19..15b3327b3c4 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/CopyPropertyCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/CopyPropertyCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; using Dbg = System.Management.Automation; @@ -152,6 +151,5 @@ protected override void ProcessRecord() } // ProcessRecord #endregion Command code - } // CopyItemPropertyCommand } // namespace Microsoft.PowerShell.Commands diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Eventlog.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Eventlog.cs index 2d5ff805e75..eececdd3d33 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Eventlog.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Eventlog.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections; @@ -132,7 +131,6 @@ public long[] InstanceId } private long[] _instanceIds = null; - /// /// match eventlog entries by the Index /// gets or sets an array of indexes @@ -152,7 +150,6 @@ public int[] Index } private int[] _indexes = null; - /// /// match eventlog entries by the EntryType /// gets or sets an array of EntryTypes @@ -224,7 +221,6 @@ public string Message [Parameter(ParameterSetName = "List")] public SwitchParameter List { get; set; } - /// /// Return the log names rather than the EventLog objects /// @@ -442,8 +438,6 @@ private void Process(EventLog log) } } - - private bool FiltersMatch(EventLogEntry entry) { if (_indexes != null) @@ -614,7 +608,6 @@ public sealed class ClearEventLogCommand : PSCmdlet [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public string[] LogName { get; set; } - /// /// Clear eventlog entries from these Computers. /// @@ -706,7 +699,6 @@ public sealed class WriteEventLogCommand : PSCmdlet [ValidateNotNullOrEmpty] public string LogName { get; set; } - /// /// The source by which the application is registered on the specified computer. /// @@ -748,7 +740,6 @@ public sealed class WriteEventLogCommand : PSCmdlet [ValidateLength(0, 32766)] public string Message { get; set; } - /// /// Write eventlog entries of this log /// @@ -1318,7 +1309,6 @@ public class RemoveEventLogCommand : PSCmdlet [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public String[] Source { get; set; } - /// /// BeginProcessing method. /// diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetChildrenCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetChildrenCommand.cs index 566ec8929f7..f71f0ee751f 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetChildrenCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetChildrenCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; @@ -278,7 +277,6 @@ internal override object GetDynamicParameters(CmdletProviderContext context) #endregion command data - #region command code /// @@ -288,8 +286,7 @@ protected override void ProcessRecord() { CmdletProviderContext currentContext = CmdletProviderContext; - if (_paths == null || - (_paths != null && _paths.Length == 0)) + if (_paths == null || _paths.Length == 0) { _paths = new string[] { String.Empty }; } diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetClipboardCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetClipboardCommand.cs index 176ee347211..f88f79aefb5 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetClipboardCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetClipboardCommand.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using System.Management.Automation; using System.Collections.Generic; using System.Windows.Forms; diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetComputerInfoCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetComputerInfoCommand.cs index 5d014dbea57..f94c1190742 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetComputerInfoCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetComputerInfoCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #if !UNIX @@ -571,7 +570,6 @@ private static MiscInfoGroup GetOtherInfo(CimSession session) //TODO: Local machine only. Check for that? rv.physicallyInstalledMemory = GetPhysicallyInstalledSystemMemory(); - // get time zone // we'll use .Net's TimeZoneInfo for now. systeminfo uses Caption from Win32_TimeZone var tzi = TimeZoneInfo.Local; @@ -5119,7 +5117,6 @@ private static class PInvokeDllNames public const UInt32 S_OK = 0; - /// /// Import WINAPI function PowerDeterminePlatformRoleEx /// diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetContentCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetContentCommand.cs index f4b5ce1b39a..5248ac19e59 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetContentCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetContentCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections; diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetPropertyCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetPropertyCommand.cs index ea812badce1..8c746508e97 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetPropertyCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetPropertyCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetTransactionCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetTransactionCommand.cs index 81d9c1f9010..05216d7e1bc 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetTransactionCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetTransactionCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; using Dbg = System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetWMIObjectCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetWMIObjectCommand.cs index 4d2ee3550be..3488b10e0ea 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetWMIObjectCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetWMIObjectCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Globalization; @@ -21,7 +20,6 @@ public class GetWmiObjectCommand : WmiBaseCmdlet { #region Parameters - /// /// The WMI class to query /// diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Hotfix.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Hotfix.cs index 6bdbedbb966..e96fa603d01 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Hotfix.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Hotfix.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Text; @@ -26,7 +25,6 @@ using System.Security.AccessControl; using Dbg = System.Management.Automation; - namespace Microsoft.PowerShell.Commands { #region Get-HotFix @@ -79,7 +77,6 @@ public sealed class GetHotFixCommand : PSCmdlet, IDisposable #region Overrides - private ManagementObjectSearcher _searchProcess; private bool _inputContainsWildcard = false; diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/InvokeWMIMethodCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/InvokeWMIMethodCommand.cs index 2e37ca088e6..8a911bfb69b 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/InvokeWMIMethodCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/InvokeWMIMethodCommand.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/MovePropertyCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/MovePropertyCommand.cs index 9396471b74a..ffdf1b95ca9 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/MovePropertyCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/MovePropertyCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; @@ -168,6 +167,5 @@ protected override void ProcessRecord() } // ProcessRecord #endregion Command code - } // MoveItemPropertyCommand } // namespace Microsoft.PowerShell.Commands diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Navigation.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Navigation.cs index e16d512b1f1..a4f7e8750e2 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Navigation.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Navigation.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; @@ -206,7 +205,6 @@ protected override void StopProcessing() /// public virtual string Filter { get; set; } - /// /// Gets or sets the include property /// @@ -225,7 +223,6 @@ protected override void StopProcessing() // Include - /// /// Gets or sets the exclude property /// @@ -244,7 +241,6 @@ protected override void StopProcessing() // Exclude - /// /// Gets or sets the force property /// @@ -276,7 +272,6 @@ public virtual SwitchParameter Force } // Force private bool _force; - /// /// Retrieves the dynamic parameters for the command from /// the provider. @@ -419,7 +414,6 @@ public class GetLocationCommand : DriveMatchingCoreCommandBase #region Location parameter set parameters - /// /// Gets or sets the provider from which to get the current location. /// @@ -486,7 +480,6 @@ public string[] StackName #region command data - #region Location parameter set data /// @@ -505,10 +498,8 @@ public string[] StackName #endregion Stack parameter set data - #endregion command data - #region command code /// @@ -717,7 +708,6 @@ protected override void ProcessRecord() } // class GetLocationCommand #endregion GetLocationCommand - #region SetLocationCommand /// @@ -962,7 +952,6 @@ public string LiteralPath } // set } // LiteralPath - /// /// Gets or sets the parameter -passThru which states output from /// the command should be placed in the pipeline. @@ -1156,10 +1145,8 @@ public string StackName #endregion Command data - #region Command code - /// /// Gets the top container from the location stack and sets the /// location to it. @@ -1586,7 +1573,6 @@ internal List GetMatchingDrives( } } - WildcardPattern providerMatcher = null; PSSnapinQualifiedName pssnapinQualifiedProviderName = null; @@ -1606,7 +1592,6 @@ internal List GetMatchingDrives( WildcardOptions.IgnoreCase); } - WildcardPattern nameMatcher = null; if (!driveNameEmpty) @@ -2362,8 +2347,7 @@ protected override bool ProviderSupportsShouldProcess /// protected override void ProcessRecord() { - if (Path == null || - (Path != null && Path.Length == 0)) + if (Path == null || Path.Length == 0) { Path = new string[] { String.Empty }; } @@ -3388,7 +3372,6 @@ private void MoveItem(string path) continue; } - // See if the item to be moved is in use. bool isCurrentLocationOrAncestor = false; try @@ -3562,7 +3545,6 @@ public override SwitchParameter Force set { base.Force = value; } } - /// /// Gets or sets the pass through property which determines /// if the object that is set should be written to the pipeline. @@ -4533,9 +4515,7 @@ public string[] PSProvider /// protected override void ProcessRecord() { - if (PSProvider == null || - (PSProvider != null && - PSProvider.Length == 0)) + if (PSProvider == null || PSProvider.Length == 0) { // Get all the providers diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/NewPropertyCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/NewPropertyCommand.cs index e89d9db2284..fbf3312c149 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/NewPropertyCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/NewPropertyCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; using Dbg = System.Management.Automation; @@ -182,6 +181,5 @@ protected override void ProcessRecord() } // ProcessRecord #endregion Command code - } // NewItemPropertyCommand } // namespace Microsoft.PowerShell.Commands diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/ParsePathCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/ParsePathCommand.cs index a1f29117de4..a87643e36b7 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/ParsePathCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/ParsePathCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.ObjectModel; @@ -48,7 +47,6 @@ public class SplitPathCommand : CoreCommandWithCredentialsBase /// private const string extensionSet = "ExtensionSet"; - /// /// The parameter set name to get the qualifier set. /// @@ -187,7 +185,6 @@ public string[] LiteralPath #region parameter data - #endregion parameter data #region Command code diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/PassThroughContentCommandBase.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/PassThroughContentCommandBase.cs index 20ea5a5c394..7f4e3e65c06 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/PassThroughContentCommandBase.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/PassThroughContentCommandBase.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; using Dbg = System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/PassThroughPropertyCommandBase.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/PassThroughPropertyCommandBase.cs index 8b25bf179f8..734433ffc90 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/PassThroughPropertyCommandBase.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/PassThroughPropertyCommandBase.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; using Dbg = System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/PingPathCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/PingPathCommand.cs index ea69de6c381..37f39e54e24 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/PingPathCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/PingPathCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; using Dbg = System.Management.Automation; @@ -207,7 +206,6 @@ protected override void ProcessRecord() } // ProcessRecord #endregion Command code - } // PingPathCommand } // namespace Microsoft.PowerShell.Commands diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs index a49c5f7a2f6..0ac97156103 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Text; @@ -69,12 +68,6 @@ internal enum MatchMode /// internal MatchMode myMode = MatchMode.All; - /// - /// The computer from which to retrieve processes. - /// - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - protected string[] SuppliedComputerName { get; set; } = Utils.EmptyArray(); - /// /// The Name parameter is declared in subclasses, /// since it is optional for GetProcess and mandatory for StopProcess. @@ -228,19 +221,8 @@ private void RetrieveMatchingProcessesById() Process process; try { - if (SuppliedComputerName.Length > 0) - { - foreach (string computerName in SuppliedComputerName) - { - process = Process.GetProcessById(processId, computerName); - AddIdempotent(process); - } - } - else - { - process = Process.GetProcessById(processId); - AddIdempotent(process); - } + process = Process.GetProcessById(processId); + AddIdempotent(process); } catch (ArgumentException) { @@ -292,19 +274,7 @@ internal Process[] AllProcesses if (null == _allProcesses) { List processes = new List(); - - if (SuppliedComputerName.Length > 0) - { - foreach (string computerName in SuppliedComputerName) - { - processes.AddRange(Process.GetProcesses(computerName)); - } - } - else - { - processes.AddRange(Process.GetProcesses()); - } - + processes.AddRange(Process.GetProcesses()); _allProcesses = processes.ToArray(); } return _allProcesses; @@ -555,29 +525,6 @@ public SwitchParameter IncludeUserName } private bool _includeUserName = false; - - /// - /// gets/sets the destination computer name - /// - [Parameter(Mandatory = false, ParameterSetName = NameParameterSet, ValueFromPipelineByPropertyName = true)] - [Parameter(Mandatory = false, ParameterSetName = IdParameterSet, ValueFromPipelineByPropertyName = true)] - [Parameter(Mandatory = false, ParameterSetName = InputObjectParameterSet, ValueFromPipelineByPropertyName = true)] - [Alias("Cn")] - [ValidateNotNullOrEmpty()] - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - public string[] ComputerName - { - get - { - return SuppliedComputerName; - } - set - { - SuppliedComputerName = value; - } - } - - /// ///To display the modules of a process /// @@ -621,13 +568,6 @@ protected override void BeginProcessing() /// protected override void ProcessRecord() { - if (ComputerName.Length > 0 && (FileVersionInfo.IsPresent || Module.IsPresent)) - { - Exception ex = new InvalidOperationException(ProcessResources.NoComputerNameWithFileVersion); - ErrorRecord er = new ErrorRecord(ex, "InvalidOperationException", ErrorCategory.InvalidOperation, ComputerName); - ThrowTerminatingError(er); - } - foreach (Process process in MatchingProcesses()) { //if module and fileversion are to be displayed @@ -710,7 +650,10 @@ protected override void ProcessRecord() //if fileversion of each process is to be displayed try { - WriteObject(PsUtils.GetMainModule(process).FileVersionInfo, true); + ProcessModule mainModule = PsUtils.GetMainModule(process); + if (mainModule != null) { + WriteObject(mainModule.FileVersionInfo, true); + } } catch (InvalidOperationException exception) { @@ -778,7 +721,6 @@ private static PSObject AddUserNameToProcess(Process process) return processAsPsobj; } - /// /// Retrieve the UserName through PInvoke /// @@ -960,7 +902,6 @@ public int Timeout private int _timeout = 0; private bool _timeOutSpecified; - #endregion Parameters private bool _disposed = false; @@ -1007,7 +948,6 @@ private void myProcess_Exited(object sender, System.EventArgs e) private ManualResetEvent _waitHandle; private int _numberOfProcessesToWaitFor; - /// /// gets the list of process /// @@ -1194,7 +1134,6 @@ public SwitchParameter PassThru set { _passThru = value; } } - //Addition by v-ramch Mar 18 2008 //Added force parameter /// @@ -1329,7 +1268,6 @@ protected override void ProcessRecord() } } // ProcessRecord - /// /// Kill the current process here. /// @@ -1672,10 +1610,9 @@ public sealed class StartProcessCommand : PSCmdlet, IDisposable /// [Parameter(Mandatory = true, Position = 0)] [ValidateNotNullOrEmpty] - [Alias("PSPath")] + [Alias("PSPath","Path")] public string FilePath { get; set; } - /// /// Arguments for the process /// @@ -1685,7 +1622,6 @@ public sealed class StartProcessCommand : PSCmdlet, IDisposable [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public string[] ArgumentList { get; set; } - /// /// Credentials for the process /// @@ -1711,7 +1647,6 @@ public PSCredential Credential [ValidateNotNullOrEmpty] public string WorkingDirectory { get; set; } - /// /// load user profile from registry /// @@ -1750,7 +1685,6 @@ public SwitchParameter NoNewWindow [Parameter] public SwitchParameter PassThru { get; set; } - /// /// Redirect error /// @@ -1768,7 +1702,6 @@ public string RedirectStandardError } private string _redirectstandarderror; - /// /// Redirect input /// @@ -1786,7 +1719,6 @@ public string RedirectStandardInput } private string _redirectstandardinput; - /// /// Redirect output /// @@ -1924,7 +1856,6 @@ protected override void BeginProcessing() startInfo.Arguments = sb.ToString(); ; } - //WorkingDirectory if (WorkingDirectory != null) { @@ -2322,7 +2253,6 @@ private SafeFileHandle GetSafeFileHandleForRedirection(string RedirectionPath, u System.IntPtr hFileHandle = System.IntPtr.Zero; ProcessNativeMethods.SECURITY_ATTRIBUTES lpSecurityAttributes = new ProcessNativeMethods.SECURITY_ATTRIBUTES(); - hFileHandle = ProcessNativeMethods.CreateFileW(RedirectionPath, ProcessNativeMethods.GENERIC_READ | ProcessNativeMethods.GENERIC_WRITE, ProcessNativeMethods.FILE_SHARE_WRITE | ProcessNativeMethods.FILE_SHARE_READ, @@ -2714,11 +2644,9 @@ internal static class ProcessNativeMethods internal static UInt32 OF_READWRITE = 0x00000002; internal static UInt32 OPEN_EXISTING = 3; - // Methods // static NativeMethods(); - [DllImport(PinvokeDllNames.GetStdHandleDllName, CharSet = CharSet.Ansi, SetLastError = true)] public static extern IntPtr GetStdHandle(int whichHandle); @@ -2761,7 +2689,6 @@ public static extern FileNakedHandle CreateFileW( System.IntPtr hTemplateFile ); - [Flags] internal enum LogonFlags { @@ -2804,7 +2731,6 @@ protected override bool ReleaseHandle() } } - [StructLayout(LayoutKind.Sequential)] internal class STARTUPINFO { diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/PropertyCommandBase.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/PropertyCommandBase.cs index bd707d4cc2e..9f65a40b9d6 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/PropertyCommandBase.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/PropertyCommandBase.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; using Dbg = System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/RegisterWMIEventCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/RegisterWMIEventCommand.cs index 0319b0e8130..0e288454b0d 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/RegisterWMIEventCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/RegisterWMIEventCommand.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections; @@ -45,7 +44,6 @@ public class RegisterWmiEventCommand : ObjectEventRegistrationBase [ValidateNotNullOrEmpty] public string ComputerName { get; set; } = "localhost"; - /// /// The WMI class to use /// @@ -97,7 +95,6 @@ private string GetScopeString(string computer, string namespaceParameter) } #endregion helper functions - /// /// Returns the object that generates events to be monitored /// diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/RemovePropertyCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/RemovePropertyCommand.cs index 67f035b1f27..76df0806b8d 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/RemovePropertyCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/RemovePropertyCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; using Dbg = System.Management.Automation; @@ -180,6 +179,5 @@ protected override void ProcessRecord() } // ProcessRecord #endregion Command code - } // RemoveItemPropertyCommand } // namespace Microsoft.PowerShell.Commands diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/RemoveWMIObjectCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/RemoveWMIObjectCommand.cs index ac10af1dc98..31c78f79e82 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/RemoveWMIObjectCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/RemoveWMIObjectCommand.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management; diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/RenamePropertyCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/RenamePropertyCommand.cs index c5077bfda79..8f2fc873ce1 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/RenamePropertyCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/RenamePropertyCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; using Dbg = System.Management.Automation; @@ -149,6 +148,5 @@ protected override void ProcessRecord() } // ProcessRecord #endregion Command code - } // RenameItemPropertyCommand } // namespace Microsoft.PowerShell.Commands diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs index 5930dbab51e..6f260a89f8b 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; @@ -76,7 +75,6 @@ public SwitchParameter Relative } // Relative private SwitchParameter _relative; - #endregion Parameters #region parameter data @@ -107,13 +105,26 @@ protected override void ProcessRecord() { foreach (PathInfo currentPath in result) { + // When result path and base path is on different PSDrive + // (../)*path should not go beyond the root of base path + if (currentPath.Drive != SessionState.Path.CurrentLocation.Drive && + SessionState.Path.CurrentLocation.Drive != null && + !currentPath.ProviderPath.StartsWith( + SessionState.Path.CurrentLocation.Drive.Root, StringComparison.OrdinalIgnoreCase)) + { + WriteObject(currentPath.Path, enumerateCollection: false); + continue; + } string adjustedPath = SessionState.Path.NormalizeRelativePath(currentPath.Path, SessionState.Path.CurrentLocation.ProviderPath); - if (!adjustedPath.StartsWith(".", StringComparison.OrdinalIgnoreCase)) + // Do not insert './' if result path is not relative + if (!adjustedPath.StartsWith( + currentPath.Drive?.Root ?? currentPath.Path, StringComparison.OrdinalIgnoreCase) && + !adjustedPath.StartsWith(".", StringComparison.OrdinalIgnoreCase)) { adjustedPath = SessionState.Path.Combine(".", adjustedPath); } - WriteObject(adjustedPath, false); + WriteObject(adjustedPath, enumerateCollection: false); } } } @@ -152,13 +163,12 @@ protected override void ProcessRecord() if (!_relative) { - WriteObject(result, true); + WriteObject(result, enumerateCollection: true); } } } // ProcessRecord #endregion Command code - } // ResolvePathCommand } // namespace Microsoft.PowerShell.Commands diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/RollbackTransactionCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/RollbackTransactionCommand.cs index 79b48c496b6..1c586b100c9 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/RollbackTransactionCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/RollbackTransactionCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; using Dbg = System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs index 29c407c50d0..d993091378d 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs @@ -1,6 +1,6 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #if !UNIX // Not built on Unix using System; @@ -551,7 +551,6 @@ public string[] Name [Alias("DS")] public SwitchParameter DependentServices { get; set; } - /// /// This returns the ServicesDependedOn of the specified service. /// @@ -571,7 +570,7 @@ protected override void ProcessRecord() { if (!DependentServices.IsPresent && !RequiredServices.IsPresent) { - WriteObject(service); + WriteObject(AddProperties(service)); } else { @@ -594,6 +593,107 @@ protected override void ProcessRecord() } #endregion Overrides + + /// + /// Adds UserName, Description, BinaryPathName, DelayedAutoStart and StartupType to a ServiceController object. + /// + /// + /// ServiceController as PSObject with UserName, Description and StartupType added + private PSObject AddProperties(ServiceController service) { + NakedWin32Handle hScManager = IntPtr.Zero; + NakedWin32Handle hService = IntPtr.Zero; + int lastError = 0; + PSObject serviceAsPSObj = PSObject.AsPSObject(service); + try + { + hScManager = NativeMethods.OpenSCManagerW( + lpMachineName: service.MachineName, + lpDatabaseName: null, + dwDesiredAccess: NativeMethods.SC_MANAGER_CONNECT + ); + if (IntPtr.Zero == hScManager) { + lastError = Marshal.GetLastWin32Error(); + Win32Exception exception = new Win32Exception(lastError); + WriteNonTerminatingError( + service, + exception, + "FailToOpenServiceControlManager", + ServiceResources.FailToOpenServiceControlManager, + ErrorCategory.PermissionDenied); + } + hService = NativeMethods.OpenServiceW( + hScManager, + service.ServiceName, + NativeMethods.SERVICE_QUERY_CONFIG + ); + if (IntPtr.Zero == hService) { + lastError = Marshal.GetLastWin32Error(); + Win32Exception exception = new Win32Exception(lastError); + WriteNonTerminatingError( + service, + exception, + "CouldNotGetServiceInfo", + ServiceResources.CouldNotGetServiceInfo, + ErrorCategory.PermissionDenied); + } + + NativeMethods.SERVICE_DESCRIPTIONW description = new NativeMethods.SERVICE_DESCRIPTIONW(); + bool querySuccessful = NativeMethods.QueryServiceConfig2(hService, NativeMethods.SERVICE_CONFIG_DESCRIPTION, out description); + + NativeMethods.SERVICE_DELAYED_AUTO_START_INFO autostartInfo = new NativeMethods.SERVICE_DELAYED_AUTO_START_INFO(); + querySuccessful = querySuccessful && NativeMethods.QueryServiceConfig2(hService, NativeMethods.SERVICE_CONFIG_DELAYED_AUTO_START_INFO, out autostartInfo); + + NativeMethods.QUERY_SERVICE_CONFIG serviceInfo = new NativeMethods.QUERY_SERVICE_CONFIG(); + querySuccessful = querySuccessful && NativeMethods.QueryServiceConfig(hService, out serviceInfo); + + if(!querySuccessful) { + WriteNonTerminatingError( + service: service, + innerException: null, + errorId: "CouldNotGetServiceInfo", + errorMessage: ServiceResources.CouldNotGetServiceInfo, + category: ErrorCategory.PermissionDenied + ); + } + + PSProperty noteProperty = new PSProperty("UserName", serviceInfo.lpServiceStartName); + serviceAsPSObj.Properties.Add(noteProperty, true); + serviceAsPSObj.TypeNames.Insert(0, "System.Service.ServiceController#UserName"); + + noteProperty = new PSProperty("Description", description.lpDescription); + serviceAsPSObj.Properties.Add(noteProperty, true); + serviceAsPSObj.TypeNames.Insert(0, "System.Service.ServiceController#Description"); + + noteProperty = new PSProperty("DelayedAutoStart", autostartInfo.fDelayedAutostart); + serviceAsPSObj.Properties.Add(noteProperty, true); + serviceAsPSObj.TypeNames.Insert(0, "System.Service.ServiceController#DelayedAutoStart"); + + noteProperty = new PSProperty("BinaryPathName", serviceInfo.lpBinaryPathName); + serviceAsPSObj.Properties.Add(noteProperty, true); + serviceAsPSObj.TypeNames.Insert(0, "System.Service.ServiceController#BinaryPathName"); + + noteProperty = new PSProperty("StartupType", NativeMethods.GetServiceStartupType(service.StartType, autostartInfo.fDelayedAutostart)); + serviceAsPSObj.Properties.Add(noteProperty, true); + serviceAsPSObj.TypeNames.Insert(0, "System.Service.ServiceController#StartupType"); + } + finally + { + if (IntPtr.Zero != hService) { + bool succeeded = NativeMethods.CloseServiceHandle(hService); + if (!succeeded) { + Diagnostics.Assert(lastError != 0, "ErrorCode not success"); + } + } + + if (IntPtr.Zero != hScManager) { + bool succeeded = NativeMethods.CloseServiceHandle(hScManager); + if (!succeeded) { + Diagnostics.Assert(lastError != 0, "ErrorCode not success"); + } + } + } // finally + return serviceAsPSObj; + } } #endregion GetServiceCommand @@ -1371,8 +1471,6 @@ public class SetServiceCommand : ServiceOperationBaseCommand [Credential()] public PSCredential Credential { get; set; } - - /// /// The following is the definition of the input parameter "Description". /// Specifies a new description for the service. @@ -1392,7 +1490,6 @@ public string Description } internal string description = null; - /// /// The following is the definition of the input parameter "StartupType". /// Changes the starting mode of the service. Valid values for StartupType are: @@ -1403,7 +1500,7 @@ public string Description [Parameter] [Alias("StartMode", "SM", "ST")] [ValidateNotNullOrEmpty] - public ServiceStartMode StartupType + public ServiceStartupType StartupType { get { return startupType; } set @@ -1413,8 +1510,7 @@ public ServiceStartMode StartupType } // We set the initial value to an invalid value so that we can // distinguish when this is and is not set. - internal ServiceStartMode startupType = (ServiceStartMode)(-1); - + internal ServiceStartupType startupType = ServiceStartupType.InvalidValue; /// /// The following is the definition of the input parameter "Status". @@ -1530,6 +1626,7 @@ protected override void ProcessRecord() NakedWin32Handle hScManager = IntPtr.Zero; NakedWin32Handle hService = IntPtr.Zero; + IntPtr delayedAutoStartInfoBuffer = IntPtr.Zero; try { hScManager = NativeMethods.OpenSCManagerW( @@ -1567,10 +1664,9 @@ protected override void ProcessRecord() ErrorCategory.PermissionDenied); return; } - // Modify startup type or display name or credential if (!String.IsNullOrEmpty(DisplayName) - || (ServiceStartMode)(-1) != StartupType || null != Credential) + || ServiceStartupType.InvalidValue != StartupType || null != Credential) { DWORD dwStartType = NativeMethods.SERVICE_NO_CHANGE; if (!NativeMethods.TryGetNativeStartupType(StartupType, out dwStartType)) @@ -1638,6 +1734,32 @@ protected override void ProcessRecord() ErrorCategory.PermissionDenied); } + // Set the delayed auto start + NativeMethods.SERVICE_DELAYED_AUTO_START_INFO ds = new NativeMethods.SERVICE_DELAYED_AUTO_START_INFO(); + ds.fDelayedAutostart = StartupType == ServiceStartupType.AutomaticDelayedStart; + size = Marshal.SizeOf(ds); + delayedAutoStartInfoBuffer = Marshal.AllocCoTaskMem(size); + Marshal.StructureToPtr(ds, delayedAutoStartInfoBuffer, false); + + status = NativeMethods.ChangeServiceConfig2W( + hService, + NativeMethods.SERVICE_CONFIG_DELAYED_AUTO_START_INFO, + delayedAutoStartInfoBuffer); + + if (!status) + { + int lastError = Marshal.GetLastWin32Error(); + Win32Exception exception = new Win32Exception(lastError); + WriteNonTerminatingError( + Name, + DisplayName, + Name, + exception, + "CouldNotSetServiceDelayedAutoStart", + ServiceResources.CouldNotSetServiceDelayedAutoStart, + ErrorCategory.PermissionDenied); + } + // Handle the '-Status' parameter if (!string.IsNullOrEmpty(Status)) { @@ -1694,6 +1816,10 @@ protected override void ProcessRecord() } finally { + if (IntPtr.Zero != delayedAutoStartInfoBuffer) + { + Marshal.FreeCoTaskMem(delayedAutoStartInfoBuffer); + } if (IntPtr.Zero != hService) { bool succeeded = NativeMethods.CloseServiceHandle(hService); @@ -1771,6 +1897,7 @@ public string Name /// /// [Parameter(Position = 1, Mandatory = true)] + [Alias("Path")] public string BinaryPathName { get { return binaryPathName; } @@ -1809,12 +1936,12 @@ public string Description /// /// [Parameter] - public ServiceStartMode StartupType + public ServiceStartupType StartupType { get { return startupType; } set { startupType = value; } } - internal ServiceStartMode startupType = ServiceStartMode.Automatic; + internal ServiceStartupType startupType = ServiceStartupType.Automatic; /// /// Account under which the service should run @@ -1865,6 +1992,7 @@ protected override void BeginProcessing() NakedWin32Handle hScManager = IntPtr.Zero; NakedWin32Handle hService = IntPtr.Zero; IntPtr password = IntPtr.Zero; + IntPtr delayedAutoStartInfoBuffer = IntPtr.Zero; try { hScManager = NativeMethods.OpenSCManagerW( @@ -1987,6 +2115,34 @@ protected override void BeginProcessing() ErrorCategory.PermissionDenied); } + // Set the delayed auto start + if(StartupType == ServiceStartupType.AutomaticDelayedStart) { + NativeMethods.SERVICE_DELAYED_AUTO_START_INFO ds = new NativeMethods.SERVICE_DELAYED_AUTO_START_INFO(); + ds.fDelayedAutostart = true; + size = Marshal.SizeOf(ds); + delayedAutoStartInfoBuffer = Marshal.AllocCoTaskMem(size); + Marshal.StructureToPtr(ds, delayedAutoStartInfoBuffer, false); + + succeeded = NativeMethods.ChangeServiceConfig2W( + hService, + NativeMethods.SERVICE_CONFIG_DELAYED_AUTO_START_INFO, + delayedAutoStartInfoBuffer); + + if (!succeeded) + { + int lastError = Marshal.GetLastWin32Error(); + Win32Exception exception = new Win32Exception(lastError); + WriteNonTerminatingError( + Name, + DisplayName, + Name, + exception, + "CouldNotNewServiceDelayedAutoStart", + ServiceResources.CouldNotNewServiceDelayedAutoStart, + ErrorCategory.PermissionDenied); + } + } + // write the ServiceController for the new service using (ServiceController service = new ServiceController(Name)) // ensure dispose @@ -1996,6 +2152,11 @@ protected override void BeginProcessing() } finally { + if (IntPtr.Zero != delayedAutoStartInfoBuffer) + { + Marshal.FreeCoTaskMem(delayedAutoStartInfoBuffer); + } + if (IntPtr.Zero != password) { Marshal.ZeroFreeCoTaskMemUnicode(password); @@ -2305,6 +2466,7 @@ internal static class NativeMethods // from winuser.h internal const int ERROR_SERVICE_ALREADY_RUNNING = 1056; internal const int ERROR_SERVICE_NOT_ACTIVE = 1062; + internal const int ERROR_INSUFFICIENT_BUFFER = 122; internal const DWORD SC_MANAGER_CONNECT = 1; internal const DWORD SC_MANAGER_CREATE_SERVICE = 2; internal const DWORD SC_MANAGER_ALL_ACCESS = 0xf003f; @@ -2316,6 +2478,9 @@ internal static class NativeMethods internal const DWORD SERVICE_DEMAND_START = 0x3; internal const DWORD SERVICE_DISABLED = 0x4; internal const DWORD SERVICE_CONFIG_DESCRIPTION = 1; + internal const DWORD SERVICE_CONFIG_DELAYED_AUTO_START_INFO = 3; + internal const DWORD SERVICE_CONFIG_SERVICE_SID_INFO = 5; + internal const DWORD SERVICE_WIN32_OWN_PROCESS = 0x10; internal const DWORD SERVICE_ERROR_NORMAL = 1; @@ -2336,6 +2501,25 @@ NakedWin32Handle OpenServiceW( DWORD dwDesiredAccess ); + [DllImport(PinvokeDllNames.QueryServiceConfigDllName, CharSet = CharSet.Unicode, SetLastError = true)] + internal static extern + bool QueryServiceConfigW( + NakedWin32Handle hSCManager, + IntPtr lpServiceConfig, + DWORD cbBufSize, + out DWORD pcbBytesNeeded + ); + + [DllImport(PinvokeDllNames.QueryServiceConfig2DllName, CharSet = CharSet.Unicode, SetLastError = true)] + internal static extern + bool QueryServiceConfig2W( + NakedWin32Handle hService, + DWORD dwInfoLevel, + IntPtr lpBuffer, + DWORD cbBufSize, + out DWORD pcbBytesNeeded + ); + [DllImport(PinvokeDllNames.CloseServiceHandleDllName, CharSet = CharSet.Unicode, SetLastError = true)] internal static extern bool CloseServiceHandle( @@ -2379,6 +2563,26 @@ internal struct SERVICE_DESCRIPTIONW internal string lpDescription; }; + [StructLayout(LayoutKind.Sequential)] + internal struct QUERY_SERVICE_CONFIG + { + internal uint dwServiceType; + internal uint dwStartType; + internal uint dwErrorControl; + [MarshalAs(UnmanagedType.LPWStr)] internal string lpBinaryPathName; + [MarshalAs(UnmanagedType.LPWStr)] internal string lpLoadOrderGroup; + internal uint dwTagId; + [MarshalAs(UnmanagedType.LPWStr)] internal string lpDependencies; + [MarshalAs(UnmanagedType.LPWStr)] internal string lpServiceStartName; + [MarshalAs(UnmanagedType.LPWStr)] internal string lpDisplayName; + }; + + [StructLayout(LayoutKind.Sequential)] + internal struct SERVICE_DELAYED_AUTO_START_INFO + { + internal bool fDelayedAutostart; + }; + [DllImport(PinvokeDllNames.CreateServiceWDllName, CharSet = CharSet.Unicode, SetLastError = true)] internal static extern NakedWin32Handle CreateServiceW( @@ -2460,6 +2664,77 @@ public static extern bool QueryInformationJobObject(SafeHandle hJob, int JobObje ref JOBOBJECT_BASIC_PROCESS_ID_LIST lpJobObjectInfo, int cbJobObjectLength, IntPtr lpReturnLength); + internal static bool QueryServiceConfig(NakedWin32Handle hService, out NativeMethods.QUERY_SERVICE_CONFIG configStructure) + { + IntPtr lpBuffer = IntPtr.Zero; + configStructure = default(NativeMethods.QUERY_SERVICE_CONFIG); + DWORD bufferSize, bufferSizeNeeded = 0; + bool status = NativeMethods.QueryServiceConfigW( + hSCManager: hService, + lpServiceConfig: lpBuffer, + cbBufSize: 0, + pcbBytesNeeded: out bufferSizeNeeded); + + if (status != true && Marshal.GetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER) { + return status; + } + + try + { + lpBuffer = Marshal.AllocCoTaskMem((int)bufferSizeNeeded); + bufferSize = bufferSizeNeeded; + + status = NativeMethods.QueryServiceConfigW( + hService, + lpBuffer, + bufferSize, + out bufferSizeNeeded); + configStructure = (NativeMethods.QUERY_SERVICE_CONFIG)Marshal.PtrToStructure(lpBuffer, typeof(NativeMethods.QUERY_SERVICE_CONFIG)); + } + finally + { + Marshal.FreeCoTaskMem(lpBuffer); + } + return status; + } + + internal static bool QueryServiceConfig2(NakedWin32Handle hService, DWORD infolevel, out T configStructure) + { + IntPtr lpBuffer = IntPtr.Zero; + configStructure = default(T); + DWORD bufferSize, bufferSizeNeeded = 0; + + bool status = NativeMethods.QueryServiceConfig2W( + hService: hService, + dwInfoLevel: infolevel, + lpBuffer: lpBuffer, + cbBufSize: 0, + pcbBytesNeeded: out bufferSizeNeeded); + + if (status != true && Marshal.GetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER) { + return status; + } + + try + { + lpBuffer = Marshal.AllocCoTaskMem((int)bufferSizeNeeded); + bufferSize = bufferSizeNeeded; + + status = NativeMethods.QueryServiceConfig2W( + hService, + infolevel, + lpBuffer, + bufferSize, + out bufferSizeNeeded); + configStructure = (T)Marshal.PtrToStructure(lpBuffer, typeof(T)); + } + finally + { + Marshal.FreeCoTaskMem(lpBuffer); + } + return status; + } + /// /// Get appropriate win32 StartupType /// @@ -2472,22 +2747,23 @@ public static extern bool QueryInformationJobObject(SafeHandle hJob, int JobObje /// /// If a supported StartupType is provided, funciton returns true, otherwise false. /// - internal static bool TryGetNativeStartupType(ServiceStartMode StartupType, out DWORD dwStartType) + internal static bool TryGetNativeStartupType(ServiceStartupType StartupType, out DWORD dwStartType) { bool success = true; dwStartType = NativeMethods.SERVICE_NO_CHANGE; switch (StartupType) { - case ServiceStartMode.Automatic: + case ServiceStartupType.Automatic: + case ServiceStartupType.AutomaticDelayedStart: dwStartType = NativeMethods.SERVICE_AUTO_START; break; - case ServiceStartMode.Manual: + case ServiceStartupType.Manual: dwStartType = NativeMethods.SERVICE_DEMAND_START; break; - case ServiceStartMode.Disabled: + case ServiceStartupType.Disabled: dwStartType = NativeMethods.SERVICE_DISABLED; break; - case (ServiceStartMode)(-1): + case ServiceStartupType.InvalidValue: dwStartType = NativeMethods.SERVICE_NO_CHANGE; break; default: @@ -2496,8 +2772,44 @@ internal static bool TryGetNativeStartupType(ServiceStartMode StartupType, out D } return success; } + + internal static ServiceStartupType GetServiceStartupType(ServiceStartMode startMode, bool delayedAutoStart) + { + ServiceStartupType result = ServiceStartupType.Disabled; + switch(startMode) + { + case ServiceStartMode.Automatic: + result = delayedAutoStart ? ServiceStartupType.AutomaticDelayedStart : ServiceStartupType.Automatic; + break; + case ServiceStartMode.Manual: + result = ServiceStartupType.Manual; + break; + case ServiceStartMode.Disabled: + result = ServiceStartupType.Disabled; + break; + } + return result; + } } #endregion NativeMethods + + #region ServiceStartupType + /// + ///Enum for usage with StartupType. Automatic, Manual and Disabled index matched from System.ServiceProcess.ServiceStartMode + /// + public enum ServiceStartupType { + ///Invalid service + InvalidValue = -1, + ///Automatic service + Automatic = 2, + ///Manual service + Manual = 3, + ///Disabled service + Disabled = 4, + ///Automatic (Delayed Start) service + AutomaticDelayedStart = 10 + } + #endregion ServiceStartupType } #endif // Not built on Unix diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/SetClipboardCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/SetClipboardCommand.cs index a59d4a69670..525c4a975c8 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/SetClipboardCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/SetClipboardCommand.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using System.Management.Automation; using System.Collections.Generic; using System.Globalization; diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/SetContentCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/SetContentCommand.cs index e8bde3599c2..5eeaec0a1d8 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/SetContentCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/SetContentCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; using System.Management.Automation.Internal; @@ -28,8 +27,7 @@ public class SetContentCommand : WriteContentCommandBase /// internal override void BeforeOpenStreams(string[] paths) { - if (paths == null || - (paths != null && paths.Length == 0)) + if (paths == null || paths.Length == 0) { throw PSTraceSource.NewArgumentNullException("paths"); } diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/SetPropertyCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/SetPropertyCommand.cs index fa9cbb78d0d..74a1d384150 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/SetPropertyCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/SetPropertyCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; @@ -227,6 +226,5 @@ protected override void ProcessRecord() } // ProcessRecord #endregion Command code - } // SetItemPropertyCommand } // namespace Microsoft.PowerShell.Commands diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/SetWMIInstanceCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/SetWMIInstanceCommand.cs index b507faae72e..94744c03cfe 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/SetWMIInstanceCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/SetWMIInstanceCommand.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/StartTransactionCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/StartTransactionCommand.cs index e758380ce5e..a2eb9469891 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/StartTransactionCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/StartTransactionCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/TestConnectionCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/TestConnectionCommand.cs new file mode 100644 index 00000000000..17acc9b1db0 --- /dev/null +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/TestConnectionCommand.cs @@ -0,0 +1,937 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Management.Automation; +using System.Management.Automation.Internal; +using System.Net; +using System.Net.NetworkInformation; +using System.Net.Sockets; +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.PowerShell.Commands +{ + /// + /// The implementation of the "Test-Connection" cmdlet. + /// + [Cmdlet(VerbsDiagnostic.Test, "Connection", DefaultParameterSetName = ParameterSetPingCount, HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135266")] + [OutputType(typeof(PingReport), ParameterSetName = new string[] { ParameterSetPingCount })] + [OutputType(typeof(PingReply), ParameterSetName = new string[] { ParameterSetPingContinues, ParameterSetDetectionOfMTUSize })] + [OutputType(typeof(Boolean), ParameterSetName = new string[] { ParameterSetPingCount, ParameterSetPingContinues, ParameterSetConnectionByTCPPort })] + [OutputType(typeof(Int32), ParameterSetName = new string[] { ParameterSetDetectionOfMTUSize })] + [OutputType(typeof(TraceRouteReply), ParameterSetName = new string[] { ParameterSetTraceRoute })] + public class TestConnectionCommand : PSCmdlet + { + private const string ParameterSetPingCount = "PingCount"; + private const string ParameterSetPingContinues = "PingContinues"; + private const string ParameterSetTraceRoute = "TraceRoute"; + //private const string ParameterSetPathPing = "PathPing"; + private const string ParameterSetConnectionByTCPPort = "ConnectionByTCPPort"; + //private const string ParameterSetDetectionOfBlackHole = "DetectionOfBlackHole"; + private const string ParameterSetDetectionOfMTUSize = "DetectionOfMTUSize"; + +#region Parameters + + /// + /// Do ping test. + /// + [Parameter(ParameterSetName = ParameterSetPingCount)] + [Parameter(ParameterSetName = ParameterSetPingContinues)] + public SwitchParameter Ping { get; set; } = true; + + /// + /// Force using IPv4 protocol. + /// + [Parameter(ParameterSetName = ParameterSetPingCount)] + [Parameter(ParameterSetName = ParameterSetPingContinues)] + [Parameter(ParameterSetName = ParameterSetTraceRoute)] + [Parameter(ParameterSetName = ParameterSetDetectionOfMTUSize)] + [Parameter(ParameterSetName = ParameterSetConnectionByTCPPort)] + public SwitchParameter IPv4 { get; set; } + + /// + /// Force using IPv6 protocol. + /// + [Parameter(ParameterSetName = ParameterSetPingCount)] + [Parameter(ParameterSetName = ParameterSetPingContinues)] + [Parameter(ParameterSetName = ParameterSetTraceRoute)] + [Parameter(ParameterSetName = ParameterSetDetectionOfMTUSize)] + [Parameter(ParameterSetName = ParameterSetConnectionByTCPPort)] + public SwitchParameter IPv6 { get; set; } + + /// + /// Do reverse DNS lookup to get names for IP addresses. + /// + [Parameter(ParameterSetName = ParameterSetPingCount)] + [Parameter(ParameterSetName = ParameterSetPingContinues)] + [Parameter(ParameterSetName = ParameterSetTraceRoute)] + [Parameter(ParameterSetName = ParameterSetDetectionOfMTUSize)] + [Parameter(ParameterSetName = ParameterSetConnectionByTCPPort)] + public SwitchParameter ResolveDestination { get; set; } + + /// + /// Source from which to do a test (ping, trace route, ...). + /// The default is Local Host. + /// Remoting is not yet implemented internally in the cmdlet. + /// + [Parameter(ParameterSetName = ParameterSetPingCount)] + [Parameter(ParameterSetName = ParameterSetPingContinues)] + [Parameter(ParameterSetName = ParameterSetTraceRoute)] + [Parameter(ParameterSetName = ParameterSetConnectionByTCPPort)] + public string Source { get; } = Dns.GetHostName(); + + /// + /// The number of times the Ping data packets can be forwarded by routers. + /// As gateways and routers transmit packets through a network, + /// they decrement the CurrentMTUSize Time-to-Live (TTL) value found in the packet header. + /// The default (from Windows) is 128 hops. + /// + [Parameter(ParameterSetName = ParameterSetPingCount)] + [Parameter(ParameterSetName = ParameterSetPingContinues)] + [Parameter(ParameterSetName = ParameterSetTraceRoute)] + [ValidateRange(0, sMaxHops)] + [Alias("Ttl")] + public int MaxHops { get; set; } = sMaxHops; + + private const int sMaxHops = 128; + + /// + /// Count of attempts. + /// The default (from Windows) is 4 times. + /// + [Parameter(ParameterSetName = ParameterSetPingCount)] + [ValidateRange(ValidateRangeKind.Positive)] + public int Count { get; set; } = 4; + + /// + /// Delay between attempts. + /// The default (from Windows) is 1 second. + /// + [Parameter(ParameterSetName = ParameterSetPingCount)] + [Parameter(ParameterSetName = ParameterSetPingContinues)] + [ValidateRange(ValidateRangeKind.Positive)] + public int Delay { get; set; } = 1; + + /// + /// Buffer size to send. + /// The default (from Windows) is 32 bites. + /// Max value is 65500 (limit from Windows API). + /// + [Parameter(ParameterSetName = ParameterSetPingCount)] + [Parameter(ParameterSetName = ParameterSetPingContinues)] + [Alias("Size", "Bytes", "BS")] + [ValidateRange(0, 65500)] + public int BufferSize { get; set; } = DefaultSendBufferSize; + + /// + /// Don't fragment ICMP packages. + /// Currently CoreFX not supports this on Unix. + /// + [Parameter(ParameterSetName = ParameterSetPingCount)] + [Parameter(ParameterSetName = ParameterSetPingContinues)] + public SwitchParameter DontFragment { get; set; } + + /// + /// Continue ping until user press Ctrl-C + /// or Int.MaxValue threshold reached. + /// + [Parameter(ParameterSetName = ParameterSetPingContinues)] + public SwitchParameter Continues { get; set; } + + /// + /// Set short output kind ('bool' for Ping, 'int' for MTU size ...). + /// Default is to return typed result object(s). + /// + [Parameter()] + public SwitchParameter Quiet; + + /// + /// Time-out value in seconds. + /// If a response is not received in this time, no response is assumed. + /// It is not the cmdlet timeout! It is a timeout for waiting one ping response. + /// The default (from Windows) is 5 second. + /// + [Parameter()] + [ValidateRange(ValidateRangeKind.Positive)] + public int TimeoutSeconds { get; set; } = 5; + + /// + /// Destination - computer name or IP address. + /// + [Parameter(Mandatory = true, + Position = 0, + ValueFromPipeline = true, + ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + [Alias("ComputerName")] + public string[] TargetName { get; set; } + + /// + /// Detect MTU size. + /// + [Parameter(Mandatory = true, ParameterSetName = ParameterSetDetectionOfMTUSize)] + public SwitchParameter MTUSizeDetect { get; set; } + + /// + /// Do traceroute test. + /// + [Parameter(Mandatory = true, ParameterSetName = ParameterSetTraceRoute)] + public SwitchParameter Traceroute { get; set; } + + /// + /// Do tcp connection test. + /// + [ValidateRange(0, 65535)] + [Parameter(Mandatory = true, ParameterSetName = ParameterSetConnectionByTCPPort)] + public int TCPPort { get; set; } + +#endregion Parameters + + /// + /// Init the cmdlet. + /// + protected override void BeginProcessing() + { + base.BeginProcessing(); + + switch (ParameterSetName) + { + case ParameterSetPingContinues: + Count = int.MaxValue; + break; + } + } + + /// + /// Process a connection test. + /// + protected override void ProcessRecord() + { + foreach (var targetName in TargetName) + { + switch (ParameterSetName) + { + case ParameterSetPingCount: + case ParameterSetPingContinues: + ProcessPing(targetName); + break; + case ParameterSetDetectionOfMTUSize: + ProcessMTUSize(targetName); + break; + case ParameterSetTraceRoute: + ProcessTraceroute(targetName); + break; + case ParameterSetConnectionByTCPPort: + ProcessConnectionByTCPPort(targetName); + break; + } + } + } + +#region ConnectionTest + + private void ProcessConnectionByTCPPort(String targetNameOrAddress) + { + String resolvedTargetName = null; + IPAddress targetAddress = null; + + if (!InitProcessPing(targetNameOrAddress, out resolvedTargetName, out targetAddress)) + { + return; + } + + WriteConnectionTestHeader(resolvedTargetName, targetAddress.ToString()); + + TcpClient client = new TcpClient(); + + try + { + Task connectionTask = client.ConnectAsync(targetAddress, TCPPort); + String targetString = targetAddress.ToString(); + + for (var i=1; i <= TimeoutSeconds; i++) + { + WriteConnectionTestProgress(targetNameOrAddress, targetString, i); + + Task timeoutTask = Task.Delay(millisecondsDelay: 1000); + Task.WhenAny(connectionTask, timeoutTask).Result.Wait(); + + if (timeoutTask.Status == TaskStatus.Faulted || timeoutTask.Status == TaskStatus.Canceled) + { + // Waiting is interrupted by Ctrl-C. + WriteObject(false); + return; + } + + if (connectionTask.Status == TaskStatus.RanToCompletion) + { + WriteObject(true); + return; + } + } + } + catch + { + // Silently ignore connection errors. + } + finally + { + client.Close(); + WriteConnectionTestFooter(); + } + + WriteObject(false); + } + + private void WriteConnectionTestHeader(string resolvedTargetName, string targetAddress) + { + TestConnectionProgressBarActivity = StringUtil.Format(TestConnectionResources.ConnectionTestStart, resolvedTargetName, targetAddress); + ProgressRecord record = new ProgressRecord(s_ProgressId, TestConnectionProgressBarActivity, ProgressRecordSpace); + WriteProgress(record); + } + + private void WriteConnectionTestProgress(string targetNameOrAddress, string targetAddress, int timeout) + { + var msg = StringUtil.Format(TestConnectionResources.ConnectionTestDescription, + targetNameOrAddress, + targetAddress, + timeout); + ProgressRecord record = new ProgressRecord(s_ProgressId, TestConnectionProgressBarActivity, msg); + WriteProgress(record); + } + + private void WriteConnectionTestFooter() + { + ProgressRecord record = new ProgressRecord(s_ProgressId, TestConnectionProgressBarActivity, ProgressRecordSpace); + record.RecordType = ProgressRecordType.Completed; + WriteProgress(record); + } + +#endregion ConnectionTest + +#region TracerouteTest + private void ProcessTraceroute(String targetNameOrAddress) + { + String resolvedTargetName = null; + IPAddress targetAddress = null; + byte[] buffer = GetSendBuffer(BufferSize); + + if (!InitProcessPing(targetNameOrAddress, out resolvedTargetName, out targetAddress)) + { + return; + } + + WriteConsoleTraceRouteHeader(resolvedTargetName, targetAddress.ToString()); + + TraceRouteResult traceRouteResult = new TraceRouteResult(Source, targetAddress, resolvedTargetName); + + Int32 currentHop = 1; + Ping sender = new Ping(); + PingOptions pingOptions = new PingOptions(currentHop, DontFragment.IsPresent); + PingReply reply = null; + Int32 timeout = TimeoutSeconds * 1000; + + do + { + TraceRouteReply traceRouteReply = new TraceRouteReply(); + + pingOptions.Ttl = traceRouteReply.Hop = currentHop; + currentHop++; + + // In the specific case we don't use 'Count' property. + // If we change 'DefaultTraceRoutePingCount' we should change 'ConsoleTraceRouteReply' resource string. + for (int i = 1; i <= DefaultTraceRoutePingCount; i++) + { + + try + { + reply = sender.Send(targetAddress, timeout, buffer, pingOptions); + + traceRouteReply.PingReplies.Add(reply); + } + catch (PingException ex) + { + string message = StringUtil.Format(TestConnectionResources.NoPingResult, + resolvedTargetName, + ex.Message); + Exception pingException = new System.Net.NetworkInformation.PingException(message, ex.InnerException); + ErrorRecord errorRecord = new ErrorRecord(pingException, + TestConnectionExceptionId, + ErrorCategory.ResourceUnavailable, + resolvedTargetName); + WriteError(errorRecord); + + continue; + } + catch + { + // Ignore host resolve exceptions. + } + + // We use short delay because it is impossible DoS with trace route. + Thread.Sleep(200); + } + + if (ResolveDestination && reply.Status == IPStatus.Success) + { + traceRouteReply.ReplyRouterName = Dns.GetHostEntry(reply.Address).HostName; + } + + traceRouteReply.ReplyRouterAddress = reply.Address; + + WriteTraceRouteProgress(traceRouteReply); + + traceRouteResult.Replies.Add(traceRouteReply); + + } while (reply != null && currentHop <= sMaxHops && (reply.Status == IPStatus.TtlExpired || reply.Status == IPStatus.TimedOut)); + + WriteTraceRouteFooter(); + + if (Quiet.IsPresent) + { + WriteObject(currentHop <= sMaxHops); + } + else + { + WriteObject(traceRouteResult); + } + } + + private void WriteConsoleTraceRouteHeader(string resolvedTargetName, string targetAddress) + { + TestConnectionProgressBarActivity = StringUtil.Format(TestConnectionResources.TraceRouteStart, resolvedTargetName, targetAddress, MaxHops); + + WriteInformation(TestConnectionProgressBarActivity, PSHostTag); + + ProgressRecord record = new ProgressRecord(s_ProgressId, TestConnectionProgressBarActivity, ProgressRecordSpace); + WriteProgress(record); + } + + private string TestConnectionProgressBarActivity; + private static string[] PSHostTag = new string[] { "PSHOST" }; + + private void WriteTraceRouteProgress(TraceRouteReply traceRouteReply) + { + String msg = String.Empty; + + if (traceRouteReply.PingReplies[2].Status == IPStatus.TtlExpired || traceRouteReply.PingReplies[2].Status == IPStatus.Success) + { + var routerAddress = traceRouteReply.ReplyRouterAddress.ToString(); + var routerName = traceRouteReply.ReplyRouterName ?? routerAddress; + var roundtripTime0 = traceRouteReply.PingReplies[0].Status == IPStatus.TimedOut ? "*" : traceRouteReply.PingReplies[0].RoundtripTime.ToString(); + var roundtripTime1 = traceRouteReply.PingReplies[1].Status == IPStatus.TimedOut ? "*" : traceRouteReply.PingReplies[1].RoundtripTime.ToString(); + msg = StringUtil.Format(TestConnectionResources.TraceRouteReply, + traceRouteReply.Hop, roundtripTime0, roundtripTime1, traceRouteReply.PingReplies[2].RoundtripTime.ToString(), + routerName, routerAddress); + } + else + { + msg = StringUtil.Format(TestConnectionResources.TraceRouteTimeOut, traceRouteReply.Hop); + } + + WriteInformation(msg, PSHostTag); + + ProgressRecord record = new ProgressRecord(s_ProgressId, TestConnectionProgressBarActivity, msg); + WriteProgress(record); + } + + private void WriteTraceRouteFooter() + { + WriteInformation(TestConnectionResources.TraceRouteComplete, PSHostTag); + + ProgressRecord record = new ProgressRecord(s_ProgressId, TestConnectionProgressBarActivity, ProgressRecordSpace); + record.RecordType = ProgressRecordType.Completed; + WriteProgress(record); + } + + /// + /// The class contains an information about a trace route attempt. + /// + public class TraceRouteReply + { + internal TraceRouteReply() + { + PingReplies = new List(DefaultTraceRoutePingCount); + } + + /// + /// Number of current hop (router). + /// + public int Hop; + + /// + /// List of ping replies for current hop (router). + /// + public List PingReplies; + + /// + /// Router IP address. + /// + public IPAddress ReplyRouterAddress; + + /// + /// Resolved router name. + /// + public String ReplyRouterName; + } + + /// + /// The class contains an information about the source, the destination and trace route results. + /// + public class TraceRouteResult + { + internal TraceRouteResult(string source, IPAddress destinationAddress, string destinationHost) + { + Source = source; + DestinationAddress = destinationAddress; + DestinationHost = destinationHost; + Replies = new List(); + } + + /// + /// Source from which to trace route. + /// + public string Source { get; } + + /// + /// Destination to which to trace route. + /// + public IPAddress DestinationAddress { get; } + + /// + /// Destination to which to trace route. + /// + public string DestinationHost { get; } + + /// + /// + /// + public List Replies { get; } + } + +#endregion TracerouteTest + +#region MTUSizeTest + private void ProcessMTUSize(String targetNameOrAddress) + { + PingReply reply, replyResult = null; + + String resolvedTargetName = null; + IPAddress targetAddress = null; + + if (!InitProcessPing(targetNameOrAddress, out resolvedTargetName, out targetAddress)) + { + return; + } + + WriteMTUSizeHeader(resolvedTargetName, targetAddress.ToString()); + + // Cautious! Algorithm is sensitive to changing boundary values. + int HighMTUSize = 10000; + int CurrentMTUSize = 1473; + int LowMTUSize = targetAddress.AddressFamily == AddressFamily.InterNetworkV6 ? 1280 : 68; + Int32 timeout = TimeoutSeconds * 1000; + + try + { + Ping sender = new Ping(); + PingOptions pingOptions = new PingOptions(MaxHops, true); + int retry = 1; + + while (LowMTUSize < (HighMTUSize-1)) + { + byte[] buffer = GetSendBuffer(CurrentMTUSize); + + WriteMTUSizeProgress(CurrentMTUSize, retry); + + WriteDebug(StringUtil.Format("LowMTUSize: {0}, CurrentMTUSize: {1}, HighMTUSize: {2}", LowMTUSize, CurrentMTUSize, HighMTUSize)); + + reply = sender.Send(targetAddress, timeout, buffer, pingOptions); + + // Cautious! Algorithm is sensitive to changing boundary values. + if (reply.Status == IPStatus.PacketTooBig) + { + HighMTUSize = CurrentMTUSize; + retry = 1; + } + else if (reply.Status == IPStatus.Success) + { + LowMTUSize = CurrentMTUSize; + replyResult = reply; + retry = 1; + } + else + { + // Target host don't reply - try again up to 'Count'. + if (retry >= Count) + { + string message = StringUtil.Format(TestConnectionResources.NoPingResult, + targetAddress, + reply.Status.ToString()); + Exception pingException = new System.Net.NetworkInformation.PingException(message); + ErrorRecord errorRecord = new ErrorRecord(pingException, + TestConnectionExceptionId, + ErrorCategory.ResourceUnavailable, + targetAddress); + WriteError(errorRecord); + return; + } + else + { + retry++; + continue; + } + } + + CurrentMTUSize = (LowMTUSize + HighMTUSize) /2; + + // Prevent DoS attack. + Thread.Sleep(100); + } + } + catch (PingException ex) + { + string message = StringUtil.Format(TestConnectionResources.NoPingResult, targetAddress, ex.Message); + Exception pingException = new System.Net.NetworkInformation.PingException(message, ex.InnerException); + ErrorRecord errorRecord = new ErrorRecord(pingException, + TestConnectionExceptionId, + ErrorCategory.ResourceUnavailable, + targetAddress); + WriteError(errorRecord); + return; + } + + WriteMTUSizeFooter(); + + if (Quiet.IsPresent) + { + WriteObject(CurrentMTUSize); + } + else + { + var res = PSObject.AsPSObject(replyResult); + + PSMemberInfo sourceProperty = new PSNoteProperty("Source", Source); + res.Members.Add(sourceProperty); + PSMemberInfo destinationProperty = new PSNoteProperty("Destination", targetNameOrAddress); + res.Members.Add(destinationProperty); + PSMemberInfo mtuSizeProperty = new PSNoteProperty("MTUSize", CurrentMTUSize); + res.Members.Add(mtuSizeProperty); + res.TypeNames.Insert(0, "PingReply#MTUSize"); + + WriteObject(res); + } + } + + private void WriteMTUSizeHeader(string resolvedTargetName, string targetAddress) + { + TestConnectionProgressBarActivity = StringUtil.Format(TestConnectionResources.MTUSizeDetectStart, + resolvedTargetName, + targetAddress, + BufferSize); + + ProgressRecord record = new ProgressRecord(s_ProgressId, TestConnectionProgressBarActivity, ProgressRecordSpace); + WriteProgress(record); + } + + private void WriteMTUSizeProgress(int currentMTUSize, int retry) + { + var msg = StringUtil.Format(TestConnectionResources.MTUSizeDetectDescription, currentMTUSize, retry); + + ProgressRecord record = new ProgressRecord(s_ProgressId, TestConnectionProgressBarActivity, msg); + WriteProgress(record); + } + + private void WriteMTUSizeFooter() + { + ProgressRecord record = new ProgressRecord(s_ProgressId, TestConnectionProgressBarActivity, ProgressRecordSpace); + record.RecordType = ProgressRecordType.Completed; + WriteProgress(record); + } + +#endregion MTUSizeTest + +#region PingTest + + private void ProcessPing(String targetNameOrAddress) + { + String resolvedTargetName = null; + IPAddress targetAddress = null; + + if (!InitProcessPing(targetNameOrAddress, out resolvedTargetName, out targetAddress)) + { + return; + } + + if (!Continues.IsPresent) + { + WritePingHeader(resolvedTargetName, targetAddress.ToString()); + } + + bool quietResult = true; + byte[] buffer = GetSendBuffer(BufferSize); + + Ping sender = new Ping(); + PingOptions pingOptions = new PingOptions(MaxHops, DontFragment.IsPresent); + PingReply reply = null; + PingReport pingReport = new PingReport(Source, resolvedTargetName); + Int32 timeout = TimeoutSeconds * 1000; + Int32 delay = Delay * 1000; + + for (int i = 1; i <= Count; i++) + { + try + { + reply = sender.Send(targetAddress, timeout, buffer, pingOptions); + } + catch (PingException ex) + { + string message = StringUtil.Format(TestConnectionResources.NoPingResult, resolvedTargetName, ex.Message); + Exception pingException = new System.Net.NetworkInformation.PingException(message, ex.InnerException); + ErrorRecord errorRecord = new ErrorRecord(pingException, + TestConnectionExceptionId, + ErrorCategory.ResourceUnavailable, + resolvedTargetName); + WriteError(errorRecord); + + quietResult = false; + continue; + } + + if (Continues.IsPresent) + { + WriteObject(reply); + } + else + { + if (Quiet.IsPresent) + { + // Return 'true' only if all pings have completed successfully. + quietResult &= reply.Status == IPStatus.Success; + } + else + { + pingReport.Replies.Add(reply); + } + + WritePingProgress(reply); + } + + // Delay between ping but not after last ping. + if (i < Count && Delay > 0) + { + Thread.Sleep(delay); + } + } + + if (!Continues.IsPresent) + { + WritePingFooter(); + } + + if (Quiet.IsPresent) + { + WriteObject(quietResult); + } + else + { + WriteObject(pingReport); + } + } + + private void WritePingHeader(string resolvedTargetName, string targetAddress) + { + TestConnectionProgressBarActivity = StringUtil.Format(TestConnectionResources.MTUSizeDetectStart, + resolvedTargetName, + targetAddress, + BufferSize); + + WriteInformation(TestConnectionProgressBarActivity, PSHostTag); + + ProgressRecord record = new ProgressRecord(s_ProgressId, + TestConnectionProgressBarActivity, + ProgressRecordSpace); + WriteProgress(record); + } + + private void WritePingProgress(PingReply reply) + { + String msg = String.Empty; + if (reply.Status != IPStatus.Success) + { + msg = TestConnectionResources.PingTimeOut; + } + else + { + msg = StringUtil.Format(TestConnectionResources.PingReply, + reply.Address.ToString(), + reply.Buffer.Length, + reply.RoundtripTime, + reply.Options?.Ttl); + } + + WriteInformation(msg, PSHostTag); + + ProgressRecord record = new ProgressRecord(s_ProgressId, TestConnectionProgressBarActivity, msg); + WriteProgress(record); + } + + private void WritePingFooter() + { + WriteInformation(TestConnectionResources.PingComplete, PSHostTag); + + ProgressRecord record = new ProgressRecord(s_ProgressId, TestConnectionProgressBarActivity, ProgressRecordSpace); + record.RecordType = ProgressRecordType.Completed; + WriteProgress(record); + } + + /// + /// The class contains an information about the source, the destination and ping results. + /// + public class PingReport + { + internal PingReport(string source, string destination) + { + Source = source; + Destination = destination; + Replies = new List(); + } + + /// + /// Source from which to ping. + /// + public string Source { get; } + + /// + /// Destination to which to ping. + /// + public string Destination { get; } + + /// + /// Ping results for every ping attempt. + /// + public List Replies { get; } + } + +#endregion PingTest + + private bool InitProcessPing(String targetNameOrAddress, out String resolvedTargetName, out IPAddress targetAddress) + { + IPHostEntry hostEntry = null; + + resolvedTargetName = targetNameOrAddress; + + if (IPAddress.TryParse(targetNameOrAddress, out targetAddress)) + { + if (ResolveDestination) + { + hostEntry = Dns.GetHostEntry(targetNameOrAddress); + resolvedTargetName = hostEntry.HostName; + } + } + else + { + try + { + hostEntry = Dns.GetHostEntry(targetNameOrAddress); + + if (ResolveDestination) + { + resolvedTargetName = hostEntry.HostName; + hostEntry = Dns.GetHostEntry(hostEntry.HostName); + } + } + catch (Exception ex) + { + string message = StringUtil.Format(TestConnectionResources.NoPingResult, + resolvedTargetName, + TestConnectionResources.CannotResolveTargetName); + Exception pingException = new System.Net.NetworkInformation.PingException(message, ex); + ErrorRecord errorRecord = new ErrorRecord(pingException, + TestConnectionExceptionId, + ErrorCategory.ResourceUnavailable, + resolvedTargetName); + WriteError(errorRecord); + return false; + } + + if (IPv6 || IPv4) + { + AddressFamily addressFamily = IPv6 ? AddressFamily.InterNetworkV6 :AddressFamily.InterNetwork; + + foreach(var address in hostEntry.AddressList) + { + if (address.AddressFamily == addressFamily) + { + targetAddress = address; + break; + } + } + + if (targetAddress == null) + { + string message = StringUtil.Format(TestConnectionResources.NoPingResult, + resolvedTargetName, + TestConnectionResources.TargetAddressAbsent); + Exception pingException = new System.Net.NetworkInformation.PingException(message, null); + ErrorRecord errorRecord = new ErrorRecord(pingException, + TestConnectionExceptionId, + ErrorCategory.ResourceUnavailable, + resolvedTargetName); + WriteError(errorRecord); + return false; + } + } + else + { + targetAddress = hostEntry.AddressList[0]; + } + } + + return true; + } + + // Users most often use the default buffer size so we cache the buffer. + // Creates and filles a send buffer. This follows the ping.exe and CoreFX model. + private byte[] GetSendBuffer(int bufferSize) + { + if (bufferSize == DefaultSendBufferSize && s_DefaultSendBuffer != null) + { + return s_DefaultSendBuffer; + } + + byte[] sendBuffer = new byte[bufferSize]; + + for (int i = 0; i < bufferSize; i++) + { + sendBuffer[i] = (byte)((int)'a' + i % 23); + } + + if (bufferSize == DefaultSendBufferSize && s_DefaultSendBuffer == null) + { + s_DefaultSendBuffer= sendBuffer; + } + + return sendBuffer; + } + + // Count of pings sent per each trace route hop. + // Default = 3 (from Windows). + // If we change 'DefaultTraceRoutePingCount' we should change 'ConsoleTraceRouteReply' resource string. + private const int DefaultTraceRoutePingCount = 3; + + /// Create the default send buffer once and cache it. + private const int DefaultSendBufferSize = 32; + private static byte[] s_DefaultSendBuffer= null; + + // Random value for WriteProgress Activity Id. + private static readonly int s_ProgressId = 174593053; + + // Empty message string for Progress Bar. + private const string ProgressRecordSpace = " "; + + private const string TestConnectionExceptionId = "TestConnectionException"; + } +} diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/TimeZoneCommands.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/TimeZoneCommands.cs index 75b41682981..42c54f74caa 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/TimeZoneCommands.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/TimeZoneCommands.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -665,7 +668,6 @@ public struct TIME_ZONE_INFORMATION [return: MarshalAs(UnmanagedType.Bool)] public static extern bool PrivilegeCheck(IntPtr ClientToken, ref PRIVILEGE_SET RequiredPrivileges, ref bool pfResult); - /// /// PInvoke AdjustTokenPrivilege API /// diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/UseTransactionCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/UseTransactionCommand.cs index b65f46412c7..43b722d08f7 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/UseTransactionCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/UseTransactionCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/WMIHelper.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/WMIHelper.cs index bef805293b0..91abff494e7 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/WMIHelper.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/WMIHelper.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Globalization; @@ -1018,7 +1017,6 @@ internal static string GetScopeString(string computer, string namespaceParameter } #endregion Helper Classes - /// /// A class to set WMI connection options /// @@ -1708,8 +1706,6 @@ private void HandleJobUnblocked(object sender, EventArgs eventArgs) } } - - private ThrottleManager _throttleManager = new ThrottleManager(); private object _syncObject = new object(); // sync object @@ -1783,7 +1779,6 @@ internal PSWmiChildJob(Cmdlet cmds, string computerName, ThrottleManager throttl private bool _bJobFailed; private bool _bAtLeastOneObject; - private ArrayList _wmiSinkArray; /// /// Event raised by this job to indicate to its parent that @@ -1884,7 +1879,6 @@ private void JobDoneForWin32Shutdown(object sender, EventArgs arg) /// public override string StatusMessage { get; } = "test"; - /// /// Indicates if there is more data available in /// this Job diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/WebServiceProxy.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/WebServiceProxy.cs index 30837a5c4a1..84d966e9094 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/WebServiceProxy.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/WebServiceProxy.cs @@ -1,6 +1,5 @@ -/********************************************************************-- -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.IO; @@ -27,7 +26,6 @@ using Microsoft.Win32; using System.Text.RegularExpressions; - namespace Microsoft.PowerShell.Commands { #region New-WebServiceProxy @@ -105,7 +103,6 @@ public PSCredential Credential } private PSCredential _credential; - /// /// use default credential.. /// @@ -150,7 +147,7 @@ public SwitchParameter UseDefaultCredential /// protected override void BeginProcessing() { - if (_uri.ToString().Trim().Length == 0) + if (string.IsNullOrWhiteSpace(_uri.ToString())) { Exception ex = new ArgumentException(WebServiceResources.InvalidUri); ErrorRecord er = new ErrorRecord(ex, "ArgumentException", ErrorCategory.InvalidOperation, null); diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/WriteContentCommandBase.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/WriteContentCommandBase.cs index 20fdab66dcf..eb2731450ca 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/WriteContentCommandBase.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/WriteContentCommandBase.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections; diff --git a/src/Microsoft.PowerShell.Commands.Management/resources/CmdletizationResources.resx b/src/Microsoft.PowerShell.Commands.Management/resources/CmdletizationResources.resx index 1a25e938a38..15bfadffe7b 100644 --- a/src/Microsoft.PowerShell.Commands.Management/resources/CmdletizationResources.resx +++ b/src/Microsoft.PowerShell.Commands.Management/resources/CmdletizationResources.resx @@ -124,10 +124,6 @@ {1} is a placeholder for a server name. Example: "localhost". - - ..\..\..\..\src\cimSupport\cmdletization\xml\cmdlets-over-objects.xsd;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 - {Locked} - CIM method {1} on the {0} CIM object {0} is a placeholder for a CIM path. Example: \\SERVER1\ROOT\cimv2:Win32_Process.Handle="11828" diff --git a/src/Microsoft.PowerShell.Commands.Management/resources/ComputerResources.resx b/src/Microsoft.PowerShell.Commands.Management/resources/ComputerResources.resx index f295fed1f2e..63a671c0248 100644 --- a/src/Microsoft.PowerShell.Commands.Management/resources/ComputerResources.resx +++ b/src/Microsoft.PowerShell.Commands.Management/resources/ComputerResources.resx @@ -153,9 +153,6 @@ The command cannot locate the "{0}" restore point. Verify the "{0}" sequence number, and then try the command again. - - Testing connection to computer '{0}' failed: {1} - {0} ({1}) @@ -357,18 +354,6 @@ The computer {0} is skipped. Fail to retrieve its LastBootUpTime via the WMI service with the following error message: {1}. - - Parameter WsmanAuthentication should not be specified when the DCOM protocol is in use. {0} - - - Parameters DcomAuthentication and Impersonation should not be specified when the WSMan protocol is in use. {0} - - - Parameter WsmanAuthentication should not be specified with DcomAuthentication and Impersonation at the same time. {0} - - - Parameter WsmanAuthentication is valid only if the WSMan protocol is used. Parameters DcomAuthentication (Authentication) and Impersonation are valid only if the DCOM protocol is used. - Cannot verify the secure channel for the local computer. Operation failed with the following exception: {0}. @@ -396,24 +381,6 @@ Cannot validate the time interval for restore point creation. It failed to retrieve the last restore point with the following error message: {0}. - - Parameter WsmanAuthentication cannot be specified with the DCOM protocol. Parameter WSManAuthentication is valid only when the WSMan protocol is used. - - - Parameters DcomAuthentication and Impersonation cannot be specified with the WSMan protocol. {0} - - - Parameter WsmanAuthentication is valid only when the WSMan protocol is used. Parameters DcomAuthentication and Impersonation are valid only when the DCOM protocol is used. - - - Parameter WsmanAuthentication cannot be specified with DcomAuthentication or Impersonation parameters. {0} - - - Parameter WsmanAuthentication cannot be specified with the DCOM protocol. {0} - - - DcomAuthentication is not supported. Please use WsmanAuthentication instead. - The AsJob Parameter Set is not supported. diff --git a/src/Microsoft.PowerShell.Commands.Management/resources/ServiceResources.resx b/src/Microsoft.PowerShell.Commands.Management/resources/ServiceResources.resx index 4a1aa45ee7d..6218714a18c 100644 --- a/src/Microsoft.PowerShell.Commands.Management/resources/ServiceResources.resx +++ b/src/Microsoft.PowerShell.Commands.Management/resources/ServiceResources.resx @@ -162,15 +162,24 @@ Service '{1} ({0})' cannot be configured due to the following error: {2} + + Service '{1} ({0})' cannot be queried due to the following error: {2} + Service '{1} ({0})' description cannot be configured due to the following error: {2} + + Service '{1} ({0})' automatic (delayed start) cannot be configured due to the following error: {2} + Service '{1} ({0})' cannot be created due to the following error: {2} Service '{1} ({0})' was created, but its description cannot be configured due to the following error: {2} + + Service '{1} ({0})' was created, but its StartupType 'Automatic (Delayed Start)' could not be configured due to the following error: {2} + Service '{1} ({0})' cannot be removed due to the following error: {2} diff --git a/src/Microsoft.PowerShell.Commands.Management/resources/TestConnectionResources.resx b/src/Microsoft.PowerShell.Commands.Management/resources/TestConnectionResources.resx new file mode 100644 index 00000000000..794680166cc --- /dev/null +++ b/src/Microsoft.PowerShell.Commands.Management/resources/TestConnectionResources.resx @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tracing route to {0} [{1}] over a maximum of {2} hops: + + + {0,3} {1} ms {2} ms {3} ms {4} [{5}] + + + {0,3} * ms * ms * ms Request timed out. + + + Trace complete. + + + Trying to connect to {0} [{1}]: + + + Target: {0} [{1}]. Seconds: {2} + + + Pinging {0} [{1}] with {2} bytes of data: + + + MTU size: {0}. Attempt: {1} + + + Testing connection to computer '{0}' failed: {1} + + + Cannot resolve the target name. + + + Target IPv4/IPv6 address absent. + + + Pinging {0} [{1}] with {2} bytes of data: + + + Request timed out. + + + Reply from {0}: bytes={1} time={2}ms TTL={3} + + + Ping complete. + + diff --git a/src/Microsoft.PowerShell.Commands.Management/singleshell/installer/MshManagementMshSnapin.cs b/src/Microsoft.PowerShell.Commands.Management/singleshell/installer/MshManagementMshSnapin.cs index 0796cb0bf9c..06661bb6b2a 100644 --- a/src/Microsoft.PowerShell.Commands.Management/singleshell/installer/MshManagementMshSnapin.cs +++ b/src/Microsoft.PowerShell.Commands.Management/singleshell/installer/MshManagementMshSnapin.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.ComponentModel; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj index 33741706393..1c5919dfa18 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj +++ b/src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj @@ -77,7 +77,8 @@ - + + diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddMember.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddMember.cs index ca2aa30235f..87395206242 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddMember.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddMember.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections; @@ -132,7 +131,6 @@ public SwitchParameter PassThru get { return _passThru; } } - #region Simplifying NoteProperty Declaration private const string NotePropertySingleMemberSet = "NotePropertySingleMemberSet"; @@ -180,7 +178,6 @@ public IDictionary NotePropertyMembers #endregion Simplifying NoteProperty Declaration - private static object GetParameterType(object sourceValue, Type destinationType) { return LanguagePrimitives.ConvertTo(sourceValue, destinationType, CultureInfo.InvariantCulture); @@ -514,7 +511,7 @@ private void UpdateTypeNames() private ErrorRecord NewError(string errorId, string resourceId, object targetObject, params object[] args) { ErrorDetails details = new ErrorDetails(this.GetType().GetTypeInfo().Assembly, - "AddMember", resourceId, args); + "Microsoft.PowerShell.Commands.Utility.resources.AddMember", resourceId, args); ErrorRecord errorRecord = new ErrorRecord( new InvalidOperationException(details.Message), errorId, diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs index a71101f269e..9234ba97083 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs @@ -1,30 +1,26 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - -#region Using directives +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; using System.Globalization; +using System.IO; using System.Linq; using System.Management.Automation; using System.Management.Automation.Internal; using System.Reflection; +using System.Security; using System.Text; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; -using System.IO; using Microsoft.CodeAnalysis.Emit; -using System.Collections.Immutable; -using System.Security; -using PathType = System.IO.Path; -#endregion +using PathType = System.IO.Path; namespace Microsoft.PowerShell.Commands { @@ -35,73 +31,33 @@ namespace Microsoft.PowerShell.Commands public enum Language { /// - /// The C# programming language: latest version. + /// The C# programming language. /// CSharp, /// - /// The C# programming language v7 - /// - CSharpVersion7, - - /// - /// The C# programming language v6 - /// - CSharpVersion6, - - /// - /// The C# programming language v5 - /// - CSharpVersion5, - - /// - /// The C# programming language v4 - /// - CSharpVersion4, - - /// - /// The C# programming language v3 (for Linq, etc) - /// - CSharpVersion3, - - /// - /// The C# programming language v2 - /// - CSharpVersion2, - - /// - /// The C# programming language v1 - /// - CSharpVersion1, - - /// - /// The Visual Basic programming language - /// - VisualBasic, - - /// - /// The Managed JScript programming language + /// The Visual Basic programming language. /// - JScript, + VisualBasic } /// - /// Types supported for the OutputAssembly parameter + /// Types supported for the OutputAssembly parameter. /// public enum OutputAssemblyType { /// - /// A Dynamically linked library (DLL) + /// A Dynamically linked library (DLL). /// Library, /// - /// An executable application that targets the console subsystem + /// An executable application that targets the console subsystem. /// ConsoleApplication, /// - /// An executable application that targets the graphical subsystem + /// An executable application that targets the graphical subsystem. /// WindowsApplication } @@ -143,14 +99,17 @@ public class AddTypeCompilerError } /// - /// Base class that contains logic for Add-Type cmdlet based on - /// - CodeDomProvider - /// - CodeAnalysis(Roslyn) + /// Adds a new type to the Application Domain. + /// This version is based on CodeAnalysis (Roslyn). /// - public abstract class AddTypeCommandBase : PSCmdlet + [Cmdlet(VerbsCommon.Add, "Type", DefaultParameterSetName = "FromSource", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135195")] + [OutputType(typeof(Type))] + public sealed class AddTypeCommand : PSCmdlet { + #region Parameters + /// - /// The source code of this type + /// The source code of this type. /// [Parameter(Mandatory = true, Position = 0, ParameterSetName = "FromSource")] public String TypeDefinition @@ -166,13 +125,13 @@ public String TypeDefinition } /// - /// The name of the type used for auto-generated types + /// The name of the type used for auto-generated types. /// [Parameter(Mandatory = true, Position = 0, ParameterSetName = "FromMember")] public String Name { get; set; } /// - /// The source code of this method / member + /// The source code of this method / member. /// [Parameter(Mandatory = true, Position = 1, ParameterSetName = "FromMember")] [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] @@ -188,19 +147,15 @@ public String[] MemberDefinition if (value != null) { - for (int counter = 0; counter < value.Length; counter++) - { - sourceCode += value[counter] + "\n"; - } + sourceCode = String.Join("\n", value); } } } internal String sourceCode; - /// - /// The namespaced used for the auto-generated type + /// The namespaced used for the auto-generated type. /// [Parameter(ParameterSetName = "FromMember")] [Alias("NS")] @@ -213,26 +168,22 @@ public String Namespace } set { - typeNamespace = value; - if (typeNamespace != null) - { - typeNamespace = typeNamespace.Trim(); - } + typeNamespace = value?.Trim(); } } + internal string typeNamespace = "Microsoft.PowerShell.Commands.AddType.AutoGeneratedTypes"; /// - /// Any using statements required by the auto-generated type + /// Any using statements required by the auto-generated type. /// [Parameter(ParameterSetName = "FromMember")] [Alias("Using")] [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public String[] UsingNamespace { get; set; } = Utils.EmptyArray(); - /// - /// The path to the source code or DLL to load + /// The path to the source code or DLL to load. /// [Parameter(Mandatory = true, Position = 0, ParameterSetName = "FromPath")] [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] @@ -278,7 +229,7 @@ public string[] Path } /// - /// The literal path to the source code or DLL to load + /// The literal path to the source code or DLL to load. /// [Parameter(Mandatory = true, ParameterSetName = "FromLiteralPath")] [Alias("PSPath")] @@ -331,10 +282,6 @@ private void ProcessPaths(List resolvedPaths) Language = Language.VisualBasic; break; - case ".JS": - Language = Language.JScript; - break; - case ".DLL": loadAssembly = true; break; @@ -377,7 +324,7 @@ private void ProcessPaths(List resolvedPaths) internal string[] paths; /// - /// The name of the assembly to load + /// The name of the assembly to load. /// [Parameter(Mandatory = true, ParameterSetName = "FromAssemblyName")] [Alias("AN")] @@ -396,45 +343,17 @@ public String[] AssemblyName } internal String[] assemblyNames; - internal bool loadAssembly = false; - /// - /// The language used to generate source code + /// The language used to generate source code. /// [Parameter(ParameterSetName = "FromSource")] [Parameter(ParameterSetName = "FromMember")] - public Language Language - { - get - { - return language; - } - set - { - language = value; - languageSpecified = true; - - PostSetLanguage(language); - } - } + public Language Language { get; set; } = Language.CSharp; /// - /// Post-action for Language setter. - /// - /// - internal virtual void PostSetLanguage(Language language) - { - } - - - internal bool languageSpecified = false; - internal Language language = Language.CSharp; - - - /// - /// Any reference DLLs to use in the compilation + /// Any reference DLLs to use in the compilation. /// [Parameter(ParameterSetName = "FromSource")] [Parameter(ParameterSetName = "FromMember")] @@ -453,7 +372,7 @@ public String[] ReferencedAssemblies internal string[] referencedAssemblies = Utils.EmptyArray(); /// - /// The path to the output assembly + /// The path to the output assembly. /// [Parameter(ParameterSetName = "FromSource")] [Parameter(ParameterSetName = "FromMember")] @@ -533,7 +452,7 @@ public string OutputAssembly internal string outputAssembly = null; /// - /// The output type of the assembly + /// The output type of the assembly. /// [Parameter(ParameterSetName = "FromSource")] [Parameter(ParameterSetName = "FromMember")] @@ -555,42 +474,21 @@ public OutputAssemblyType OutputType internal OutputAssemblyType outputType = OutputAssemblyType.Library; internal bool outputTypeSpecified = false; - /// - /// Flag to pass the resulting types along + /// Flag to pass the resulting types along. /// [Parameter()] - public SwitchParameter PassThru - { - get - { - return passThru; - } - set - { - passThru = value; - } - } - internal SwitchParameter passThru; + public SwitchParameter PassThru { get; set; } /// - /// Flag to ignore warnings during compilation + /// Flag to ignore warnings during compilation. /// [Parameter()] - public SwitchParameter IgnoreWarnings - { - get - { - return ignoreWarnings; - } - set - { - ignoreWarnings = value; - ignoreWarningsSpecified = true; - } - } - internal bool ignoreWarningsSpecified; - internal SwitchParameter ignoreWarnings; + public SwitchParameter IgnoreWarnings { get; set; } + + #endregion Parameters + + #region GererateSource internal string GenerateTypeSource(string typeNamespace, string name, string sourceCode, Language language) { @@ -614,38 +512,17 @@ internal string GenerateTypeSource(string typeNamespace, string name, string sou } } - internal bool IsCSharp(Language language) - { - switch (language) - { - case Language.CSharp: - case Language.CSharpVersion2: - case Language.CSharpVersion3: - case Language.CSharpVersion1: - case Language.CSharpVersion4: - case Language.CSharpVersion5: - case Language.CSharpVersion6: - case Language.CSharpVersion7: - return true; - default: - return false; - } - } - // Get the -FromMember template for a given language - internal string GetMethodTemplate(Language language) + private string GetMethodTemplate(Language language) { - if (IsCSharp(language)) - { - return - " public class {0}\n" + - " {{\n" + - " {1}\n" + - " }}\n"; - } - switch (language) { + case Language.CSharp: + return + " public class {0}\n" + + " {{\n" + + " {1}\n" + + " }}\n"; case Language.VisualBasic: return " public Class {0}\n" + @@ -653,163 +530,89 @@ internal string GetMethodTemplate(Language language) " {1}\n" + " \n" + " End Class\n"; - case Language.JScript: - return - " public class {0}\n" + - " {{\n" + - " {1}\n" + - " }}\n"; } + + Diagnostics.Assert(false, "GetMethodTemplate: Unsupported language family."); + return null; } // Get the -FromMember namespace template for a given language - internal string GetNamespaceTemplate(Language language) + private string GetNamespaceTemplate(Language language) { - if (IsCSharp(language)) - { - return - "namespace {0}\n" + - "{{\n" + - "{1}\n" + - "}}\n"; - } - switch (language) { + case Language.CSharp: + return + "namespace {0}\n" + + "{{\n" + + "{1}\n" + + "}}\n"; case Language.VisualBasic: return "Namespace {0}\n" + "\n" + "{1}\n" + "End Namespace\n"; - case Language.JScript: - return - "package {0}\n" + - "{{\n" + - "{1}\n" + - "}}\n"; } + + Diagnostics.Assert(false, "GetNamespaceTemplate: Unsupported language family."); + return null; } // Get the -FromMember namespace template for a given language - internal string GetUsingTemplate(Language language) + private string GetUsingTemplate(Language language) { - if (IsCSharp(language)) - { - return - "using System;\n" + - "using System.Runtime.InteropServices;\n" + - "{0}" + - "\n"; - } - switch (language) { - case Language.VisualBasic: + case Language.CSharp: return - "Imports System\n" + - "Imports System.Runtime.InteropServices\n" + + "using System;\n" + + "using System.Runtime.InteropServices;\n" + "{0}" + "\n"; - case Language.JScript: + case Language.VisualBasic: return - "import System;\n" + - "import System.Runtime.InteropServices;\n" + + "Imports System\n" + + "Imports System.Runtime.InteropServices\n" + "{0}" + "\n"; } + + Diagnostics.Assert(false, "GetUsingTemplate: Unsupported language family."); + return null; } // Generate the code for the using statements - internal string GetUsingSet(Language language) + private string GetUsingSet(Language language) { StringBuilder usingNamespaceSet = new StringBuilder(); - if (IsCSharp(language)) - { - foreach (string namespaceValue in UsingNamespace) - { - usingNamespaceSet.Append("using " + namespaceValue + ";\n"); - } - } - else - { - switch (language) - { - case Language.VisualBasic: - foreach (string namespaceValue in UsingNamespace) - { - usingNamespaceSet.Append("Imports " + namespaceValue + "\n"); - } - break; - case Language.JScript: - foreach (string namespaceValue in UsingNamespace) - { - usingNamespaceSet.Append("import " + namespaceValue + ";\n"); - } - break; - } - } - - return usingNamespaceSet.ToString(); - } - - /// - /// Perform common error checks. - /// Populate source code. - /// - protected override void EndProcessing() - { - // Generate an error if they've specified an output - // assembly type without an output assembly - if (String.IsNullOrEmpty(outputAssembly) && outputTypeSpecified) + switch (language) { - ErrorRecord errorRecord = new ErrorRecord( - new Exception( - String.Format( - CultureInfo.CurrentCulture, - AddTypeStrings.OutputTypeRequiresOutputAssembly)), - "OUTPUTTYPE_REQUIRES_ASSEMBLY", - ErrorCategory.InvalidArgument, - outputType); - - ThrowTerminatingError(errorRecord); - return; + case Language.CSharp: + foreach (string namespaceValue in UsingNamespace) + { + usingNamespaceSet.Append("using " + namespaceValue + ";\n"); + } + break; + case Language.VisualBasic: + foreach (string namespaceValue in UsingNamespace) + { + usingNamespaceSet.Append("Imports " + namespaceValue + "\n"); + } + break; + default: + Diagnostics.Assert(false, "GetUsingSet: Unsupported language family."); + break; } - PopulateSource(); + return usingNamespaceSet.ToString(); } - internal void PopulateSource() - { - // Prevent code compilation in ConstrainedLanguage mode - if (SessionState.LanguageMode == PSLanguageMode.ConstrainedLanguage) - { - ThrowTerminatingError( - new ErrorRecord( - new PSNotSupportedException(AddTypeStrings.CannotDefineNewType), "CannotDefineNewType", ErrorCategory.PermissionDenied, null)); - } - - // Load the source if they want to load from a file - if (String.Equals(ParameterSetName, "FromPath", StringComparison.OrdinalIgnoreCase) || - String.Equals(ParameterSetName, "FromLiteralPath", StringComparison.OrdinalIgnoreCase) - ) - { - sourceCode = ""; - foreach (string file in paths) - { - sourceCode += System.IO.File.ReadAllText(file) + "\n"; - } - } - - if (String.Equals(ParameterSetName, "FromMember", StringComparison.OrdinalIgnoreCase)) - { - sourceCode = GenerateTypeSource(typeNamespace, Name, sourceCode, language); - } - } + #endregion GererateSource internal void HandleCompilerErrors(AddTypeCompilerError[] compilerErrors) { @@ -853,12 +656,12 @@ private void OutputError(AddTypeCompilerError error, string[] actualSource) { if (!String.IsNullOrEmpty(error.FileName)) { - actualSource = System.IO.File.ReadAllText(error.FileName).Split(Utils.Separators.Newline); + actualSource = System.IO.File.ReadAllLines(error.FileName); } } string errorText = StringUtil.Format(AddTypeStrings.CompilationErrorFormat, - error.FileName, error.Line, error.ErrorText) + "\n"; + error.FileName, error.Line, error.ErrorText) + Environment.NewLine; for (int lineNumber = error.Line - 1; lineNumber < error.Line + 2; lineNumber++) { @@ -876,8 +679,8 @@ private void OutputError(AddTypeCompilerError error, string[] actualSource) lineText += actualSource[lineNumber - 1]; - errorText += "\n" + StringUtil.Format(AddTypeStrings.CompilationErrorFormat, - error.FileName, lineNumber, lineText) + "\n"; + errorText += Environment.NewLine + StringUtil.Format(AddTypeStrings.CompilationErrorFormat, + error.FileName, lineNumber, lineText) + Environment.NewLine; } } @@ -896,24 +699,38 @@ private void OutputError(AddTypeCompilerError error, string[] actualSource) WriteError(errorRecord); } } - } - /// - /// Adds a new type to the Application Domain. - /// This version is based on CodeAnalysis (Roslyn). - /// - [Cmdlet(VerbsCommon.Add, "Type", DefaultParameterSetName = "FromSource", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135195")] - [OutputType(typeof(Type))] - public sealed class AddTypeCommand : AddTypeCommandBase - { private static Dictionary s_sourceCache = new Dictionary(); /// - /// Generate the type(s) + /// Generate the type(s). /// protected override void EndProcessing() { - base.EndProcessing(); + // Prevent code compilation in ConstrainedLanguage mode + if (SessionState.LanguageMode == PSLanguageMode.ConstrainedLanguage) + { + ThrowTerminatingError( + new ErrorRecord( + new PSNotSupportedException(AddTypeStrings.CannotDefineNewType), "CannotDefineNewType", ErrorCategory.PermissionDenied, null)); + } + + // Generate an error if they've specified an output + // assembly type without an output assembly + if (String.IsNullOrEmpty(outputAssembly) && outputTypeSpecified) + { + ErrorRecord errorRecord = new ErrorRecord( + new Exception( + String.Format( + CultureInfo.CurrentCulture, + AddTypeStrings.OutputTypeRequiresOutputAssembly)), + "OUTPUTTYPE_REQUIRES_ASSEMBLY", + ErrorCategory.InvalidArgument, + outputType); + + ThrowTerminatingError(errorRecord); + return; + } if (loadAssembly) { @@ -932,14 +749,36 @@ protected override void EndProcessing() { // Load the source if they want to load from a file if (String.Equals(ParameterSetName, "FromPath", StringComparison.OrdinalIgnoreCase) || - String.Equals(ParameterSetName, "FromLiteralPath", StringComparison.OrdinalIgnoreCase)) + String.Equals(ParameterSetName, "FromLiteralPath", StringComparison.OrdinalIgnoreCase) + ) { - this.sourceCode = ""; - foreach (string file in paths) + if (paths.Length == 1) + { + sourceCode = File.ReadAllText(paths[0]); + } + else { - this.sourceCode += System.IO.File.ReadAllText(file) + "\n"; + + // We replace 'ReadAllText' with 'StringBuilder' and 'ReadAllLines' + // to avoide temporary LOH allocations. + + StringBuilder sb = new StringBuilder(8192); + + foreach (string file in paths) + { + foreach (string line in File.ReadAllLines(file)) + { + sb.AppendLine(line); + } + } + + sourceCode = sb.ToString(); } } + else if (String.Equals(ParameterSetName, "FromMember", StringComparison.OrdinalIgnoreCase)) + { + sourceCode = GenerateTypeSource(typeNamespace, Name, sourceCode, Language); + } CompileSourceToAssembly(this.sourceCode); } @@ -957,7 +796,7 @@ private void LoadAssemblies(IEnumerable assemblies) assembly = Assembly.LoadFrom(ResolveAssemblyName(assemblyName, false)); } - if (passThru) + if (PassThru) { WriteTypes(assembly); } @@ -1039,7 +878,7 @@ private static PortableExecutableReference[] InitDefaultRefAssemblies() /// /// Initialize the set of assembly names that should be ignored when they are specified in '-ReferencedAssemblies'. - /// - System.Private.CoreLib.ni.dll - the runtim dll that contains most core/primitive types + /// - System.Private.CoreLib.ni.dll - the runtime dll that contains most core/primitive types /// - System.Private.Uri.dll - the runtime dll that contains 'System.Uri' and related types /// Referencing these runtime dlls may cause ambiguous type identity or other issues. /// - System.Runtime.dll - the corresponding reference dll will be automatically included @@ -1095,7 +934,7 @@ private string ResolveAssemblyName(string assembly, bool isForReferenceAssembly) if (!assembly.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) { // It could be a short assembly name or a full assembly name, but we - // alwasy want the short name to find the corresponding assembly file. + // always want the short name to find the corresponding assembly file. var assemblyName = new AssemblyName(assembly); refAssemblyDll = assemblyName.Name + ".dll"; } @@ -1185,46 +1024,17 @@ private void WriteTypes(Assembly assembly) private void CompileSourceToAssembly(string source) { CSharpParseOptions parseOptions; - if (IsCSharp(language)) + if (Language == Language.CSharp) { - switch (language) - { - case Language.CSharpVersion1: - parseOptions = new CSharpParseOptions(LanguageVersion.CSharp1); - break; - case Language.CSharpVersion2: - parseOptions = new CSharpParseOptions(LanguageVersion.CSharp2); - break; - case Language.CSharpVersion3: - parseOptions = new CSharpParseOptions(LanguageVersion.CSharp3); - break; - case Language.CSharpVersion4: - parseOptions = new CSharpParseOptions(LanguageVersion.CSharp4); - break; - case Language.CSharpVersion5: - parseOptions = new CSharpParseOptions(LanguageVersion.CSharp5); - break; - case Language.CSharpVersion6: - parseOptions = new CSharpParseOptions(LanguageVersion.CSharp6); - break; - case Language.CSharpVersion7: - parseOptions = new CSharpParseOptions(LanguageVersion.CSharp7); - break; - case Language.CSharp: - parseOptions = new CSharpParseOptions(); - break; - default: - parseOptions = null; - break; - } + parseOptions = new CSharpParseOptions(); } else { ErrorRecord errorRecord = new ErrorRecord( - new Exception(String.Format(CultureInfo.CurrentCulture, AddTypeStrings.SpecialNetVersionRequired, language.ToString(), string.Empty)), + new Exception(String.Format(CultureInfo.CurrentCulture, AddTypeStrings.SpecialNetVersionRequired, Language.ToString(), string.Empty)), "LANGUAGE_NOT_SUPPORTED", ErrorCategory.InvalidArgument, - language); + Language); ThrowTerminatingError(errorRecord); parseOptions = null; @@ -1271,7 +1081,7 @@ private void CompileSourceToAssembly(string source) ms.Seek(0, SeekOrigin.Begin); Assembly assembly = Assembly.Load(ms.ToArray()); CheckTypesForDuplicates(assembly); - if (passThru) + if (PassThru) { WriteTypes(assembly); } @@ -1283,7 +1093,7 @@ private void CompileSourceToAssembly(string source) emitResult = compilation.Emit(outputAssembly); if (emitResult.Success) { - if (passThru) + if (PassThru) { Assembly assembly = Assembly.LoadFrom(outputAssembly); CheckTypesForDuplicates(assembly); diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs index 6313a9a5ddc..ba8bb6be34a 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; @@ -54,7 +53,6 @@ public char Delimiter [Parameter(ParameterSetName = "UseCulture")] public SwitchParameter UseCulture { get; set; } - /// /// Abstract Property - Input Object which is written in Csv format /// Derived as Different Attributes.In ConvertTo-CSV, This is a positional parameter. Export-CSV not a Positional behaviour. @@ -67,27 +65,21 @@ public abstract PSObject InputObject } /// - /// NoTypeInformation : should the #TYPE line be generated + /// IncludeTypeInformation : The #TYPE line should be generated. Default is false. Cannot specify with NoTypeInformation. /// [Parameter] + [Alias("ITI")] + public SwitchParameter IncludeTypeInformation { get; set; } + + /// + /// NoTypeInformation : The #TYPE line should not be generated. Default is true. Cannot specify with IncludeTypeInformation. + /// + [Parameter(DontShow = true)] [Alias("NTI")] - public SwitchParameter NoTypeInformation - { - get - { - return _noTypeInformation; - } - set - { - _noTypeInformation = value; - } - } - private bool _noTypeInformation; + public SwitchParameter NoTypeInformation { get; set; } = true; #endregion Command Line Parameters - - /// /// Write the string to a file or pipeline /// @@ -100,6 +92,16 @@ public virtual void WriteCsvLine(string line) /// protected override void BeginProcessing() { + if (this.MyInvocation.BoundParameters.ContainsKey(nameof(IncludeTypeInformation)) && this.MyInvocation.BoundParameters.ContainsKey(nameof(NoTypeInformation))) + { + InvalidOperationException exception = new InvalidOperationException(CsvCommandStrings.CannotSpecifyIncludeTypeInformationAndNoTypeInformation); + ErrorRecord errorRecord = new ErrorRecord(exception, "CannotSpecifyIncludeTypeInformationAndNoTypeInformation", ErrorCategory.InvalidData, null); + this.ThrowTerminatingError(errorRecord); + } + if (this.MyInvocation.BoundParameters.ContainsKey("IncludeTypeInformation")) + { + NoTypeInformation = !IncludeTypeInformation; + } _delimiter = ImportExportCSVHelper.SetDelimiter(this, ParameterSetName, _delimiter, UseCulture); } } @@ -165,8 +167,6 @@ public string LiteralPath } private bool _isLiteralPath = false; - - /// /// Property that sets force parameter. /// @@ -206,8 +206,20 @@ public SwitchParameter NoClobber /// Encoding optional flag /// [Parameter()] - [ValidateSetAttribute(new string[] { "Unicode", "UTF7", "UTF8", "ASCII", "UTF32", "BigEndianUnicode", "Default", "OEM" })] - public string Encoding { get; set; } + [ArgumentToEncodingTransformationAttribute()] + [ArgumentCompletions( + EncodingConversion.Ascii, + EncodingConversion.BigEndianUnicode, + EncodingConversion.OEM, + EncodingConversion.Unicode, + EncodingConversion.Utf7, + EncodingConversion.Utf8, + EncodingConversion.Utf8Bom, + EncodingConversion.Utf8NoBom, + EncodingConversion.Utf32 + )] + [ValidateNotNullOrEmpty] + public Encoding Encoding { get; set; } = ClrFacade.GetDefaultEncoding(); /// /// Property that sets append parameter. @@ -248,7 +260,6 @@ protected override void BeginProcessing() _helper = new ExportCsvHelper(this, base.Delimiter); } - /// /// Convert the current input object to Csv and write to file/WriteObject /// @@ -367,7 +378,7 @@ private void CreateFileStream() PathUtils.MasterStreamOpen( this, this.Path, - Encoding ?? "ASCII", + Encoding, false, // defaultEncoding Append, Force, @@ -498,7 +509,6 @@ public sealed [ValidateNotNull] public char Delimiter { get; set; } - /// /// mandatory file name to read from /// @@ -558,7 +568,6 @@ public SwitchParameter UseCulture } private bool _useculture; - /// /// Header property to customize the names /// @@ -571,8 +580,20 @@ public SwitchParameter UseCulture /// Encoding optional flag /// [Parameter()] - [ValidateSetAttribute(new[] { "Unicode", "UTF7", "UTF8", "ASCII", "UTF32", "BigEndianUnicode", "Default", "OEM" })] - public string Encoding { get; set; } + [ArgumentToEncodingTransformationAttribute()] + [ArgumentCompletions( + EncodingConversion.Ascii, + EncodingConversion.BigEndianUnicode, + EncodingConversion.OEM, + EncodingConversion.Unicode, + EncodingConversion.Utf7, + EncodingConversion.Utf8, + EncodingConversion.Utf8Bom, + EncodingConversion.Utf8NoBom, + EncodingConversion.Utf32 + )] + [ValidateNotNullOrEmpty] + public Encoding Encoding { get; set; } = ClrFacade.GetDefaultEncoding(); /// /// Avoid writing out duplicate warning messages when there are @@ -673,8 +694,6 @@ protected override _helper = new ExportCsvHelper(this, base.Delimiter); } - - /// /// Convert the current input object to Csv and write to stream/WriteObject /// @@ -867,7 +886,6 @@ internal class ExportCsvHelper : IDisposable //Name of properties to be written in CSV format - /// /// Get the name of properties from source PSObject and /// add them to _propertyNames. @@ -1306,10 +1324,6 @@ private string { type = null; } - else - { - type = ImportExportCSVHelper.CSVTypePrefix + type; - } } } return type; @@ -1337,7 +1351,6 @@ private Collection //Read the next character char ch = ReadChar(); - if ((ch == _delimiter)) { if (seenBeginQuote) @@ -1453,21 +1466,12 @@ private Collection break; } } - else if (IsNewLine(ch)) + else if (IsNewLine(ch, out string newLine)) { - if (ch == '\r') - { - ReadChar(); - } - if (seenBeginQuote) { //newline inside quote are valid - current.Append(ch); - if (ch == '\r') - { - current.Append('\n'); - } + current.Append(newLine); } else { @@ -1490,23 +1494,30 @@ private Collection return result; } + // If we detect a newline we return it as a string "\r", "\n" or "\r\n" private bool - IsNewLine(char ch) + IsNewLine(char ch, out string newLine) { - bool newLine = false; - if (ch == '\n') - { - newLine = true; - } - else if (ch == '\r') + newLine = ""; + if (ch == '\r') { if (PeekNextChar('\n')) { - newLine = true; + ReadChar(); + newLine = "\r\n"; } + else + { + newLine = "\r"; + } + } + else if (ch == '\n') + { + newLine = "\n"; } - return newLine; + + return newLine != ""; } /// @@ -1544,13 +1555,9 @@ private Collection { break; } - else if (IsNewLine(ch)) + else if (IsNewLine(ch, out string newLine)) { endOfRecord = true; - if (ch == '\r') - { - ReadChar(); - } break; } else @@ -1582,11 +1589,6 @@ private Collection PSObject result = new PSObject(); char delimiterlocal = delimiter; int unspecifiedNameIndex = 1; - if (type != null && type.Length > 0) - { - result.TypeNames.Clear(); - result.TypeNames.Add(type); - } for (int i = 0; i <= names.Count - 1; i++) { string name = names[i]; @@ -1614,6 +1616,13 @@ private Collection _alreadyWarnedUnspecifiedName = true; } + if (type != null && type.Length > 0) + { + result.TypeNames.Clear(); + result.TypeNames.Add(type); + result.TypeNames.Add(ImportExportCSVHelper.CSVTypePrefix + type); + } + return result; } } diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ConsoleColorCmdlet.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ConsoleColorCmdlet.cs index ca8ef06ed16..6fe3c3f5c0d 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ConsoleColorCmdlet.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ConsoleColorCmdlet.cs @@ -1,8 +1,5 @@ -/********************************************************************++ - -Copyright (c) Microsoft Corporation. All rights reserved. - ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; @@ -63,8 +60,6 @@ public ConsoleColorCmdlet() } } - - /// /// /// diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ConvertFrom-StringData.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ConvertFrom-StringData.cs index a632dc8610b..9ad5a1c0c95 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ConvertFrom-StringData.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ConvertFrom-StringData.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Csv.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Csv.cs index f2bc20b75f1..bce8acb1269 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Csv.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Csv.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Collections.ObjectModel; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CustomSerialization.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CustomSerialization.cs index 87fd82b2bf4..09aacba0d2a 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CustomSerialization.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CustomSerialization.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. namespace System.Management.Automation { @@ -279,7 +278,6 @@ internal void WriteOneObject(object source, string property, int depth) return; } - if (HandlePrimitiveKnownTypePSObject(source, property, depth)) { return; @@ -428,7 +426,6 @@ private bool HandleKnownContainerTypes(object source, string property, int depth return true; } - /// /// Checks if source is known container type and returns appropriate /// information diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CustomSerializationStrings.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CustomSerializationStrings.cs index a98974cfd6d..9c22f590aa0 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CustomSerializationStrings.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CustomSerializationStrings.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. namespace System.Management.Automation { @@ -11,7 +10,6 @@ internal static class CustomSerializationStrings { #region element tags - /// /// Element tag for root node /// @@ -27,7 +25,6 @@ internal static class CustomSerializationStrings /// internal const string Properties = "Property"; - #region attribute tags /// diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/DebugRunspaceCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/DebugRunspaceCommand.cs index 22cb72cec8d..003fcef583b 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/DebugRunspaceCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/DebugRunspaceCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Disable-PSBreakpoint.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Disable-PSBreakpoint.cs index 4e8a4758f1b..9f7f3a3efbd 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Disable-PSBreakpoint.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Disable-PSBreakpoint.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Enable-PSBreakpoint.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Enable-PSBreakpoint.cs index ffec562fa2b..d4ba85d090b 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Enable-PSBreakpoint.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Enable-PSBreakpoint.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Diagnostics; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/EnableDisableRunspaceDebugCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/EnableDisableRunspaceDebugCommand.cs index a5f7092f2ce..81acbef07a3 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/EnableDisableRunspaceDebugCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/EnableDisableRunspaceDebugCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ExportAliasCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ExportAliasCommand.cs index 26e75084930..bebc287c449 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ExportAliasCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ExportAliasCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; @@ -254,7 +253,6 @@ protected override void ProcessRecord() } } // ProcessRecord - /// /// Writes the aliases to the file /// @@ -327,7 +325,6 @@ private static string GetAliasLine(AliasInfo alias, string formatString) return result; } - private void WriteHeader(StreamWriter writer) { WriteFormattedResourceString(writer, AliasCommandStrings.ExportAliasHeaderTitle); diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/ColumnInfo.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/ColumnInfo.cs index 595859f70c6..1c18571c9b2 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/ColumnInfo.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/ColumnInfo.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. namespace Microsoft.PowerShell.Commands { diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/ExpressionColumnInfo.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/ExpressionColumnInfo.cs index 2ae6b5585c2..e56e2b4d2e1 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/ExpressionColumnInfo.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/ExpressionColumnInfo.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. namespace Microsoft.PowerShell.Commands { diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/HeaderInfo.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/HeaderInfo.cs index 3e487439528..a6b86061673 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/HeaderInfo.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/HeaderInfo.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. namespace Microsoft.PowerShell.Commands { diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/OriginalColumnInfo.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/OriginalColumnInfo.cs index f1737bbaf4f..395eaee2040 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/OriginalColumnInfo.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/OriginalColumnInfo.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. namespace Microsoft.PowerShell.Commands { diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/OutGridViewCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/OutGridViewCommand.cs index a1496eb3ca3..1461f226017 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/OutGridViewCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/OutGridViewCommand.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. namespace Microsoft.PowerShell.Commands { diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/OutWindowProxy.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/OutWindowProxy.cs index 19b4fc2423d..adcf5f0c127 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/OutWindowProxy.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/OutWindowProxy.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. namespace Microsoft.PowerShell.Commands { @@ -22,7 +21,6 @@ internal class OutWindowProxy : IDisposable private const string IndexPropertyName = "IndexValue"; private int _index; - /// Columns definition of the underlying Management List private HeaderInfo _headerInfo; @@ -261,8 +259,6 @@ public void Dispose() GC.SuppressFinalize(this); } - - /// /// Close the window if it has already been displayed. /// diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/ScalarTypeColumnInfo.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/ScalarTypeColumnInfo.cs index 872a362c1d1..e8204464c95 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/ScalarTypeColumnInfo.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/ScalarTypeColumnInfo.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. namespace Microsoft.PowerShell.Commands { diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/TableView.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/TableView.cs index 548dd36acaa..f828d1324de 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/TableView.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/TableView.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. namespace Microsoft.PowerShell.Commands { diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/common/GetFormatDataCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/common/GetFormatDataCommand.cs index f5923481ccc..7f047e376a6 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/common/GetFormatDataCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/common/GetFormatDataCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Linq; @@ -76,7 +75,6 @@ protected override void BeginProcessing() } } - private static Dictionary> GetTypeGroupMap(IEnumerable groupDefinitions) { var typeGroupMap = new Dictionary>(); diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/common/WriteFormatDataCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/common/WriteFormatDataCommand.cs index 78967899beb..c78b54090e4 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/common/WriteFormatDataCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/common/WriteFormatDataCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs index b1c65d3f2b1..89ab8c1ca21 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.IO; using System.Text; @@ -46,14 +49,20 @@ public sealed class FormatHex : PSCmdlet /// Type of character encoding for InputObject /// [Parameter(ParameterSetName = "ByInputObject")] - [ValidateSetAttribute(new string[] { - EncodingConversion.Unicode, + [ArgumentToEncodingTransformationAttribute()] + [ArgumentCompletions( + EncodingConversion.Ascii, EncodingConversion.BigEndianUnicode, - EncodingConversion.Utf8, + EncodingConversion.OEM, + EncodingConversion.Unicode, EncodingConversion.Utf7, - EncodingConversion.Utf32, - EncodingConversion.Ascii})] - public string Encoding { get; set; } = "Ascii"; + EncodingConversion.Utf8, + EncodingConversion.Utf8Bom, + EncodingConversion.Utf8NoBom, + EncodingConversion.Utf32 + )] + [ValidateNotNullOrEmpty] + public Encoding Encoding { get; set; } = ClrFacade.GetDefaultEncoding(); /// /// This parameter is no-op @@ -76,9 +85,9 @@ protected override void ProcessRecord() } else { - List pathsToProcess = String.Equals(this.ParameterSetName, "LiteralPath", StringComparison.OrdinalIgnoreCase) ? + List pathsToProcess = String.Equals(this.ParameterSetName, "LiteralPath", StringComparison.OrdinalIgnoreCase) ? ResolvePaths(LiteralPath, true) : ResolvePaths(Path, false); - + ProcessPath(pathsToProcess); } } @@ -235,19 +244,18 @@ private void ProcessObjectContent(PSObject inputObject) List pathsToProcess = ResolvePaths(path, true); ProcessPath(pathsToProcess); } - + else if (obj is string) { string inputString = obj.ToString(); - Encoding resolvedEncoding = EncodingConversion.Convert(this, Encoding); - inputBytes = resolvedEncoding.GetBytes(inputString); + inputBytes = Encoding.GetBytes(inputString); } - + else if (obj is byte) { inputBytes = new byte[] { (byte)obj }; } - + else if (obj is byte[]) { inputBytes = ((byte[])obj); @@ -274,7 +282,7 @@ private void ProcessObjectContent(PSObject inputObject) { inputBytes = BitConverter.GetBytes((Int64)obj); } - + else if (obj is Int64[]) { List inputStreamArray = new List(); diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-list/Format-List.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-list/Format-List.cs index 3a137cc1527..6db95821034 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-list/Format-List.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-list/Format-List.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; using Microsoft.PowerShell.Commands.Internal.Format; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-object/format-object.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-object/format-object.cs index c1030e57d64..a4efe117997 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-object/format-object.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-object/format-object.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; using Microsoft.PowerShell.Commands.Internal.Format; @@ -22,7 +21,6 @@ public FormatCustomCommand() this.implementation = new InnerFormatShapeCommand(FormatShape.Complex); } - #region Command Line Switches /// diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-table/Format-Table.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-table/Format-Table.cs index 63212a63da1..fcf92d00f6d 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-table/Format-Table.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-table/Format-Table.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; @@ -24,4 +23,3 @@ public FormatTableCommand() } } - diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-wide/Format-Wide.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-wide/Format-Wide.cs index 97576c7c7da..9075782e26b 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-wide/Format-Wide.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-wide/Format-Wide.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.IO; @@ -25,7 +24,6 @@ public FormatWideCommand() this.implementation = new InnerFormatShapeCommand(FormatShape.Wide); } - #region Command Line Switches /// @@ -60,7 +58,6 @@ public SwitchParameter AutoSize } private Nullable _autosize = null; - /// /// optional, non positional parameter /// @@ -110,7 +107,6 @@ internal override FormattingCommandLineParameters GetCommandLineParameters() // the user specified -autosize:true AND a column number string msg = StringUtil.Format(FormatAndOut_format_xxx.CannotSpecifyAutosizeAndColumnsError); - ErrorRecord errorRecord = new ErrorRecord( new InvalidDataException(), "FormatCannotSpecifyAutosizeAndColumns", diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/out-file/Out-File.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/out-file/Out-File.cs index b8fd1cc09b6..01b8ff081fa 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/out-file/Out-File.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/out-file/Out-File.cs @@ -1,8 +1,8 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; +using System.Text; using System.Management.Automation; using System.Management.Automation.Internal; using System.Management.Automation.Host; @@ -72,25 +72,20 @@ public string LiteralPath /// /// [Parameter(Position = 1)] - [ValidateNotNullOrEmpty] - [ValidateSetAttribute(new string[] { - EncodingConversion.Unknown, - EncodingConversion.String, - EncodingConversion.Unicode, + [ArgumentToEncodingTransformationAttribute()] + [ArgumentCompletions( + EncodingConversion.Ascii, EncodingConversion.BigEndianUnicode, - EncodingConversion.Utf8, + EncodingConversion.OEM, + EncodingConversion.Unicode, EncodingConversion.Utf7, - EncodingConversion.Utf32, - EncodingConversion.Ascii, - EncodingConversion.Default, - EncodingConversion.OEM })] - public string Encoding - { - get { return _encoding; } - set { _encoding = value; } - } - - private string _encoding; + EncodingConversion.Utf8, + EncodingConversion.Utf8Bom, + EncodingConversion.Utf8NoBom, + EncodingConversion.Utf32 + )] + [ValidateNotNullOrEmpty] + public Encoding Encoding { get; set; } = ClrFacade.GetDefaultEncoding(); /// /// Property that sets append parameter. @@ -180,7 +175,6 @@ protected override void BeginProcessing() base.BeginProcessing(); } - /// /// one time initialization: acquire a screen host interface /// by creating one on top of a file @@ -196,7 +190,7 @@ private LineOutput InstantiateLineOutputInterface() PathUtils.MasterStreamOpen( this, FilePath, - _encoding, + Encoding, false, // defaultEncoding Append, Force, @@ -211,32 +205,13 @@ private LineOutput InstantiateLineOutputInterface() return null; // compute the # of columns available - int computedWidth = 120; + int computedWidth = int.MaxValue; if (_width != null) { // use the value from the command line computedWidth = _width.Value; } - else - { - // use the value we get from the console - try - { - // NOTE: we subtract 1 because we want to properly handle - // the following scenario: - // MSH>get-foo|out-file foo.txt - // MSH>get-content foo.txt - // in this case, if the computed width is (say) 80, get-content - // would cause a wrapping of the 80 column long raw strings. - // Hence we set the width to 79. - computedWidth = this.Host.UI.RawUI.BufferSize.Width - 1; - } - catch (HostException) - { - // non interactive host - } - } // use the stream writer to create and initialize the Line Output writer TextWriterLineOutput twlo = new TextWriterLineOutput(_sw, computedWidth, _suppressNewline); diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/out-printer/PrinterLineOutput.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/out-printer/PrinterLineOutput.cs index b84d8038726..7b79ddaaafc 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/out-printer/PrinterLineOutput.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/out-printer/PrinterLineOutput.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; @@ -264,7 +263,6 @@ private void pd_PrintPage(object sender, PrintPageEventArgs ev) ev.HasMorePages = _lines.Count > 0; } - /// /// flag for one time initialization of the interface (columns, etc.) /// @@ -290,7 +288,6 @@ private void pd_PrintPage(object sender, PrintPageEventArgs ev) /// private int _printFontSize = 0; - /// /// default font, used if the printFont is not specified or if the /// printFont is not fixed pitch. diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/out-printer/out-printer.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/out-printer/out-printer.cs index 45a9c643cb1..d70f044340d 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/out-printer/out-printer.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/out-printer/out-printer.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; using Microsoft.PowerShell.Commands.Internal.Format; @@ -61,6 +60,3 @@ private LineOutput InstantiateLineOutputInterface() } } - - - diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/out-string/out-string.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/out-string/out-string.cs index d12354a7f52..fb63659b4c8 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/out-string/out-string.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/out-string/out-string.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Text; @@ -94,31 +93,13 @@ private LineOutput InstantiateLineOutputInterface() _writer = new StreamingTextWriter(callback, Host.CurrentCulture); // compute the # of columns available - int computedWidth = 120; + int computedWidth = int.MaxValue; if (_width != null) { // use the value from the command line computedWidth = _width.Value; } - else - { - // use the value we get from the console - try - { - // NOTE: we subtract 1 because we want to properly handle - // the following scenario: - // MSH>get-foo|format-table|out-string - // in this case, if the computed width is (say) 80, get-content - // would cause a wrapping of the 80 column long raw strings. - // Hence we set the width to 79. - computedWidth = this.Host.UI.RawUI.BufferSize.Width - 1; - } - catch (HostException) - { - // non interactive host - } - } // use it to create and initialize the Line Output writer TextWriterLineOutput twlo = new TextWriterLineOutput(_writer, computedWidth); diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Get-PSBreakpoint.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Get-PSBreakpoint.cs index 2b2bc3b320a..cd449e2e481 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Get-PSBreakpoint.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Get-PSBreakpoint.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; @@ -264,7 +263,6 @@ protected override void ProcessRecord() } } - /// /// Gives the criteria to filter breakpoints /// diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Get-PSCallStack.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Get-PSCallStack.cs index 95ebf019ab8..3b07991f428 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Get-PSCallStack.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Get-PSCallStack.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetAliasCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetAliasCommand.cs index 71881daa8a9..568bbdfbb21 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetAliasCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetAliasCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; @@ -110,8 +109,6 @@ private void WriteMatches(string value, string parametersetname) aliasTable = SessionState.Internal.GetAliasTable(); } - - bool matchfound = false; bool ContainsWildcard = WildcardPattern.ContainsWildcardCharacters(value); WildcardPattern wcPattern = WildcardPattern.Get(value, WildcardOptions.IgnoreCase); diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetCultureCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetCultureCommand.cs index a7cf6d671d7..1667ca7c6ba 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetCultureCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetCultureCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; @@ -23,4 +22,3 @@ protected override void BeginProcessing() } // GetCultureCommand } // Microsoft.PowerShell.Commands - diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetDateCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetDateCommand.cs index 9aae07cf70b..bc52bd6e864 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetDateCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetDateCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Globalization; @@ -42,7 +41,6 @@ public DateTime Date private DateTime _date; private bool _dateSpecified; - /// /// Allows the user to override the year /// @@ -63,7 +61,6 @@ public int Year private int _year; private bool _yearSpecified; - /// /// Allows the user to override the month /// @@ -84,7 +81,6 @@ public int Month private int _month; private bool _monthSpecified; - /// /// Allows the user to override the day /// @@ -105,7 +101,6 @@ public int Day private int _day; private bool _daySpecified; - /// /// Allows the user to override the hour /// @@ -126,7 +121,6 @@ public int Hour private int _hour; private bool _hourSpecified; - /// /// Allows the user to override the minute /// @@ -147,7 +141,6 @@ public int Minute private int _minute; private bool _minuteSpecified; - /// /// Allows the user to override the second /// @@ -194,7 +187,6 @@ public int Millisecond [Parameter] public DisplayHintType DisplayHint { get; set; } = DisplayHintType.DateTime; - /// /// Unix format string /// @@ -202,7 +194,6 @@ public int Millisecond [ValidateNotNullOrEmpty] public string UFormat { get; set; } - /// /// Unix format string /// @@ -323,13 +314,13 @@ protected override void ProcessRecord() } } // EndProcessing + private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); /// /// This is more an implementation of the UNIX strftime /// private string UFormatDateString(DateTime dateTime) { - DateTime epoch = DateTime.Parse("January 1, 1970", System.Globalization.CultureInfo.InvariantCulture); int offset = 0; StringBuilder sb = new StringBuilder(); @@ -361,18 +352,12 @@ private string UFormatDateString(DateTime dateTime) sb.Append("{0:MMM}"); break; - case 'h': - sb.Append("{0:MMM}"); - break; - case 'C': sb.Append(dateTime.Year / 100); break; case 'c': - sb.Append("{0:ddd} {0:MMM} "); - sb.Append(StringUtil.Format("{0,2} ", dateTime.Day)); - sb.Append("{0:HH}:{0:mm}:{0:ss} {0:yyyy}"); + sb.Append("{0:ddd} {0:dd} {0:MMM} {0:yyyy} {0:HH}:{0:mm}:{0:ss}"); break; case 'D': @@ -387,24 +372,36 @@ private string UFormatDateString(DateTime dateTime) sb.Append(StringUtil.Format("{0,2}", dateTime.Day)); break; + case 'G': + sb.Append("{0:yyyy}"); + break; + + case 'g': + sb.Append("{0:yy}"); + break; + case 'H': sb.Append("{0:HH}"); break; + case 'h': + sb.Append("{0:MMM}"); + break; + case 'I': sb.Append("{0:hh}"); break; case 'j': - sb.Append(dateTime.DayOfYear); + sb.Append(StringUtil.Format("{0:000}", dateTime.DayOfYear)); break; case 'k': - sb.Append("{0:HH}"); + sb.Append(StringUtil.Format("{0,2:0}", dateTime.Hour)); break; case 'l': - sb.Append("{0:hh}"); + sb.Append("{0,2:%h}"); break; case 'M': @@ -436,39 +433,54 @@ private string UFormatDateString(DateTime dateTime) break; case 's': - sb.Append(dateTime.Subtract(epoch).TotalSeconds); + sb.Append(StringUtil.Format("{0:0}", dateTime.ToUniversalTime().Subtract(epoch).TotalSeconds)); break; case 'T': sb.Append("{0:HH:mm:ss}"); break; - case 'X': - sb.Append("{0:HH:mm:ss}"); - break; - case 't': sb.Append("\t"); break; - case 'u': - sb.Append((int)dateTime.DayOfWeek); - break; - case 'U': sb.Append(dateTime.DayOfYear / 7); break; - case 'V': - sb.Append((dateTime.DayOfYear / 7) + 1); - break; - - case 'G': - sb.Append("{0:yyyy}"); + case 'u': + sb.Append((int)dateTime.DayOfWeek); break; - case 'g': - sb.Append("{0:yy}"); + case 'V': + // .Net Core doesn't implement ISO 8601. + // So we use workaround from https://blogs.msdn.microsoft.com/shawnste/2006/01/24/iso-8601-week-of-year-format-in-microsoft-net/ + // with corrections from comments + + // Culture doesn't matter since we specify start day of week + var calender = CultureInfo.InvariantCulture.Calendar; + var day = calender.GetDayOfWeek(dateTime); + var normalizedDatetime = dateTime; + + switch (day) + { + case DayOfWeek.Monday: + case DayOfWeek.Tuesday: + case DayOfWeek.Wednesday: + normalizedDatetime = dateTime.AddDays(3); + break; + + case DayOfWeek.Friday: + case DayOfWeek.Saturday: + case DayOfWeek.Sunday: + normalizedDatetime = dateTime.AddDays(-3); + break; + } + + // FirstFourDayWeek and DayOfWeek.Monday is from ISO 8601 + sb.Append(StringUtil.Format("{0:00}",calender.GetWeekOfYear(normalizedDatetime, + CalendarWeekRule.FirstFourDayWeek, + DayOfWeek.Monday))); break; case 'W': @@ -479,18 +491,22 @@ private string UFormatDateString(DateTime dateTime) sb.Append((int)dateTime.DayOfWeek); break; - case 'x': - sb.Append("{0:MM/dd/yy}"); + case 'X': + sb.Append("{0:HH:mm:ss}"); break; - case 'y': - sb.Append("{0:yy}"); + case 'x': + sb.Append("{0:MM/dd/yy}"); break; case 'Y': sb.Append("{0:yyyy}"); break; + case 'y': + sb.Append("{0:yy}"); + break; + case 'Z': sb.Append("{0:zz}"); break; @@ -539,4 +555,3 @@ public enum DisplayHintType #endregion } // namespace Microsoft.PowerShell.Commands - diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetEventCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetEventCommand.cs index 0989e91f919..7de6d9879eb 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetEventCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetEventCommand.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; @@ -58,7 +57,6 @@ public int EventIdentifier } private int _eventId = -1; - #endregion parameters private WildcardPattern _matchPattern; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetEventSubscriberCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetEventSubscriberCommand.cs index 7c013c30a3d..7ef87569f3d 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetEventSubscriberCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetEventSubscriberCommand.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; @@ -47,7 +46,6 @@ public string SourceIdentifier [Alias("Id")] public int SubscriptionId { get; set; } = -1; - /// /// Also show supporting events /// diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetHash.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetHash.cs index 336c4829d42..732619dc522 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetHash.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetHash.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.Collections.Generic; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetHostCmdlet.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetHostCmdlet.cs index 448ef283f4f..90d36efe409 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetHostCmdlet.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetHostCmdlet.cs @@ -1,7 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetMember.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetMember.cs index 980154f7771..6806d930bec 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetMember.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetMember.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.ObjectModel; @@ -68,7 +67,6 @@ public class GetMemberCommand : PSCmdlet [Parameter(ValueFromPipeline = true)] public PSObject InputObject { set; get; } - /// /// The member names to be retrieved /// @@ -76,7 +74,6 @@ public class GetMemberCommand : PSCmdlet [ValidateNotNullOrEmpty] public string[] Name { set; get; } = new string[] { "*" }; - /// /// The member types to be retrieved /// @@ -84,7 +81,6 @@ public class GetMemberCommand : PSCmdlet [Alias("Type")] public PSMemberTypes MemberType { set; get; } = PSMemberTypes.All; - /// /// View from which the members are retrieved. /// @@ -190,7 +186,6 @@ protected override void ProcessRecord() // PSMemberSet instance is created to represent PSExtended, PSAdapted, PSBase, PSObject hidden // properties. We should honor extended properties for such case. - // request is to search dotnet or adapted or both members. // dotnet,adapted members cannot be Script*,Note*,Code* memberTypeToSearch ^= (PSMemberTypes.AliasProperty | PSMemberTypes.CodeMethod | PSMemberTypes.CodeProperty @@ -265,7 +260,6 @@ public int Compare(MemberDefinition first, MemberDefinition second) } } - /// /// This method implements the End method for get-member command /// diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetRandomCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetRandomCommand.cs index 83232ea3b99..87e81a45373 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetRandomCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetRandomCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetRunspaceCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetRunspaceCommand.cs index f138b9dd89d..009c1c2a43f 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetRunspaceCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetRunspaceCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUICultureCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUICultureCommand.cs index 9e6a983a30c..9a958d1e1bc 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUICultureCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUICultureCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; @@ -23,4 +22,3 @@ protected override void BeginProcessing() } // GetUICultureCommand } // Microsoft.PowerShell.Commands - diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUnique.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUnique.cs index a17f2c0ec45..d3cedd9a83e 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUnique.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUnique.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; @@ -24,7 +23,6 @@ public sealed class GetUniqueCommand : PSCmdlet [Parameter(ValueFromPipeline = true)] public PSObject InputObject { set; get; } = AutomationNull.Value; - /// /// This parameter specifies that objects should be converted to /// strings and the strings should be compared. @@ -38,7 +36,6 @@ public SwitchParameter AsString } private bool _asString; - /// /// This parameter specifies that just the types of the objects /// should be compared. diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUptime.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUptime.cs index f7389e606af..1d8b178cfc7 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUptime.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUptime.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetVerbCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetVerbCommand.cs index 384c1030085..878f753dfa3 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetVerbCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetVerbCommand.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using System.Management.Automation; using System.Collections.Generic; using System.Collections.ObjectModel; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ImplicitRemotingCommands.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ImplicitRemotingCommands.cs index e694403c6b8..f9394ffcebf 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ImplicitRemotingCommands.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ImplicitRemotingCommands.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections; @@ -77,19 +76,20 @@ public SwitchParameter Force /// Encoding optional flag /// [Parameter] - [ValidateSetAttribute(new string[] { "Unicode", "UTF7", "UTF8", "ASCII", "UTF32", "BigEndianUnicode", "Default", "OEM" })] - public string Encoding - { - get - { - return _encoding.GetType().Name; - } - set - { - _encoding = EncodingConversion.Convert(this, value); - } - } - private Encoding _encoding = System.Text.Encoding.UTF8; + [ArgumentToEncodingTransformationAttribute()] + [ArgumentCompletions( + EncodingConversion.Ascii, + EncodingConversion.BigEndianUnicode, + EncodingConversion.OEM, + EncodingConversion.Unicode, + EncodingConversion.Utf7, + EncodingConversion.Utf8, + EncodingConversion.Utf8Bom, + EncodingConversion.Utf8NoBom, + EncodingConversion.Utf32 + )] + [ValidateNotNullOrEmpty] + public Encoding Encoding { get; set; } = ClrFacade.GetDefaultEncoding(); #endregion Parameters @@ -144,7 +144,7 @@ protected override void BeginProcessing() List generatedFiles = GenerateProxyModule( tempDirectory, Path.GetFileName(directory.FullName), - _encoding, + Encoding, _force, listOfCommandMetadata, alias2resolvedCommandName, @@ -2053,7 +2053,6 @@ private void GenerateTopComment(TextWriter writer) throw '{3}' }} - $script:WriteHost = $executionContext.InvokeCommand.GetCommand('Write-Host', [System.Management.Automation.CommandTypes]::Cmdlet) $script:WriteWarning = $executionContext.InvokeCommand.GetCommand('Write-Warning', [System.Management.Automation.CommandTypes]::Cmdlet) $script:WriteInformation = $executionContext.InvokeCommand.GetCommand('Write-Information', [System.Management.Automation.CommandTypes]::Cmdlet) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Import-LocalizedData.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Import-LocalizedData.cs index fdcbb57a166..5e31191303e 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Import-LocalizedData.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Import-LocalizedData.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Globalization; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ImportAliasCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ImportAliasCommand.cs index 07372404d70..4a98475ab5e 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ImportAliasCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ImportAliasCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ImportPowerShellDataFile.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ImportPowerShellDataFile.cs index d0418892bdb..ee253baf228 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ImportPowerShellDataFile.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ImportPowerShellDataFile.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.Diagnostics.CodeAnalysis; using System.Management.Automation; @@ -17,7 +20,7 @@ public class ImportPowerShellDataFileCommand : PSCmdlet /// /// Path specified, using globbing to resolve /// - [Parameter(Mandatory = true, Position = 0, ParameterSetName = "ByPath")] + [Parameter(Mandatory = true, Position = 0, ParameterSetName = "ByPath")] [ValidateNotNullOrEmpty] [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public string[] Path { get; set; } @@ -84,7 +87,7 @@ private void WritePathNotFoundError(string path) } void WriteInvalidDataFileError(string resolvedPath, string errorId) - { + { var errorCategory = ErrorCategory.InvalidData; var errorMessage = string.Format(UtilityResources.CouldNotParseAsPowerShellDataFile, resolvedPath); var exception = new InvalidOperationException(errorMessage); diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/InvokeCommandCmdlet.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/InvokeCommandCmdlet.cs index 4392ec00a84..7c751922b4d 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/InvokeCommandCmdlet.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/InvokeCommandCmdlet.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; using System.Management.Automation.Internal; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/MatchString.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/MatchString.cs index 88fac123a4a..ef70aacf40d 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/MatchString.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/MatchString.cs @@ -1,8 +1,8 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; +using System.Text; using System.Text.RegularExpressions; using System.IO; using System.Collections; @@ -61,12 +61,13 @@ internal MatchInfoContext() /// public object Clone() { - MatchInfoContext clone = new MatchInfoContext(); - clone.PreContext = (clone.PreContext != null) ? (string[])PreContext.Clone() : null; - clone.PostContext = (clone.PostContext != null) ? (string[])PostContext.Clone() : null; - clone.DisplayPreContext = (clone.DisplayPreContext != null) ? (string[])DisplayPreContext.Clone() : null; - clone.DisplayPostContext = (clone.DisplayPostContext != null) ? (string[])DisplayPostContext.Clone() : null; - return clone; + return new MatchInfoContext() + { + PreContext = (string[])PreContext?.Clone(), + PostContext = (string[])PostContext?.Clone(), + DisplayPreContext = (string[])DisplayPreContext?.Clone(), + DisplayPostContext = (string[])DisplayPostContext?.Clone() + }; } } @@ -114,7 +115,6 @@ public string Filename } private string _filename; - /// /// The full path of the file containing the matching line. /// @@ -433,7 +433,6 @@ public bool Contains(T item) throw new NotImplementedException(); } - [SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")] public void CopyTo(T[] array, int arrayIndex) { @@ -1200,19 +1199,20 @@ public SwitchParameter AllMatches /// The text encoding to process each file as. /// [Parameter] - [ValidateNotNullOrEmpty] - [ValidateSetAttribute(new string[] { + [ArgumentToEncodingTransformationAttribute()] + [ArgumentCompletions( + EncodingConversion.Ascii, + EncodingConversion.BigEndianUnicode, + EncodingConversion.OEM, EncodingConversion.Unicode, EncodingConversion.Utf7, EncodingConversion.Utf8, - EncodingConversion.Utf32, - EncodingConversion.Ascii, - EncodingConversion.BigEndianUnicode, - EncodingConversion.Default, - EncodingConversion.OEM })] - public string Encoding { get; set; } - - private System.Text.Encoding _textEncoding; + EncodingConversion.Utf8Bom, + EncodingConversion.Utf8NoBom, + EncodingConversion.Utf32 + )] + [ValidateNotNullOrEmpty] + public Encoding Encoding { get; set; } = ClrFacade.GetDefaultEncoding(); /// /// The number of context lines to collect. If set to a @@ -1281,16 +1281,6 @@ public SwitchParameter AllMatches /// protected override void BeginProcessing() { - // Process encoding switch. - if (Encoding != null) - { - _textEncoding = EncodingConversion.Convert(this, Encoding); - } - else - { - _textEncoding = new System.Text.UTF8Encoding(); - } - if (!_simpleMatch) { RegexOptions regexOptions = (_caseSensitive) ? RegexOptions.None : RegexOptions.IgnoreCase; @@ -1433,7 +1423,7 @@ private bool ProcessFile(string filename) using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { - using (StreamReader sr = new StreamReader(fs, _textEncoding)) + using (StreamReader sr = new StreamReader(fs, Encoding)) { String line; int lineNo = 0; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Measure-Object.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Measure-Object.cs index 977fd640670..62bebc4d212 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Measure-Object.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Measure-Object.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; @@ -35,7 +34,7 @@ public sealed class GenericMeasureInfo : MeasureInfo /// public GenericMeasureInfo() { - Average = Sum = Maximum = Minimum = null; + Average = Sum = Maximum = Minimum = StandardDeviation = null; } /// @@ -72,6 +71,11 @@ public GenericMeasureInfo() /// /// public double? Minimum { get; set; } + + /// + /// The Standard Deviation of property values. + /// + public double? StandardDeviation { get; set; } } /// @@ -91,7 +95,7 @@ public sealed class GenericObjectMeasureInfo : MeasureInfo /// public GenericObjectMeasureInfo() { - Average = Sum = null; + Average = Sum = StandardDeviation = null; Maximum = Minimum = null; } @@ -129,8 +133,12 @@ public GenericObjectMeasureInfo() /// /// public object Minimum { get; set; } - } + /// + /// The Standard Deviation of property values. + /// + public double? StandardDeviation { get; set; } + } /// /// Class output by Measure-Object @@ -227,6 +235,8 @@ private class Statistics // Generic/Numeric statistics internal double sum = 0.0; + internal double sumPrevious = 0.0; + internal double variance = 0.0; internal object max = null; internal object min = null; @@ -265,6 +275,24 @@ public MeasureObjectCommand() #endregion Common parameters in both sets + /// + /// Set to true if Standard Deviation is to be returned. + /// + [Parameter(ParameterSetName = GenericParameterSet)] + public SwitchParameter StandardDeviation + { + get + { + return _measureStandardDeviation; + } + set + { + _measureStandardDeviation = value; + } + } + + private bool _measureStandardDeviation; + /// /// Set to true is Sum is to be returned /// @@ -413,7 +441,6 @@ public SwitchParameter IgnoreWhiteSpace #endregion TextMeasure ParameterSet #endregion Command Line Switches - /// /// Which parameter set the Cmdlet is in. /// @@ -528,7 +555,7 @@ private void AnalyzeValue(string propertyName, object objValue) AnalyzeString(strValue, stat); } - if (_measureAverage || _measureSum) + if (_measureAverage || _measureSum || _measureStandardDeviation) { double numValue = 0.0; if (!LanguagePrimitives.TryConvertTo(objValue, out numValue)) @@ -711,8 +738,19 @@ private void AnalyzeString(string strValue, Statistics stat) /// private void AnalyzeNumber(double numValue, Statistics stat) { - if (_measureSum || _measureAverage) + if (_measureSum || _measureAverage || _measureStandardDeviation) + { + stat.sumPrevious = stat.sum; stat.sum += numValue; + } + if (_measureStandardDeviation && stat.count > 1) + { + // Based off of iterative method of calculating variance on + // https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Online_algorithm + double avgPrevious = stat.sumPrevious / (stat.count - 1); + stat.variance *= (stat.count - 2.0) / (stat.count - 1); + stat.variance += (numValue - avgPrevious) * (numValue - avgPrevious) / stat.count; + } } /// @@ -793,6 +831,7 @@ private MeasureInfo CreateGenericMeasureInfo(Statistics stat, bool shouldUseGene { double? sum = null; double? average = null; + double? StandardDeviation = null; object max = null; object min = null; @@ -800,8 +839,14 @@ private MeasureInfo CreateGenericMeasureInfo(Statistics stat, bool shouldUseGene { if (_measureSum) sum = stat.sum; + if (_measureAverage && stat.count > 0) average = stat.sum / stat.count; + + if (_measureStandardDeviation) + { + StandardDeviation = Math.Sqrt(stat.variance); + } } if (_measureMax) @@ -838,6 +883,7 @@ private MeasureInfo CreateGenericMeasureInfo(Statistics stat, bool shouldUseGene gmi.Count = stat.count; gmi.Sum = sum; gmi.Average = average; + gmi.StandardDeviation = StandardDeviation; if (null != max) { gmi.Maximum = (double)max; @@ -890,7 +936,7 @@ private TextMeasureInfo CreateTextMeasureInfo(Statistics stat) /// /// Whether or not a numeric conversion error occurred. - /// If true, then average/sum will not be output. + /// If true, then average/sum/standard deviation will not be output. /// private bool _nonNumericError = false; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/NewAliasCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/NewAliasCommand.cs index d53cd1d2823..bc6276eada2 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/NewAliasCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/NewAliasCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; @@ -38,7 +37,6 @@ protected override void ProcessRecord() existingAlias = SessionState.Internal.GetAliasAtScope(Name, Scope); } - if (existingAlias != null) { // Throw if alias exists and is private... diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/NewGuidCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/NewGuidCommand.cs index 38beda8c638..b8ecc9381f8 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/NewGuidCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/NewGuidCommand.cs @@ -1,7 +1,5 @@ - -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/NewTemporaryFileCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/NewTemporaryFileCommand.cs index 2ea91339037..a271f185f85 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/NewTemporaryFileCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/NewTemporaryFileCommand.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.IO; @@ -18,18 +20,18 @@ public class NewTemporaryFileCommand : Cmdlet protected override void EndProcessing() { string filePath = null; - string tempPath = System.Environment.GetEnvironmentVariable("TEMP"); + string tempPath = Path.GetTempPath(); if (ShouldProcess(tempPath)) { try { filePath = Path.GetTempFileName(); } - catch (Exception e) + catch (IOException ioException) { - WriteError( + ThrowTerminatingError( new ErrorRecord( - e, + ioException, "NewTemporaryFileWriteError", ErrorCategory.WriteError, tempPath)); diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/NewTimeSpanCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/NewTimeSpanCommand.cs index 36a15cdeb97..c346dfb6697 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/NewTimeSpanCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/NewTimeSpanCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; @@ -39,7 +38,6 @@ public DateTime Start private DateTime _start; private bool _startSpecified; - /// /// This parameter indicates the end of a time span. It is used if two /// times are being compared. If one of the times is not specified, @@ -61,28 +59,24 @@ public DateTime End private DateTime _end; private bool _endSpecified = false; - /// /// Allows the user to override the day /// [Parameter(ParameterSetName = "Time")] public int Days { get; set; } = 0; - /// /// Allows the user to override the hour /// [Parameter(ParameterSetName = "Time")] public int Hours { get; set; } = 0; - /// /// Allows the user to override the minute /// [Parameter(ParameterSetName = "Time")] public int Minutes { get; set; } = 0; - /// /// Allows the user to override the second /// @@ -134,4 +128,3 @@ protected override void ProcessRecord() } // NewTimeSpanCommand } // namespace Microsoft.PowerShell.Commands - diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ObjectCommandComparer.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ObjectCommandComparer.cs index d3dc8bc5cc9..2de48409515 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ObjectCommandComparer.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ObjectCommandComparer.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives @@ -43,7 +42,6 @@ internal ObjectCommandPropertyValue(object propVal, bool isCaseSensitive, Cultur this.cultureInfo = cultureInfo; } - internal object PropertyValue { get; } internal bool IsExistingProperty { get; } @@ -154,7 +152,6 @@ private static bool IsValueNull(object value) return (val == null); } - internal int Compare(ObjectCommandPropertyValue first, ObjectCommandPropertyValue second) { if (first.IsExistingProperty && second.IsExistingProperty) @@ -196,7 +193,6 @@ public int Compare(object first, object second) // objects are considered the same if (IsValueNull(first) && IsValueNull(second)) return 0; - PSObject firstMsh = first as PSObject; if (firstMsh != null) { diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/OrderObjectBase.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/OrderObjectBase.cs index 9d34c4b75ec..afed3c1e6fc 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/OrderObjectBase.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/OrderObjectBase.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ReadConsoleCmdlet.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ReadConsoleCmdlet.cs index 94da63d9d09..a6d8962b95c 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ReadConsoleCmdlet.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ReadConsoleCmdlet.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections; @@ -84,7 +83,6 @@ public sealed class ReadHostCommand : PSCmdlet } #endregion Parameters - #region Cmdlet Overrides /// @@ -171,8 +169,6 @@ protected override void BeginProcessing() #endregion Cmdlet Overrides - - private object _prompt = null; private Boolean _safe = false; } diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/RegisterObjectEventCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/RegisterObjectEventCommand.cs index 1b4386200e1..15dd6f50197 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/RegisterObjectEventCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/RegisterObjectEventCommand.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/RegisterPSEventCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/RegisterPSEventCommand.cs index bcc24c49a54..8346b7aace8 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/RegisterPSEventCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/RegisterPSEventCommand.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Remove-PSBreakpoint.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Remove-PSBreakpoint.cs index bd55d3fddd0..395e30829b7 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Remove-PSBreakpoint.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Remove-PSBreakpoint.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/RemoveAliasCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/RemoveAliasCommand.cs new file mode 100644 index 00000000000..dfc98d2c2b9 --- /dev/null +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/RemoveAliasCommand.cs @@ -0,0 +1,75 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Management.Automation; +using System.Management.Automation.Internal; + +namespace Microsoft.PowerShell.Commands +{ + /// + /// The implementation of the "Remove-Alias" cmdlet. + /// + /// + [Cmdlet(VerbsCommon.Remove, "Alias", DefaultParameterSetName = "Default", HelpUri = "")] + [Alias("ral")] + public class RemoveAliasCommand : PSCmdlet + { + #region Parameters + + /// + /// The alias name to remove. + /// + [Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + public string[] Name { get; set; } + + /// + /// The scope parameter for the command determines + /// which scope the alias is removed from. + /// + [Parameter] + public string Scope { get; set; } + + /// + /// If set to true and an existing alias of the same name exists + /// and is ReadOnly, it will still be deleted. + /// + [Parameter] + public SwitchParameter Force { get; set; } + + #endregion Parameters + + #region Command code + + /// + /// The main processing loop of the command. + /// + protected override void ProcessRecord() + { + foreach(string aliasName in Name) + { + AliasInfo existingAlias = null; + if (String.IsNullOrEmpty(Scope)) + { + existingAlias = SessionState.Internal.GetAlias(aliasName); + } + else + { + existingAlias = SessionState.Internal.GetAliasAtScope(aliasName, Scope); + } + + if (existingAlias != null) + { + SessionState.Internal.RemoveAlias(aliasName, Force); + } + else + { + ItemNotFoundException notAliasFound = new ItemNotFoundException(StringUtil.Format(AliasCommandStrings.NoAliasFound, "name", aliasName)); + ErrorRecord error = new ErrorRecord(notAliasFound, "ItemNotFoundException",ErrorCategory.ObjectNotFound, aliasName); + WriteError(error); + } + } + } + #endregion Command code + } +} diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/RemoveEventCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/RemoveEventCommand.cs index 381ebde3fa4..d59db2282ea 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/RemoveEventCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/RemoveEventCommand.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Send-MailMessage.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Send-MailMessage.cs index b2667207242..0b6651920aa 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Send-MailMessage.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Send-MailMessage.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Text; @@ -9,7 +8,6 @@ using System.Diagnostics.CodeAnalysis; using System.Management.Automation; - namespace Microsoft.PowerShell.Commands { #region SendMailMessage @@ -89,20 +87,24 @@ public SwitchParameter BodyAsHtml /// /// Specifies the encoding used for the content of the body and also the subject. + /// This is set to ASCII to ensure there are no problems with any email server /// [Parameter()] [Alias("BE")] [ValidateNotNullOrEmpty] - [ArgumentToEncodingNameTransformationAttribute()] - public Encoding Encoding - { - get { return _encoding; } - set - { - _encoding = value; - } - } - private Encoding _encoding = new ASCIIEncoding(); + [ArgumentCompletions( + EncodingConversion.Ascii, + EncodingConversion.BigEndianUnicode, + EncodingConversion.OEM, + EncodingConversion.Unicode, + EncodingConversion.Utf7, + EncodingConversion.Utf8, + EncodingConversion.Utf8Bom, + EncodingConversion.Utf8NoBom, + EncodingConversion.Utf32 + )] + [ArgumentToEncodingTransformationAttribute()] + public Encoding Encoding { get; set; } = Encoding.ASCII; /// /// Specifies the address collection that contains the @@ -204,7 +206,6 @@ public String Subject } private String _subject; - /// /// Specifies the To address for this e-mail message. /// @@ -268,10 +269,8 @@ public int Port #endregion - #region private variables and methods - // Instantiate a new instance of MailMessage private MailMessage _mMailMessage = new MailMessage(); @@ -357,8 +356,6 @@ protected override AddAddressesToMailMessage(_cc, "cc"); } - - //set the delivery notification _mMailMessage.DeliveryNotificationOptions = _deliverynotification; @@ -369,8 +366,8 @@ protected override _mMailMessage.Body = _body; //set the subject and body encoding - _mMailMessage.SubjectEncoding = _encoding; - _mMailMessage.BodyEncoding = _encoding; + _mMailMessage.SubjectEncoding = Encoding; + _mMailMessage.BodyEncoding = Encoding; // Set the format of the mail message body as HTML _mMailMessage.IsBodyHtml = _bodyashtml; @@ -378,7 +375,6 @@ protected override // Set the priority of the mail message to normal _mMailMessage.Priority = _priority; - //get the PowerShell environment variable //globalEmailServer might be null if it is deleted by: PS> del variable:PSEmailServer PSVariable globalEmailServer = SessionState.Internal.GetVariable(SpecialVariables.PSEmailServer); @@ -490,37 +486,5 @@ protected override void EndProcessing() #endregion } - /// - /// To make it easier to specify -Encoding parameter, we add an ArgumentTransformationAttribute here. - /// When the input data is of type string and is valid to be converted to System.Text.Encoding, we do - /// the conversion and return the converted value. Otherwise, we just return the input data. - /// - internal sealed class ArgumentToEncodingNameTransformationAttribute : ArgumentTransformationAttribute - { - public override object Transform(EngineIntrinsics engineIntrinsics, object inputData) - { - string encodingName; - if (LanguagePrimitives.TryConvertTo(inputData, out encodingName)) - { - if (string.Equals(encodingName, EncodingConversion.Unknown, StringComparison.OrdinalIgnoreCase) || - string.Equals(encodingName, EncodingConversion.String, StringComparison.OrdinalIgnoreCase) || - string.Equals(encodingName, EncodingConversion.Unicode, StringComparison.OrdinalIgnoreCase) || - string.Equals(encodingName, EncodingConversion.BigEndianUnicode, StringComparison.OrdinalIgnoreCase) || - string.Equals(encodingName, EncodingConversion.Utf8, StringComparison.OrdinalIgnoreCase) || - string.Equals(encodingName, EncodingConversion.Utf7, StringComparison.OrdinalIgnoreCase) || - string.Equals(encodingName, EncodingConversion.Utf32, StringComparison.OrdinalIgnoreCase) || - string.Equals(encodingName, EncodingConversion.Ascii, StringComparison.OrdinalIgnoreCase) || - string.Equals(encodingName, EncodingConversion.Default, StringComparison.OrdinalIgnoreCase) || - string.Equals(encodingName, EncodingConversion.OEM, StringComparison.OrdinalIgnoreCase)) - { - // the encodingName is guaranteed to be valid, so it is safe to pass null to method - // Convert(Cmdlet cmdlet, string encoding) as the value of 'cmdlet'. - return EncodingConversion.Convert(null, encodingName); - } - } - return inputData; - } - } - #endregion -} \ No newline at end of file +} diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Set-PSBreakpoint.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Set-PSBreakpoint.cs index 50095080cec..67e48bbf904 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Set-PSBreakpoint.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Set-PSBreakpoint.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.ObjectModel; @@ -46,7 +45,6 @@ public int Column } private int? _column = null; - /// /// the command(s) to set the breakpoint on /// diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/SetAliasCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/SetAliasCommand.cs index 0d3c5ae95f4..dd5d8ea0575 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/SetAliasCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/SetAliasCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/SetDateCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/SetDateCommand.cs index f5a744c1a7e..fb7f0fc9fde 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/SetDateCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/SetDateCommand.cs @@ -1,6 +1,6 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #pragma warning disable 1634, 1691 using System; @@ -27,7 +27,6 @@ public sealed class SetDateCommand : PSCmdlet [Parameter(Position = 0, Mandatory = true, ParameterSetName = "Date", ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] public DateTime Date { get; set; } - /// /// Allows a use to specify a timespan with which to apply to the current time /// @@ -35,7 +34,6 @@ public sealed class SetDateCommand : PSCmdlet [AllowNull] public TimeSpan Adjust { get; set; } - /// /// This option determines the default output format used to display the object set-date emits /// @@ -117,7 +115,7 @@ protected override void ProcessRecord() internal static class NativeMethods { [StructLayout(LayoutKind.Sequential)] - public class SystemTime + public struct SystemTime { public UInt16 Year; public UInt16 Month; @@ -137,4 +135,3 @@ public class SystemTime } // SetDateCommand } // namespace Microsoft.PowerShell.Commands - diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommand.cs index 1f7b0c68519..f2a1476fecf 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommand.cs @@ -1,8 +1,5 @@ -//----------------------------------------------------------------------- -// -// Copyright © Microsoft Corporation. All rights reserved. -// -//----------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. namespace Microsoft.PowerShell.Commands { diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandCommandInfo.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandCommandInfo.cs index ea38c132998..fc02201d3fa 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandCommandInfo.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandCommandInfo.cs @@ -1,8 +1,5 @@ -//----------------------------------------------------------------------- -// -// Copyright © Microsoft Corporation. All rights reserved. -// -//----------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. namespace Microsoft.PowerShell.Commands.ShowCommandExtension { diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandModuleInfo.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandModuleInfo.cs index 909c395cf19..9f9d663ef9e 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandModuleInfo.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandModuleInfo.cs @@ -1,8 +1,5 @@ -//----------------------------------------------------------------------- -// -// Copyright © Microsoft Corporation. All rights reserved. -// -//----------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. namespace Microsoft.PowerShell.Commands.ShowCommandExtension { @@ -17,7 +14,7 @@ public class ShowCommandModuleInfo /// /// Creates an instance of the ShowCommandModuleInfo class based on a CommandInfo object /// - /// + /// /// /// The object to wrap. /// @@ -34,7 +31,7 @@ public ShowCommandModuleInfo(PSModuleInfo other) /// /// Creates an instance of the ShowCommandModuleInfo class based on a PSObject object /// - /// + /// /// /// The object to wrap. /// diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandParameterInfo.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandParameterInfo.cs index 00b311c069e..c9eed0a7d12 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandParameterInfo.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandParameterInfo.cs @@ -1,8 +1,5 @@ -//----------------------------------------------------------------------- -// -// Copyright © Microsoft Corporation. All rights reserved. -// -//----------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. namespace Microsoft.PowerShell.Commands.ShowCommandExtension { @@ -11,7 +8,6 @@ namespace Microsoft.PowerShell.Commands.ShowCommandExtension using System.Linq; using System.Management.Automation; - /// /// Implements a facade around ShowCommandParameterInfo and its deserialized counterpart /// @@ -20,7 +16,7 @@ public class ShowCommandParameterInfo /// /// Creates an instance of the ShowCommandParameterInfo class based on a CommandParameterInfo object /// - /// + /// /// /// The object to wrap. /// @@ -48,7 +44,7 @@ public ShowCommandParameterInfo(CommandParameterInfo other) /// /// Creates an instance of the ShowCommandParameterInfo class based on a PSObject object /// - /// + /// /// /// The object to wrap. /// diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandParameterSetInfo.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandParameterSetInfo.cs index b57f7953d72..3b572bfd94e 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandParameterSetInfo.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandParameterSetInfo.cs @@ -1,8 +1,5 @@ -//----------------------------------------------------------------------- -// -// Copyright © Microsoft Corporation. All rights reserved. -// -//----------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. namespace Microsoft.PowerShell.Commands.ShowCommandExtension { @@ -11,7 +8,6 @@ namespace Microsoft.PowerShell.Commands.ShowCommandExtension using System.Linq; using System.Management.Automation; - /// /// Implements a facade around CommandParameterSetInfo and its deserialized counterpart /// diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandParameterType.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandParameterType.cs index 85398443d72..a8769d2c9c4 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandParameterType.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandParameterType.cs @@ -1,8 +1,5 @@ -//----------------------------------------------------------------------- -// -// Copyright © Microsoft Corporation. All rights reserved. -// -//----------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. namespace Microsoft.PowerShell.Commands.ShowCommandExtension { @@ -10,7 +7,6 @@ namespace Microsoft.PowerShell.Commands.ShowCommandExtension using System.Collections; using System.Management.Automation; - /// /// Implements a facade around ShowCommandParameterInfo and its deserialized counterpart /// diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandProxy.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandProxy.cs index 1d3b8b62bfd..20ab1c538d3 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandProxy.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommandProxy.cs @@ -1,8 +1,5 @@ -//----------------------------------------------------------------------- -// -// Copyright © Microsoft Corporation. All rights reserved. -// -//----------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. namespace Microsoft.PowerShell.Commands { @@ -127,7 +124,6 @@ internal AutoResetEvent WindowLoaded } } - internal string CommandNeedingHelp { get @@ -149,7 +145,6 @@ internal void DisplayHelp(Collection helpResults) _graphicalHostReflectionWrapper.CallMethod("DisplayHelp", helpResults); } - internal string GetImportModuleCommand(string module) { return (string)_graphicalHostReflectionWrapper.CallStaticMethod("GetImportModuleCommand", module, false, true); diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/StartSleepCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/StartSleepCommand.cs index 8006470e231..2abf326f546 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/StartSleepCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/StartSleepCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; @@ -36,8 +35,6 @@ public void Dispose() #endregion - - #region parameters /// @@ -48,7 +45,6 @@ public void Dispose() [ValidateRangeAttribute(0, int.MaxValue / 1000)] public int Seconds { get; set; } - /// /// Allows sleep time to be specified in milliseconds /// diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/TestJsonCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/TestJsonCommand.cs new file mode 100644 index 00000000000..8b08da6427d --- /dev/null +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/TestJsonCommand.cs @@ -0,0 +1,101 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Management.Automation; +using System.Management.Automation.Internal; + +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using NJsonSchema; + +namespace Microsoft.PowerShell.Commands +{ + /// + /// This class implements Test-Json command. + /// + [Cmdlet(VerbsDiagnostic.Test, "Json", HelpUri = "")] + public class TestJsonCommand : PSCmdlet + { + /// + /// An JSON to be validated. + /// + [Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true)] + public String Json { get; set; } + + /// + /// A schema to validate the JSON against. + /// This is optional parameter. + /// If the parameter is absent the cmdlet only attempts to parse the JSON string. + /// If the parameter present the cmdlet attempts to parse the JSON string and + /// then validates the JSON against the schema. Before testing the JSON string, + /// the cmdlet parses the schema doing implicitly check the schema too. + /// + [Parameter(Position = 1)] + [ValidateNotNullOrEmpty()] + public String Schema { get; set; } + + private JsonSchema4 _jschema; + + /// + /// Prepare an JSON schema. + /// + protected override void BeginProcessing() + { + if (Schema != null) + { + try + { + _jschema = JsonSchema4.FromJsonAsync(Schema).Result; + } + catch (Exception exc) + { + Exception exception = new Exception(TestJsonCmdletStrings.InvalidJsonSchema, exc); + ThrowTerminatingError(new ErrorRecord(exception, "InvalidJsonSchema", ErrorCategory.InvalidData, null)); + } + } + } + + /// + /// Validate an JSON. + /// + protected override void ProcessRecord() + { + JObject parsedJson = null; + bool result = true; + + try + { + parsedJson = JObject.Parse(Json); + + if (_jschema != null) + { + var errorMessages = _jschema.Validate(parsedJson); + if (errorMessages != null && errorMessages.Count != 0) + { + result = false; + + Exception exception = new Exception(TestJsonCmdletStrings.InvalidJsonAgainstSchema); + + foreach (var message in errorMessages) + { + ErrorRecord errorRecord = new ErrorRecord(exception, "InvalidJsonAgainstSchema", ErrorCategory.InvalidData, null); + errorRecord.ErrorDetails = new ErrorDetails(message.ToString()); + WriteError(errorRecord); + } + } + } + } + catch (Exception exc) + { + result = false; + + Exception exception = new Exception(TestJsonCmdletStrings.InvalidJson, exc); + WriteError(new ErrorRecord(exception, "InvalidJson", ErrorCategory.InvalidData, Json)); + } + + WriteObject(result); + } + } +} diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/TimeExpressionCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/TimeExpressionCommand.cs index 80ea05f4851..26857e97e42 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/TimeExpressionCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/TimeExpressionCommand.cs @@ -1,13 +1,12 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #region Using directives using System; using System.Management.Automation; using System.Management.Automation.Internal; - #endregion namespace Microsoft.PowerShell.Commands @@ -28,7 +27,6 @@ public sealed class MeasureCommandCommand : PSCmdlet [Parameter(ValueFromPipeline = true)] public PSObject InputObject { set; get; } = AutomationNull.Value; - /// /// The script block to apply /// @@ -45,7 +43,6 @@ public sealed class MeasureCommandCommand : PSCmdlet #region methods - /// /// Output the timer /// @@ -54,7 +51,6 @@ protected override void EndProcessing() WriteObject(_stopWatch.Elapsed); } // EndProcessing - /// /// Execute the script block passing in the current pipeline object as /// it's only parameter. diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnblockFile.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnblockFile.cs index 95d91473183..932d2ee44c6 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnblockFile.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnblockFile.cs @@ -1,7 +1,7 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #if !UNIX -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ #region Using directives @@ -121,9 +121,17 @@ protected override void ProcessRecord() } catch (Win32Exception accessException) { - WriteError(new ErrorRecord(accessException, "RemoveItemUnauthorizedAccessError", ErrorCategory.PermissionDenied, path)); + // NativeErrorCode=2 - File not found. + // If the block stream not found the 'path' was not blocked and we successfully return. + if (accessException.NativeErrorCode != 2) + { + WriteError(new ErrorRecord(accessException, "RemoveItemUnauthorizedAccessError", ErrorCategory.PermissionDenied, path)); + } + else + { + WriteVerbose(StringUtil.Format(UtilityCommonStrings.NoZoneIdentifierFileStream, path)); + } } - } } } diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnregisterEventCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnregisterEventCommand.cs index 428c7a5843f..267aa5d52f8 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnregisterEventCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnregisterEventCommand.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Update-Data.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Update-Data.cs index 3db55e855b7..1cf0cf8e940 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Update-Data.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Update-Data.cs @@ -1,12 +1,10 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; using System.Collections.ObjectModel; - namespace Microsoft.PowerShell.Commands { /// diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Update-TypeData.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Update-TypeData.cs index daef516bbd1..50a9a2973cd 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Update-TypeData.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Update-TypeData.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Concurrent; @@ -13,7 +12,6 @@ using System.Management.Automation.Runspaces; using Dbg = System.Management.Automation.Diagnostics; - namespace Microsoft.PowerShell.Commands { /// @@ -129,7 +127,6 @@ public string SerializationMethod get { return _serializationMethod; } } - /// /// TargetTypeForDeserialization /// @@ -141,7 +138,6 @@ public Type TargetTypeForDeserialization get { return _targetTypeForDeserialization; } } - /// /// SerializationDepth /// @@ -154,7 +150,6 @@ public int SerializationDepth get { return _serializationDepth; } } - /// /// DefaultDisplayProperty /// @@ -166,7 +161,6 @@ public string DefaultDisplayProperty get { return _defaultDisplayProperty; } } - /// /// InheritPropertySerializationSet /// @@ -178,7 +172,6 @@ public Nullable InheritPropertySerializationSet get { return _inheritPropertySerializationSet; } } - /// /// StringSerializationSource /// @@ -190,7 +183,6 @@ public string StringSerializationSource get { return _stringSerializationSource; } } - /// /// DefaultDisplayPropertySet /// @@ -215,7 +207,6 @@ public string[] DefaultKeyPropertySet get { return _defaultKeyPropertySet; } } - /// /// PropertySerializationSet /// @@ -366,17 +357,13 @@ private void ProcessStrongTypeData() else { // Update successfully, we add the TypeData into cache - if (Context.RunspaceConfiguration != null) - { - Context.RunspaceConfiguration.Types.Append(new TypeConfigurationEntry(type, false)); - } - else if (Context.InitialSessionState != null) + if (Context.InitialSessionState != null) { Context.InitialSessionState.Types.Add(new SessionStateTypeEntry(type, false)); } else { - Dbg.Assert(false, "Either RunspaceConfiguration or InitialSessionState must be non-null for Update-Typedata to work"); + Dbg.Assert(false, "InitialSessionState must be non-null for Update-Typedata to work"); } } } @@ -484,17 +471,13 @@ private void ProcessDynamicType() else { // Update successfully, we add the TypeData into cache - if (Context.RunspaceConfiguration != null) - { - Context.RunspaceConfiguration.Types.Append(new TypeConfigurationEntry(type, false)); - } - else if (Context.InitialSessionState != null) + if (Context.InitialSessionState != null) { Context.InitialSessionState.Types.Add(new SessionStateTypeEntry(type, false)); } else { - Dbg.Assert(false, "Either RunspaceConfiguration or InitialSessionState must be non-null for Update-Typedata to work"); + Dbg.Assert(false, "InitialSessionState must be non-null for Update-Typedata to work"); } } } @@ -757,38 +740,7 @@ private void ProcessTypeFiles() // filename is available string target = UpdateDataStrings.UpdateTarget; - if (Context.RunspaceConfiguration != null) - { - for (int i = prependPathTotal.Count - 1; i >= 0; i--) - { - string formattedTarget = string.Format(CultureInfo.InvariantCulture, target, prependPathTotal[i]); - - if (ShouldProcess(formattedTarget, action)) - { - this.Context.RunspaceConfiguration.Types.Prepend(new TypeConfigurationEntry(prependPathTotal[i])); - } - } - - foreach (string appendPathTotalItem in appendPathTotal) - { - string formattedTarget = string.Format(CultureInfo.InvariantCulture, target, appendPathTotalItem); - - if (ShouldProcess(formattedTarget, action)) - { - this.Context.RunspaceConfiguration.Types.Append(new TypeConfigurationEntry(appendPathTotalItem)); - } - } - - try - { - this.Context.CurrentRunspace.RunspaceConfiguration.Types.Update(true); - } - catch (RuntimeException e) - { - this.WriteError(new ErrorRecord(e, "TypesXmlUpdateException", ErrorCategory.InvalidOperation, null)); - } - } - else if (Context.InitialSessionState != null) + if (Context.InitialSessionState != null) { // This hashSet is to detect if there are duplicate type files var fullFileNameHash = new HashSet(StringComparer.CurrentCultureIgnoreCase); @@ -887,7 +839,7 @@ private void ProcessTypeFiles() } else { - Dbg.Assert(false, "Either RunspaceConfiguration or InitialSessionState must be non-null for Update-Typedata to work"); + Dbg.Assert(false, "InitialSessionState must be non-null for Update-Typedata to work"); } } @@ -931,38 +883,7 @@ protected override void ProcessRecord() // filename is available string target = UpdateDataStrings.UpdateTarget; - if (Context.RunspaceConfiguration != null) - { - for (int i = prependPathTotal.Count - 1; i >= 0; i--) - { - string formattedTarget = string.Format(CultureInfo.CurrentCulture, target, prependPathTotal[i]); - - if (ShouldProcess(formattedTarget, action)) - { - this.Context.RunspaceConfiguration.Formats.Prepend(new FormatConfigurationEntry(prependPathTotal[i])); - } - } - - foreach (string appendPathTotalItem in appendPathTotal) - { - string formattedTarget = string.Format(CultureInfo.CurrentCulture, target, appendPathTotalItem); - - if (ShouldProcess(formattedTarget, action)) - { - this.Context.RunspaceConfiguration.Formats.Append(new FormatConfigurationEntry(appendPathTotalItem)); - } - } - - try - { - this.Context.CurrentRunspace.RunspaceConfiguration.Formats.Update(true); - } - catch (RuntimeException e) - { - this.WriteError(new ErrorRecord(e, "FormatXmlUpdateException", ErrorCategory.InvalidOperation, null)); - } - } - else if (Context.InitialSessionState != null) + if (Context.InitialSessionState != null) { if (Context.InitialSessionState.DisableFormatUpdates) { @@ -1055,12 +976,11 @@ protected override void ProcessRecord() if (entries.Count > 0) { Context.FormatDBManager.UpdateDataBase(entries, this.Context.AuthorizationManager, this.Context.EngineHostInterface, false); - FormatAndTypeDataHelper.ThrowExceptionOnError( - "ErrorsUpdatingFormats", - null, - entries, - RunspaceConfigurationCategory.Formats); - } + FormatAndTypeDataHelper.ThrowExceptionOnError( "ErrorsUpdatingFormats", + null, + entries, + RunspaceConfigurationCategory.Formats); + } } catch (RuntimeException e) { @@ -1069,7 +989,7 @@ protected override void ProcessRecord() } else { - Dbg.Assert(false, "Either RunspaceConfiguration or InitialSessionState must be non-null for Update-FormatData to work"); + Dbg.Assert(false, "InitialSessionState must be non-null for Update-FormatData to work"); } } } @@ -1154,17 +1074,7 @@ protected override void ProcessRecord() Dictionary> fileToIndexMap = new Dictionary>(StringComparer.OrdinalIgnoreCase); List indicesToRemove = new List(); - if (Context.RunspaceConfiguration != null) - { - for (int index = 0; index < Context.RunspaceConfiguration.Types.Count; index++) - { - string fileName = Context.RunspaceConfiguration.Types[index].FileName; - if (fileName == null) { continue; } - - ConstructFileToIndexMap(fileName, index, fileToIndexMap); - } - } - else if (Context.InitialSessionState != null) + if (Context.InitialSessionState != null) { for (int index = 0; index < Context.InitialSessionState.Types.Count; index++) { @@ -1200,11 +1110,7 @@ protected override void ProcessRecord() indicesToRemove.Sort(); for (int i = indicesToRemove.Count - 1; i >= 0; i--) { - if (Context.RunspaceConfiguration != null) - { - Context.RunspaceConfiguration.Types.RemoveItem(indicesToRemove[i]); - } - else if (Context.InitialSessionState != null) + if (Context.InitialSessionState != null) { Context.InitialSessionState.Types.RemoveItem(indicesToRemove[i]); } @@ -1212,11 +1118,7 @@ protected override void ProcessRecord() try { - if (Context.RunspaceConfiguration != null) - { - Context.RunspaceConfiguration.Types.Update(); - } - else if (Context.InitialSessionState != null) + if (Context.InitialSessionState != null) { bool oldRefreshTypeFormatSetting = Context.InitialSessionState.RefreshTypeAndFormatSetting; try @@ -1279,17 +1181,13 @@ protected override void ProcessRecord() else { // Type is removed successfully, add it into the cache - if (Context.RunspaceConfiguration != null) - { - Context.RunspaceConfiguration.Types.Append(new TypeConfigurationEntry(type, true)); - } - else if (Context.InitialSessionState != null) + if (Context.InitialSessionState != null) { Context.InitialSessionState.Types.Add(new SessionStateTypeEntry(type, true)); } else { - Dbg.Assert(false, "Either RunspaceConfiguration or InitialSessionState must be non-null for Remove-Typedata to work"); + Dbg.Assert(false, "InitialSessionState must be non-null for Remove-Typedata to work"); } } } diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs index fcd6f07cb91..af39227d230 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; @@ -9,7 +8,6 @@ using System.Diagnostics.CodeAnalysis; using System.Globalization; - [module: SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix", Scope = "type", Target = "Microsoft.PowerShell.Commands.ByteCollection")] namespace Microsoft.PowerShell.Commands diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Var.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Var.cs index ae911ae063c..f0d39620af1 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Var.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Var.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections; @@ -75,7 +74,6 @@ protected string[] ExcludeFilters } private string[] _exclude = new string[0]; - #region helpers /// @@ -244,7 +242,6 @@ internal List GetMatchingVariables(string name, string lookupScope, } - /// /// Implements get-variable command. /// @@ -277,8 +274,6 @@ public string[] Name } private string[] _name = new string[] { "*" }; - - /// /// Output only the value(s) of the requested variable(s). /// @@ -296,7 +291,6 @@ public SwitchParameter ValueOnly } private bool _valueOnly; - /// /// The Include parameter for all the variable commands /// @@ -409,7 +403,6 @@ public sealed class NewVariableCommand : VariableCommandBase [Parameter] public string Description { get; set; } - /// /// The options for the variable to specify if the variable should /// be ReadOnly, Constant, and/or Private. @@ -574,7 +567,6 @@ protected override void ProcessRecord() } // ProcessRecord } // NewVariableCommand - /// /// This class implements set-variable command /// @@ -638,7 +630,6 @@ public string[] Exclude [Parameter] public string Description { get; set; } - /// /// The options for the variable to specify if the variable should /// be ReadOnly, Constant, and/or Private. @@ -694,7 +685,6 @@ public SessionStateEntryVisibility Visibility } private SessionStateEntryVisibility? _visibility; - /// /// The variable object should be passed down the pipeline. /// @@ -976,7 +966,6 @@ private void SetVariable(string[] varNames, object varValue) matchingVariable.Value = varValue; } - if (Description != null) { matchingVariable.Description = Description; @@ -1114,7 +1103,6 @@ protected override void ProcessRecord() Scope = "local"; } - foreach (string varName in Name) { // First look for existing variables to set. diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WaitEventCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WaitEventCommand.cs index 6538a0bd716..041e1b53453 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WaitEventCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WaitEventCommand.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; @@ -123,7 +122,6 @@ private void ReceivedEvents_PSEventReceived(Object sender, PSEventArgs e) } } - // Go through all the received events. If one matches the subscription identifier, // break. private void ScanEventQueue() diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/BasicHtmlWebResponseObject.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/BasicHtmlWebResponseObject.Common.cs index ae91ff0012c..cc88ad41197 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/BasicHtmlWebResponseObject.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/BasicHtmlWebResponseObject.Common.cs @@ -1,23 +1,59 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; using System.Management.Automation; using System.Net; -using System.IO; +using System.Net.Http; using System.Text; using System.Text.RegularExpressions; -using System.Collections.Generic; -using System.Diagnostics; namespace Microsoft.PowerShell.Commands { /// /// Response object for html content without DOM parsing /// - public partial class BasicHtmlWebResponseObject : WebResponseObject + public class BasicHtmlWebResponseObject : WebResponseObject { + #region Private Fields + + private static Regex s_attribNameValueRegex; + private static Regex s_attribsRegex; + private static Regex s_imageRegex; + private static Regex s_inputFieldRegex; + private static Regex s_linkRegex; + private static Regex s_tagRegex; + + #endregion Private Fields + + #region Constructors + + /// + /// Constructor for BasicHtmlWebResponseObject + /// + /// + public BasicHtmlWebResponseObject(HttpResponseMessage response) + : this(response, null) + { } + + /// + /// Constructor for HtmlWebResponseObject with memory stream + /// + /// + /// + public BasicHtmlWebResponseObject(HttpResponseMessage response, Stream contentStream) + : base(response, contentStream) + { + EnsureHtmlParser(); + InitializeContent(); + InitializeRawContent(response); + } + + #endregion Constructors + #region Properties /// @@ -116,18 +152,45 @@ public WebCmdletElementCollection Images #endregion Properties - #region Private Fields + #region Methods - private static Regex s_tagRegex; - private static Regex s_attribsRegex; - private static Regex s_attribNameValueRegex; - private static Regex s_inputFieldRegex; - private static Regex s_linkRegex; - private static Regex s_imageRegex; + /// + /// Reads the response content from the web response. + /// + protected void InitializeContent() + { + string contentType = ContentHelper.GetContentType(BaseResponse); + if (ContentHelper.IsText(contentType)) + { + Encoding encoding = null; + // fill the Content buffer + string characterSet = WebResponseHelper.GetCharacterSet(BaseResponse); - #endregion Private Fields + if (String.IsNullOrEmpty(characterSet) && ContentHelper.IsJson(contentType)) + { + characterSet = Encoding.UTF8.HeaderName; + } - #region Methods + this.Content = StreamHelper.DecodeStream(RawContentStream, characterSet, out encoding); + this.Encoding = encoding; + } + else + { + this.Content = string.Empty; + } + } + + private PSObject CreateHtmlObject(string html, string tagName) + { + PSObject elementObject = new PSObject(); + + elementObject.Properties.Add(new PSNoteProperty("outerHTML", html)); + elementObject.Properties.Add(new PSNoteProperty("tagName", tagName)); + + ParseAttributes(html, elementObject); + + return elementObject; + } private void EnsureHtmlParser() { @@ -168,16 +231,11 @@ private void EnsureHtmlParser() } } - private PSObject CreateHtmlObject(string html, string tagName) + private void InitializeRawContent(HttpResponseMessage baseResponse) { - PSObject elementObject = new PSObject(); - - elementObject.Properties.Add(new PSNoteProperty("outerHTML", html)); - elementObject.Properties.Add(new PSNoteProperty("tagName", tagName)); - - ParseAttributes(html, elementObject); - - return elementObject; + StringBuilder raw = ContentHelper.GetRawContentHeader(baseResponse); + raw.Append(Content); + this.RawContent = raw.ToString(); } private void ParseAttributes(string outerHtml, PSObject elementObject) @@ -222,26 +280,6 @@ private void ParseAttributes(string outerHtml, PSObject elementObject) } } - /// - /// Reads the response content from the web response. - /// - protected void InitializeContent() - { - string contentType = ContentHelper.GetContentType(BaseResponse); - if (ContentHelper.IsText(contentType)) - { - Encoding encoding = null; - // fill the Content buffer - string characterSet = WebResponseHelper.GetCharacterSet(BaseResponse); - this.Content = StreamHelper.DecodeStream(RawContentStream, characterSet, out encoding); - this.Encoding = encoding; - } - else - { - this.Content = string.Empty; - } - } - #endregion Methods } } diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/ContentHelper.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/ContentHelper.Common.cs index dc3a673ef46..751ff60d872 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/ContentHelper.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/ContentHelper.Common.cs @@ -1,44 +1,50 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; +using System.Linq; using System.Management.Automation; +using System.Net.Http; +using System.Net.Http.Headers; using System.Text; using Microsoft.Win32; namespace Microsoft.PowerShell.Commands { - internal static partial class ContentHelper + internal static class ContentHelper { #region Constants - // used to split contentType arguments - private static readonly char[] s_contentTypeParamSeparator = { ';' }; - // default codepage encoding for web content. See RFC 2616. private const string _defaultCodePage = "ISO-8859-1"; #endregion Constants + #region Fields + + // used to split contentType arguments + private static readonly char[] s_contentTypeParamSeparator = { ';' }; + + #endregion Fields + #region Internal Methods - internal static bool IsText(string contentType) + internal static string GetContentType(HttpResponseMessage response) { - contentType = GetContentTypeSignature(contentType); - return CheckIsText(contentType); + // ContentType may not exist in response header. Return null if not. + return response.Content.Headers.ContentType?.MediaType; } - internal static bool IsXml(string contentType) + internal static Encoding GetDefaultEncoding() { - contentType = GetContentTypeSignature(contentType); - return CheckIsXml(contentType); + return GetEncodingOrDefault((string)null); } - internal static bool IsJson(string contentType) + internal static Encoding GetEncoding(HttpResponseMessage response) { - contentType = GetContentTypeSignature(contentType); - return CheckIsJson(contentType); + // ContentType may not exist in response header. + string charSet = response.Content.Headers.ContentType?.CharSet; + return GetEncodingOrDefault(charSet); } internal static Encoding GetEncodingOrDefault(string characterSet) @@ -60,22 +66,87 @@ internal static Encoding GetEncodingOrDefault(string characterSet) return encoding; } - internal static Encoding GetDefaultEncoding() + internal static StringBuilder GetRawContentHeader(HttpResponseMessage response) { - return GetEncodingOrDefault((string)null); + StringBuilder raw = new StringBuilder(); + + string protocol = WebResponseHelper.GetProtocol(response); + if (!string.IsNullOrEmpty(protocol)) + { + int statusCode = WebResponseHelper.GetStatusCode(response); + string statusDescription = WebResponseHelper.GetStatusDescription(response); + raw.AppendFormat("{0} {1} {2}", protocol, statusCode, statusDescription); + raw.AppendLine(); + } + + HttpHeaders[] headerCollections = + { + response.Headers, + response.Content == null ? null : response.Content.Headers + }; + + foreach (var headerCollection in headerCollections) + { + if (headerCollection == null) + { + continue; + } + foreach (var header in headerCollection) + { + // Headers may have multiple entries with different values + foreach (var headerValue in header.Value) + { + raw.Append(header.Key); + raw.Append(": "); + raw.Append(headerValue); + raw.AppendLine(); + } + } + } + + raw.AppendLine(); + return raw; + } + + internal static bool IsJson(string contentType) + { + contentType = GetContentTypeSignature(contentType); + return CheckIsJson(contentType); + } + + internal static bool IsText(string contentType) + { + contentType = GetContentTypeSignature(contentType); + return CheckIsText(contentType); + } + + internal static bool IsXml(string contentType) + { + contentType = GetContentTypeSignature(contentType); + return CheckIsXml(contentType); } #endregion Internal Methods #region Private Helper Methods - private static string GetContentTypeSignature(string contentType) + private static bool CheckIsJson(string contentType) { if (String.IsNullOrEmpty(contentType)) - return null; + return false; - string sig = contentType.Split(s_contentTypeParamSeparator, 2)[0].ToUpperInvariant(); - return (sig); + // the correct type for JSON content, as specified in RFC 4627 + bool isJson = contentType.Equals("application/json", StringComparison.OrdinalIgnoreCase); + + // add in these other "javascript" related types that + // sometimes get sent down as the mime type for JSON content + isJson |= contentType.Equals("text/json", StringComparison.OrdinalIgnoreCase) + || contentType.Equals("application/x-javascript", StringComparison.OrdinalIgnoreCase) + || contentType.Equals("text/x-javascript", StringComparison.OrdinalIgnoreCase) + || contentType.Equals("application/javascript", StringComparison.OrdinalIgnoreCase) + || contentType.Equals("text/javascript", StringComparison.OrdinalIgnoreCase); + + return (isJson); } private static bool CheckIsText(string contentType) @@ -129,25 +200,15 @@ private static bool CheckIsXml(string contentType) return (isXml); } - private static bool CheckIsJson(string contentType) + private static string GetContentTypeSignature(string contentType) { if (String.IsNullOrEmpty(contentType)) - return false; - - // the correct type for JSON content, as specified in RFC 4627 - bool isJson = contentType.Equals("application/json", StringComparison.OrdinalIgnoreCase); - - // add in these other "javascript" related types that - // sometimes get sent down as the mime type for JSON content - isJson |= contentType.Equals("text/json", StringComparison.OrdinalIgnoreCase) - || contentType.Equals("application/x-javascript", StringComparison.OrdinalIgnoreCase) - || contentType.Equals("text/x-javascript", StringComparison.OrdinalIgnoreCase) - || contentType.Equals("application/javascript", StringComparison.OrdinalIgnoreCase) - || contentType.Equals("text/javascript", StringComparison.OrdinalIgnoreCase); + return null; - return (isJson); + string sig = contentType.Split(s_contentTypeParamSeparator, 2)[0].ToUpperInvariant(); + return (sig); } - #endregion Internal Helper Methods + #endregion Private Helper Methods } } diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/HtmlWebResponseObject.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/HtmlWebResponseObject.Common.cs deleted file mode 100644 index be101d482fe..00000000000 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/HtmlWebResponseObject.Common.cs +++ /dev/null @@ -1,511 +0,0 @@ -#if !CORECLR - -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - -using System; -using System.Management.Automation; -using System.Text.RegularExpressions; -using System.Collections.Generic; -using mshtml; -using System.Diagnostics; -using System.Threading; -using ExecutionContext = System.Management.Automation.ExecutionContext; - -namespace Microsoft.PowerShell.Commands -{ - /// - /// Response object for html content - /// - public partial class HtmlWebResponseObject : WebResponseObject, IDisposable - { -#region Properties - - /// - /// gets or protected sets the Content property - /// - public new string Content { get; private set; } - - // The HTML document - private IHTMLDocument2 _parsedHtml; - - // The reset event for synchronizing the 'IHTMLDocument2.write()' call - private ManualResetEventSlim _stateChangeResetEvent; - - // The reset event for synchronizing loading the document - private ManualResetEventSlim _loadDocumentResetEvent; - - // The handler for the 'onreadystatechange' event - private HTMLDocumentEvents2_onreadystatechangeEventHandler _onreadystatechangeEventHandler; - - // The exception thrown during the parsing - private Exception _parsingException; - - // The current execution context - private readonly ExecutionContext _executionContext; - - // The flag that notifies the worker thread to stop loading the document - private bool _stopWorkerThread; - - // The flag that indicates the html is parsed - private bool _htmlParsed = false; - - /// - /// gets the ParsedHtml property - /// - public IHTMLDocument2 ParsedHtml - { - get - { - EnsureHtmlParser(); - - return _parsedHtml; - } - } - - private FormObjectCollection _forms; - - /// - /// gets the Forms property - /// - public FormObjectCollection Forms - { - get - { - if (_forms == null) - { - _forms = BuildFormsCollection(); - } - - return _forms; - } - } - - private WebCmdletElementCollection _inputFields; - - /// - /// gets the Fields property - /// - public WebCmdletElementCollection InputFields - { - get - { - if (_inputFields == null) - { - EnsureHtmlParser(); - - List parsedFields = new List(); - foreach (IHTMLElement element in _parsedHtml.all) - { - if (element.tagName.Equals("INPUT", StringComparison.OrdinalIgnoreCase)) - { - parsedFields.Add(CreateHtmlObject(element, true)); - } - System.Runtime.InteropServices.Marshal.ReleaseComObject(element); - } - - _inputFields = new WebCmdletElementCollection(parsedFields); - } - - return _inputFields; - } - } - - private WebCmdletElementCollection _links; - - /// - /// gets the Links property - /// - public WebCmdletElementCollection Links - { - get - { - if (_links == null) - { - EnsureHtmlParser(); - - List parsedLinks = new List(); - foreach (IHTMLElement element in _parsedHtml.links) - { - parsedLinks.Add(CreateHtmlObject(element, true)); - System.Runtime.InteropServices.Marshal.ReleaseComObject(element); - } - - _links = new WebCmdletElementCollection(parsedLinks); - } - - return _links; - } - } - - private WebCmdletElementCollection _images; - - /// - /// gets the Images property - /// - public WebCmdletElementCollection Images - { - get - { - if (_images == null) - { - EnsureHtmlParser(); - - List parsedImages = new List(); - foreach (IHTMLElement element in _parsedHtml.images) - { - parsedImages.Add(CreateHtmlObject(element, true)); - System.Runtime.InteropServices.Marshal.ReleaseComObject(element); - } - - _images = new WebCmdletElementCollection(parsedImages); - } - - return _images; - } - } - - private WebCmdletElementCollection _scripts; - - /// - /// gets the Scripts property - /// - public WebCmdletElementCollection Scripts - { - get - { - if (_scripts == null) - { - EnsureHtmlParser(); - - List parsedScripts = new List(); - foreach (IHTMLElement element in _parsedHtml.scripts) - { - parsedScripts.Add(CreateHtmlObject(element, true)); - System.Runtime.InteropServices.Marshal.ReleaseComObject(element); - } - - _scripts = new WebCmdletElementCollection(parsedScripts); - } - - return _scripts; - } - } - - private WebCmdletElementCollection _allElements; - - /// - /// gets the Elements property - /// - public WebCmdletElementCollection AllElements - { - get - { - if (_allElements == null) - { - EnsureHtmlParser(); - - List parsedElements = new List(); - foreach (IHTMLElement element in _parsedHtml.all) - { - parsedElements.Add(CreateHtmlObject(element, true)); - System.Runtime.InteropServices.Marshal.ReleaseComObject(element); - } - - _allElements = new WebCmdletElementCollection(parsedElements); - } - - return _allElements; - } - } - -#endregion Properties - -#region Private Fields - - private static Regex _tagRegex; - private static Regex _attribsRegex; - private static Regex _attribNameValueRegex; - -#endregion Private Fields - -#region Methods - - // The "onreadystatechange" event handler - private void ReadyStateChanged(IHTMLEventObj obj) - { - if (String.Equals("complete", _parsedHtml.readyState, StringComparison.OrdinalIgnoreCase)) - { - _stateChangeResetEvent.Set(); - } - System.Runtime.InteropServices.Marshal.ReleaseComObject(obj); - } - - // Load the document in a worker thread - private void LoadDocumentInMtaThread(Object state) - { - try - { - // Create a new IHTMLDocument2 object - _parsedHtml = (IHTMLDocument2)new HTMLDocument(); - - // Attach the event handler - var events = (HTMLDocumentEvents2_Event)_parsedHtml; - events.onreadystatechange += _onreadystatechangeEventHandler; - - // Write the content and close the document - _parsedHtml.write(Content); - _parsedHtml.close(); - - // Wait for the onReadyStateChange event to be fired. On IE9, this never happens - // so we check the readyState directly as well. - bool wait = true; - while (wait && !_stopWorkerThread) - { - if (String.Equals("complete", _parsedHtml.readyState, StringComparison.OrdinalIgnoreCase)) - { - break; - } - - wait = !_stateChangeResetEvent.Wait(100); - } - - // Detach the event handler - events.onreadystatechange -= _onreadystatechangeEventHandler; - } - catch (Exception e) - { - _parsingException = e; - } - finally - { - _loadDocumentResetEvent.Set(); - } - } - - private void EnsureHtmlParser() - { - if (_htmlParsed == false) - { - // Initialization - _stopWorkerThread = false; - _parsingException = null; - _stateChangeResetEvent = new ManualResetEventSlim(); - _loadDocumentResetEvent = new ManualResetEventSlim(); - _onreadystatechangeEventHandler = new HTMLDocumentEvents2_onreadystatechangeEventHandler(ReadyStateChanged); - - // The IHTMLDocument events cannot be handled in STA ApartmentState, so we use a worker thread to load the document - ThreadPool.QueueUserWorkItem(new WaitCallback(LoadDocumentInMtaThread)); - - // Wait for the worker thread to finish loading the document. In the meantime, we check the Ctrl-C every 500ms - bool wait = true; - while (wait) - { - if (_executionContext.CurrentPipelineStopping) - { - // Signal and wait for the worker thread to exit, then break out the loop - _stopWorkerThread = true; - _loadDocumentResetEvent.Wait(); - break; - } - - wait = !_loadDocumentResetEvent.Wait(500); - } - - // Ctrl-C is typed - if (_executionContext.CurrentPipelineStopping) - { - throw new PipelineStoppedException(); - } - - // If there is no Ctrl-C, throw if an exception happened during the parsing - if (_parsingException != null) - { - throw _parsingException; - } - - // Parsing was successful - _htmlParsed = true; - } - - if (_tagRegex == null) - { - _tagRegex = new Regex(@"<\w+((\s+[^""'>/=\s\p{Cc}]+(\s*=\s*(?:"".*?""|'.*?'|[^'"">\s]+))?)+\s*|\s*)/?>", - RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Compiled); - } - - if (_attribsRegex == null) - { - _attribsRegex = new Regex(@"(?<=\s+)([^""'>/=\s\p{Cc}]+(\s*=\s*(?:"".*?""|'.*?'|[^'"">\s]+))?)", - RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Compiled); - } - - if (_attribNameValueRegex == null) - { - _attribNameValueRegex = new Regex(@"([^""'>/=\s\p{Cc}]+)(?:\s*=\s*(?:""(.*?)""|'(.*?)'|([^'"">\s]+)))?", - RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Compiled); - } - } - - private PSObject CreateHtmlObject(IHTMLElement element, bool addTagName) - { - PSObject elementObject = new PSObject(); - - elementObject.Properties.Add(new PSNoteProperty("innerHTML", element.innerHTML)); - elementObject.Properties.Add(new PSNoteProperty("innerText", element.innerText)); - elementObject.Properties.Add(new PSNoteProperty("outerHTML", element.outerHTML)); - elementObject.Properties.Add(new PSNoteProperty("outerText", element.outerText)); - if (addTagName) - { - elementObject.Properties.Add(new PSNoteProperty("tagName", element.tagName)); - } - - ParseAttributes(element.outerHTML, elementObject); - - return elementObject; - } - - - private void ParseAttributes(string outerHtml, PSObject elementObject) - { - // We might get an empty input for a directive from the HTML file - if (!string.IsNullOrEmpty(outerHtml)) - { - // Extract just the opening tag of the HTML element (omitting the closing tag and any contents, - // including contained HTML elements) - var match = _tagRegex.Match(outerHtml); - - // Extract all the attribute specifications within the HTML element opening tag - var attribMatches = _attribsRegex.Matches(match.Value); - - foreach (Match attribMatch in attribMatches) - { - // Extract the name and value for this attribute (allowing for variations like single/double/no - // quotes, and no value at all) - var nvMatches = _attribNameValueRegex.Match(attribMatch.Value); - Debug.Assert(nvMatches.Groups.Count == 5); - - // Name is always captured by group #1 - string name = nvMatches.Groups[1].Value; - - // The value (if any) is captured by group #2, #3, or #4, depending on quoting or lack thereof - string value = null; - if (nvMatches.Groups[2].Success) - { - value = nvMatches.Groups[2].Value; - } - else if (nvMatches.Groups[3].Success) - { - value = nvMatches.Groups[3].Value; - } - else if (nvMatches.Groups[4].Success) - { - value = nvMatches.Groups[4].Value; - } - - elementObject.Properties.Add(new PSNoteProperty(name, value)); - } - } - } - - private FormObjectCollection BuildFormsCollection() - { - FormObjectCollection forms = new FormObjectCollection(); - - EnsureHtmlParser(); - foreach (IHTMLFormElement form in _parsedHtml.forms) - { - string id = GetElementId(form as IHTMLElement); - if (null == id) - { - id = form.name; - } - - FormObject f = new FormObject(id, form.method, form.action); - foreach (IHTMLElement element in form) - { - IHTMLInputElement input = element as IHTMLInputElement; - if (null != input) - { - id = GetElementId(input as IHTMLElement); - if (null == id) - { - id = input.name; - } - - f.AddField(id, input.value); - } - - System.Runtime.InteropServices.Marshal.ReleaseComObject(element); - } - - forms.Add(f); - - System.Runtime.InteropServices.Marshal.ReleaseComObject(form); - } - - return (forms); - } - - private string GetElementId(IHTMLElement element) - { - return (null == element ? null : element.id); - } - - /// - /// Reads the response content from the web response. - /// - private void InitializeContent() - { - string contentType = ContentHelper.GetContentType(BaseResponse); - if (ContentHelper.IsText(contentType)) - { - // fill the Content buffer - string characterSet = WebResponseHelper.GetCharacterSet(BaseResponse); - this.Content = StreamHelper.DecodeStream(RawContentStream, characterSet); - } - else - { - this.Content = string.Empty; - } - } -#endregion Methods - - /// - /// Dispose the the instance of the class. - /// - public void Dispose() - { - CleanupNativeResources(); - - if (_loadDocumentResetEvent != null) - { - _loadDocumentResetEvent.Dispose(); - } - if (_stateChangeResetEvent != null) - { - _stateChangeResetEvent.Dispose(); - } - - GC.SuppressFinalize(this); - } - - /// - /// Finalizer to free the COM objects. - /// - ~HtmlWebResponseObject() - { - CleanupNativeResources(); - } - - private void CleanupNativeResources() - { - if (_parsedHtml != null) - { - System.Runtime.InteropServices.Marshal.ReleaseComObject(_parsedHtml); - } - } - } -} -#endif \ No newline at end of file diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/InvokeRestMethodCommand.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/InvokeRestMethodCommand.Common.cs index e9a73b46970..69b251b627f 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/InvokeRestMethodCommand.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/InvokeRestMethodCommand.Common.cs @@ -1,11 +1,14 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; using System.IO; using System.Xml; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System.Net.Http; +using System.Text; namespace Microsoft.PowerShell.Commands { @@ -168,16 +171,28 @@ private bool TryConvertToXml(string xml, out object doc, ref Exception exRef) private bool TryConvertToJson(string json, out object obj, ref Exception exRef) { + bool converted = false; try { ErrorRecord error; obj = JsonObject.ConvertFromJson(json, out error); + if (null == obj) + { + // This ensures that a null returned by ConvertFromJson() is the actual JSON null literal. + // if not, the ArgumentException will be caught. + JToken.Parse(json); + } + if (error != null) { exRef = error.Exception; obj = null; } + else + { + converted = true; + } } catch (ArgumentException ex) { @@ -189,7 +204,13 @@ private bool TryConvertToJson(string json, out object obj, ref Exception exRef) exRef = ex; obj = null; } - return (null != obj); + catch (JsonException ex) + { + var msg = string.Format(System.Globalization.CultureInfo.CurrentCulture, WebCmdletStrings.JsonDeserializationFailed, ex.Message); + exRef = new ArgumentException(msg, ex); + obj = null; + } + return converted; } #endregion @@ -323,4 +344,131 @@ public override void Write(byte[] buffer, int offset, int count) } } } -} \ No newline at end of file + + // TODO: Merge Partials + + /// + /// The Invoke-RestMethod command + /// This command makes an HTTP or HTTPS request to a web service, + /// and returns the response in an appropriate way. + /// Intended to work against the wide spectrum of "RESTful" web services + /// currently deployed across the web. + /// + [Cmdlet(VerbsLifecycle.Invoke, "RestMethod", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=217034", DefaultParameterSetName = "StandardMethod")] + public partial class InvokeRestMethodCommand : WebRequestPSCmdlet + { + #region Virtual Method Overrides + + /// + /// Process the web response and output corresponding objects. + /// + /// + internal override void ProcessResponse(HttpResponseMessage response) + { + if (null == response) { throw new ArgumentNullException("response"); } + + using (BufferingStreamReader responseStream = new BufferingStreamReader(StreamHelper.GetResponseStream(response))) + { + if (ShouldWriteToPipeline) + { + // First see if it is an RSS / ATOM feed, in which case we can + // stream it - unless the user has overridden it with a return type of "XML" + if (TryProcessFeedStream(responseStream)) + { + // Do nothing, content has been processed. + } + else + { + // determine the response type + RestReturnType returnType = CheckReturnType(response); + + // Try to get the response encoding from the ContentType header. + Encoding encoding = null; + string charSet = response.Content.Headers.ContentType?.CharSet; + if (!string.IsNullOrEmpty(charSet)) + { + // NOTE: Don't use ContentHelper.GetEncoding; it returns a + // default which bypasses checking for a meta charset value. + StreamHelper.TryGetEncoding(charSet, out encoding); + } + + if (string.IsNullOrEmpty(charSet) && returnType == RestReturnType.Json) + { + encoding = Encoding.UTF8; + } + + object obj = null; + Exception ex = null; + + string str = StreamHelper.DecodeStream(responseStream, ref encoding); + // NOTE: Tests use this verbose output to verify the encoding. + WriteVerbose(string.Format + ( + System.Globalization.CultureInfo.InvariantCulture, + "Content encoding: {0}", + string.IsNullOrEmpty(encoding.HeaderName) ? encoding.EncodingName : encoding.HeaderName) + ); + bool convertSuccess = false; + + if (returnType == RestReturnType.Json) + { + convertSuccess = TryConvertToJson(str, out obj, ref ex) || TryConvertToXml(str, out obj, ref ex); + } + // default to try xml first since it's more common + else + { + convertSuccess = TryConvertToXml(str, out obj, ref ex) || TryConvertToJson(str, out obj, ref ex); + } + + if (!convertSuccess) + { + // fallback to string + obj = str; + } + + WriteObject(obj); + } + } + + if (ShouldSaveToOutFile) + { + StreamHelper.SaveStreamToFile(responseStream, QualifiedOutFile, this); + } + + if (!String.IsNullOrEmpty(ResponseHeadersVariable)) + { + PSVariableIntrinsics vi = SessionState.PSVariable; + vi.Set(ResponseHeadersVariable, WebResponseHelper.GetHeadersDictionary(response)); + } + } + } + + #endregion Virtual Method Overrides + + #region Helper Methods + + private RestReturnType CheckReturnType(HttpResponseMessage response) + { + if (null == response) { throw new ArgumentNullException("response"); } + + RestReturnType rt = RestReturnType.Detect; + string contentType = ContentHelper.GetContentType(response); + if (string.IsNullOrEmpty(contentType)) + { + rt = RestReturnType.Detect; + } + else if (ContentHelper.IsJson(contentType)) + { + rt = RestReturnType.Json; + } + else if (ContentHelper.IsXml(contentType)) + { + rt = RestReturnType.Xml; + } + + return (rt); + } + + #endregion Helper Methods + } +} diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index e9eb8f77e56..435eafb79b8 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.ObjectModel; @@ -10,15 +9,76 @@ using System.Text; using System.Collections; using System.Globalization; +using System.Security; +using System.Security.Authentication; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; -#if !CORECLR -using mshtml; -#endif using Microsoft.Win32; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading; +using System.Xml; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using System.Linq; namespace Microsoft.PowerShell.Commands { + /// + /// The valid values for the -Authentication parameter for Invoke-RestMethod and Invoke-WebRequest + /// + public enum WebAuthenticationType + { + /// + /// No authentication. Default. + /// + None, + + /// + /// RFC-7617 Basic Authentication. Requires -Credential + /// + Basic, + + /// + /// RFC-6750 OAuth 2.0 Bearer Authentication. Requires -Token + /// + Bearer, + + /// + /// RFC-6750 OAuth 2.0 Bearer Authentication. Requires -Token + /// + OAuth, + } + + // WebSslProtocol is used because not all SslProtocols are supported by HttpClientHandler. + // Also SslProtocols.Default is not the "default" for HttpClientHandler as SslProtocols.Ssl3 is not supported. + /// + /// The valid values for the -SslProtocol parameter for Invoke-RestMethod and Invoke-WebRequest + /// + [Flags] + public enum WebSslProtocol + { + /// + /// No SSL protocol will be set and the system defaults will be used. + /// + Default = 0, + + /// + /// Specifies the TLS 1.0 security protocol. The TLS protocol is defined in IETF RFC 2246. + /// + Tls = SslProtocols.Tls, + + /// + /// Specifies the TLS 1.1 security protocol. The TLS protocol is defined in IETF RFC 4346. + /// + Tls11 = SslProtocols.Tls11, + + /// + /// Specifies the TLS 1.2 security protocol. The TLS protocol is defined in IETF RFC 5246 + /// + Tls12 = SslProtocols.Tls12 + } + /// /// Base class for Invoke-RestMethod and Invoke-WebRequest commands. /// @@ -29,10 +89,10 @@ public abstract partial class WebRequestPSCmdlet : PSCmdlet #region URI /// - /// gets or sets the parameter UseBasicParsing + /// Deprecated. Gets or sets UseBasicParsing. This has no affect on the operation of the Cmdlet. /// - [Parameter] - public virtual SwitchParameter UseBasicParsing { get; set; } + [Parameter(DontShow = true)] + public virtual SwitchParameter UseBasicParsing { get; set; } = true; /// /// gets or sets the Uri property @@ -61,6 +121,22 @@ public abstract partial class WebRequestPSCmdlet : PSCmdlet #region Authorization and Credentials + /// + /// Gets or sets the AllowUnencryptedAuthentication property + /// + [Parameter] + public virtual SwitchParameter AllowUnencryptedAuthentication { get; set; } + + /// + /// Gets or sets the Authentication property used to determin the Authentication method for the web session. + /// Authentication does not work with UseDefaultCredentials. + /// Authentication over unencrypted sessions requires AllowUnencryptedAuthentication. + /// Basic: Requires Credential + /// OAuth/Bearer: Requires Token + /// + [Parameter] + public virtual WebAuthenticationType Authentication { get; set; } = WebAuthenticationType.None; + /// /// gets or sets the Credential property /// @@ -94,6 +170,18 @@ public abstract partial class WebRequestPSCmdlet : PSCmdlet [Parameter] public virtual SwitchParameter SkipCertificateCheck { get; set; } + /// + /// Gets or sets the TLS/SSL protocol used by the Web Cmdlet + /// + [Parameter] + public virtual WebSslProtocol SslProtocol { get; set; } = WebSslProtocol.Default; + + /// + /// Gets or sets the Token property. Token is required by Authentication OAuth and Bearer. + /// + [Parameter] + public virtual SecureString Token { get; set; } + #endregion #region Headers @@ -217,6 +305,14 @@ public virtual string CustomMethod [Parameter(ValueFromPipeline = true)] public virtual object Body { get; set; } + /// + /// Dictionary for use with RFC-7578 multipart/form-data submissions. + /// Keys are form fields and their respective values are form values. + /// A value may be a collection of form values or single form value. + /// + [Parameter] + public virtual IDictionary Form {get; set;} + /// /// gets or sets the ContentType property /// @@ -258,6 +354,12 @@ public virtual string CustomMethod [Parameter] public virtual SwitchParameter PassThru { get; set; } + /// + /// Resumes downloading a partial or incomplete file. OutFile is required. + /// + [Parameter] + public virtual SwitchParameter Resume { get; set; } + #endregion #endregion Virtual Properties @@ -274,6 +376,44 @@ internal virtual void ValidateParameters() ThrowTerminatingError(error); } + // Authentication + if (UseDefaultCredentials && (Authentication != WebAuthenticationType.None)) + { + ErrorRecord error = GetValidationError(WebCmdletStrings.AuthenticationConflict, + "WebCmdletAuthenticationConflictException"); + ThrowTerminatingError(error); + } + if ((Authentication != WebAuthenticationType.None) && (null != Token) && (null != Credential)) + { + ErrorRecord error = GetValidationError(WebCmdletStrings.AuthenticationTokenConflict, + "WebCmdletAuthenticationTokenConflictException"); + ThrowTerminatingError(error); + } + if ((Authentication == WebAuthenticationType.Basic) && (null == Credential)) + { + ErrorRecord error = GetValidationError(WebCmdletStrings.AuthenticationCredentialNotSupplied, + "WebCmdletAuthenticationCredentialNotSuppliedException"); + ThrowTerminatingError(error); + } + if ((Authentication == WebAuthenticationType.OAuth || Authentication == WebAuthenticationType.Bearer) && (null == Token)) + { + ErrorRecord error = GetValidationError(WebCmdletStrings.AuthenticationTokenNotSupplied, + "WebCmdletAuthenticationTokenNotSuppliedException"); + ThrowTerminatingError(error); + } + if (!AllowUnencryptedAuthentication && (Authentication != WebAuthenticationType.None) && (Uri.Scheme != "https")) + { + ErrorRecord error = GetValidationError(WebCmdletStrings.AllowUnencryptedAuthenticationRequired, + "WebCmdletAllowUnencryptedAuthenticationRequiredException"); + ThrowTerminatingError(error); + } + if (!AllowUnencryptedAuthentication && (null != Credential || UseDefaultCredentials) && (Uri.Scheme != "https")) + { + ErrorRecord error = GetValidationError(WebCmdletStrings.AllowUnencryptedAuthenticationRequired, + "WebCmdletAllowUnencryptedAuthenticationRequiredException"); + ThrowTerminatingError(error); + } + // credentials if (UseDefaultCredentials && (null != Credential)) { @@ -303,6 +443,18 @@ internal virtual void ValidateParameters() "WebCmdletBodyConflictException"); ThrowTerminatingError(error); } + if ((null != Body) && (null != Form)) + { + ErrorRecord error = GetValidationError(WebCmdletStrings.BodyFormConflict, + "WebCmdletBodyFormConflictException"); + ThrowTerminatingError(error); + } + if ((null != InFile) && (null != Form)) + { + ErrorRecord error = GetValidationError(WebCmdletStrings.FormInFileConflict, + "WebCmdletFormInFileConflictException"); + ThrowTerminatingError(error); + } // validate InFile path if (InFile != null) @@ -335,7 +487,7 @@ internal virtual void ValidateParameters() { if (Directory.Exists(providerPaths[0])) { - errorRecord = GetValidationError(WebCmdletStrings.DirecotryPathSpecified, + errorRecord = GetValidationError(WebCmdletStrings.DirectoryPathSpecified, "WebCmdletInFileNotFilePathException", InFile); } _originalFilePath = InFile; @@ -366,7 +518,15 @@ internal virtual void ValidateParameters() if (PassThru && (OutFile == null)) { ErrorRecord error = GetValidationError(WebCmdletStrings.OutFileMissing, - "WebCmdletOutFileMissingException"); + "WebCmdletOutFileMissingException", nameof(PassThru)); + ThrowTerminatingError(error); + } + + // Resume requires OutFile. + if (Resume.IsPresent && OutFile == null) + { + ErrorRecord error = GetValidationError(WebCmdletStrings.OutFileMissing, + "WebCmdletOutFileMissingException", nameof(Resume)); ThrowTerminatingError(error); } } @@ -389,7 +549,7 @@ internal virtual void PrepareSession() // // handle credentials // - if (null != Credential) + if (null != Credential && Authentication == WebAuthenticationType.None) { // get the relevant NetworkCredential NetworkCredential netCred = Credential.GetNetworkCredential(); @@ -398,12 +558,15 @@ internal virtual void PrepareSession() // supplying a credential overrides the UseDefaultCredentials setting WebSession.UseDefaultCredentials = false; } + else if ((null != Credential || null!= Token) && Authentication != WebAuthenticationType.None) + { + ProcessAuthentication(); + } else if (UseDefaultCredentials) { WebSession.UseDefaultCredentials = true; } - if (null != CertificateThumbprint) { X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser); @@ -488,84 +651,17 @@ internal bool ShouldWriteToPipeline get { return (!ShouldSaveToOutFile || PassThru); } } - #endregion Helper Properties - - #region Helper Methods - /// - /// Verifies that Internet Explorer is available, and that its first-run - /// configuration is complete. + /// Determines whether writing to a file should Resume and append rather than overwrite. /// - /// True if we should try to access IE's COM object. Not - /// needed if an HtmlDocument will be created shortly. - protected bool VerifyInternetExplorerAvailable(bool checkComObject) + internal bool ShouldResume { - // TODO: Remove this code once the dependency on mshtml has been resolved. -#if CORECLR - return false; -#else - bool isInternetExplorerConfigurationComplete = false; - // Check for IE for both PS Full and PS Core on windows. - // The registry key DisableFirstRunCustomize can exits at one of the following path. - // IE uses the same descending order (as mentioned) to check for the presence of this key. - // If the value of DisableFirstRunCustomize key is set to greater than zero then Run first - // is disabled. - string[] disableFirstRunCustomizePaths = new string[] { - @"HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Main", - @"HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Main", - @"HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main", - @"HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main" }; - - foreach (string currentRegPath in disableFirstRunCustomizePaths) - { - object val = Registry.GetValue(currentRegPath, "DisableFirstRunCustomize", string.Empty); - if (val != null && !string.Empty.Equals(val) && Convert.ToInt32(val, CultureInfo.InvariantCulture) > 0) - { - isInternetExplorerConfigurationComplete = true; - break; - } - } - - if (!isInternetExplorerConfigurationComplete) - { - // Verify that if IE is installed, it has been through the RunOnce check. - // Otherwise, the call will hang waiting for users to go through First Run - // personalization. - using (RegistryKey key = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Internet Explorer\\Main")) - { - if (key != null) - { - foreach (string setting in key.GetValueNames()) - { - if (setting.IndexOf("RunOnce", StringComparison.OrdinalIgnoreCase) > -1) - { - isInternetExplorerConfigurationComplete = true; - break; - } - } - } - } - } + get { return (Resume.IsPresent && _resumeSuccess); } + } - if (isInternetExplorerConfigurationComplete && checkComObject) - { - try - { - IHTMLDocument2 ieCheck = (IHTMLDocument2)new HTMLDocument(); - System.Runtime.InteropServices.Marshal.ReleaseComObject(ieCheck); - } - catch (System.Runtime.InteropServices.COMException) - { - isInternetExplorerConfigurationComplete = false; - } - } + #endregion Helper Properties - // Throw exception in PS Full only - if (!isInternetExplorerConfigurationComplete) - throw new NotSupportedException(WebCmdletStrings.IEDomNotSupported); - return isInternetExplorerConfigurationComplete; -#endif - } + #region Helper Methods private Uri PrepareUri(Uri uri) { @@ -660,12 +756,1105 @@ private bool IsStandardMethodSet() { return (ParameterSetName == "StandardMethod"); } - + private bool IsCustomMethodSet() { return (ParameterSetName == "CustomMethod"); } + private string GetBasicAuthorizationHeader() + { + string unencoded = String.Format("{0}:{1}", Credential.UserName, Credential.GetNetworkCredential().Password); + Byte[] bytes = Encoding.UTF8.GetBytes(unencoded); + return String.Format("Basic {0}", Convert.ToBase64String(bytes)); + } + + private string GetBearerAuthorizationHeader() + { + return String.Format("Bearer {0}", new NetworkCredential(String.Empty, Token).Password); + } + + private void ProcessAuthentication() + { + if(Authentication == WebAuthenticationType.Basic) + { + WebSession.Headers["Authorization"] = GetBasicAuthorizationHeader(); + } + else if (Authentication == WebAuthenticationType.Bearer || Authentication == WebAuthenticationType.OAuth) + { + WebSession.Headers["Authorization"] = GetBearerAuthorizationHeader(); + } + else + { + Diagnostics.Assert(false, String.Format("Unrecognized Authentication value: {0}", Authentication)); + } + } + + #endregion Helper Methods + } + + // TODO: Merge Partials + + /// + /// Exception class for webcmdlets to enable returning HTTP error response + /// + public sealed class HttpResponseException : HttpRequestException + { + /// + /// Constructor for HttpResponseException + /// + /// Message for the exception + /// Response from the HTTP server + public HttpResponseException (string message, HttpResponseMessage response) : base(message) + { + Response = response; + } + + /// + /// HTTP error response + /// + public HttpResponseMessage Response { get; private set; } + } + + /// + /// Base class for Invoke-RestMethod and Invoke-WebRequest commands. + /// + public abstract partial class WebRequestPSCmdlet : PSCmdlet + { + + /// + /// gets or sets the PreserveAuthorizationOnRedirect property + /// + /// + /// This property overrides compatibility with web requests on Windows. + /// On FullCLR (WebRequest), authorization headers are stripped during redirect. + /// CoreCLR (HTTPClient) does not have this behavior so web requests that work on + /// PowerShell/FullCLR can fail with PowerShell/CoreCLR. To provide compatibility, + /// we'll detect requests with an Authorization header and automatically strip + /// the header when the first redirect occurs. This switch turns off this logic for + /// edge cases where the authorization header needs to be preserved across redirects. + /// + [Parameter] + public virtual SwitchParameter PreserveAuthorizationOnRedirect { get; set; } + + /// + /// gets or sets the SkipHeaderValidation property + /// + /// + /// This property adds headers to the request's header collection without validation. + /// + [Parameter] + public virtual SwitchParameter SkipHeaderValidation { get; set; } + + #region Abstract Methods + + /// + /// Read the supplied WebResponse object and push the + /// resulting output into the pipeline. + /// + /// Instance of a WebResponse object to be processed + internal abstract void ProcessResponse(HttpResponseMessage response); + + #endregion Abstract Methods + + /// + /// Cancellation token source + /// + private CancellationTokenSource _cancelToken = null; + + /// + /// Parse Rel Links + /// + internal bool _parseRelLink = false; + + /// + /// Automatically follow Rel Links + /// + internal bool _followRelLink = false; + + /// + /// Automatically follow Rel Links + /// + internal Dictionary _relationLink = null; + + /// + /// Maximum number of Rel Links to follow + /// + internal int _maximumFollowRelLink = Int32.MaxValue; + + /// + /// The remote endpoint returned a 206 status code indicating successful resume. + /// + private bool _resumeSuccess = false; + + /// + /// The current size of the local file being resumed. + /// + private long _resumeFileSize = 0; + + private HttpMethod GetHttpMethod(WebRequestMethod method) + { + switch (Method) + { + case WebRequestMethod.Default: + case WebRequestMethod.Get: + return HttpMethod.Get; + case WebRequestMethod.Head: + return HttpMethod.Head; + case WebRequestMethod.Post: + return HttpMethod.Post; + case WebRequestMethod.Put: + return HttpMethod.Put; + case WebRequestMethod.Delete: + return HttpMethod.Delete; + case WebRequestMethod.Trace: + return HttpMethod.Trace; + case WebRequestMethod.Options: + return HttpMethod.Options; + default: + // Merge and Patch + return new HttpMethod(Method.ToString().ToUpperInvariant()); + } + } + + #region Virtual Methods + + // NOTE: Only pass true for handleRedirect if the original request has an authorization header + // and PreserveAuthorizationOnRedirect is NOT set. + internal virtual HttpClient GetHttpClient(bool handleRedirect) + { + // By default the HttpClientHandler will automatically decompress GZip and Deflate content + HttpClientHandler handler = new HttpClientHandler(); + handler.CookieContainer = WebSession.Cookies; + + // set the credentials used by this request + if (WebSession.UseDefaultCredentials) + { + // the UseDefaultCredentials flag overrides other supplied credentials + handler.UseDefaultCredentials = true; + } + else if (WebSession.Credentials != null) + { + handler.Credentials = WebSession.Credentials; + } + + if (NoProxy) + { + handler.UseProxy = false; + } + else if (WebSession.Proxy != null) + { + handler.Proxy = WebSession.Proxy; + } + + if (null != WebSession.Certificates) + { + handler.ClientCertificates.AddRange(WebSession.Certificates); + } + + if (SkipCertificateCheck) + { + handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; + handler.ClientCertificateOptions = ClientCertificateOption.Manual; + } + + // This indicates GetResponse will handle redirects. + if (handleRedirect) + { + handler.AllowAutoRedirect = false; + } + else if (WebSession.MaximumRedirection > -1) + { + if (WebSession.MaximumRedirection == 0) + { + handler.AllowAutoRedirect = false; + } + else + { + handler.MaxAutomaticRedirections = WebSession.MaximumRedirection; + } + } + + handler.SslProtocols = (SslProtocols)SslProtocol; + + HttpClient httpClient = new HttpClient(handler); + + // check timeout setting (in seconds instead of milliseconds as in HttpWebRequest) + if (TimeoutSec == 0) + { + // A zero timeout means infinite + httpClient.Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite); + } + else if (TimeoutSec > 0) + { + httpClient.Timeout = new TimeSpan(0, 0, TimeoutSec); + } + + return httpClient; + } + + internal virtual HttpRequestMessage GetRequest(Uri uri, bool stripAuthorization) + { + Uri requestUri = PrepareUri(uri); + HttpMethod httpMethod = null; + + switch (ParameterSetName) + { + case "StandardMethodNoProxy": + goto case "StandardMethod"; + case "StandardMethod": + // set the method if the parameter was provided + httpMethod = GetHttpMethod(Method); + break; + case "CustomMethodNoProxy": + goto case "CustomMethod"; + case "CustomMethod": + if (!string.IsNullOrEmpty(CustomMethod)) + { + // set the method if the parameter was provided + httpMethod = new HttpMethod(CustomMethod.ToString().ToUpperInvariant()); + } + break; + } + + // create the base WebRequest object + var request = new HttpRequestMessage(httpMethod, requestUri); + + // pull in session data + if (WebSession.Headers.Count > 0) + { + WebSession.ContentHeaders.Clear(); + foreach (var entry in WebSession.Headers) + { + if (HttpKnownHeaderNames.ContentHeaders.Contains(entry.Key)) + { + WebSession.ContentHeaders.Add(entry.Key, entry.Value); + } + else + { + if (stripAuthorization + && + String.Equals(entry.Key, HttpKnownHeaderNames.Authorization.ToString(), StringComparison.OrdinalIgnoreCase) + ) + { + continue; + } + + if (SkipHeaderValidation) + { + request.Headers.TryAddWithoutValidation(entry.Key, entry.Value); + } + else + { + request.Headers.Add(entry.Key, entry.Value); + } + } + } + } + + // Set 'Transfer-Encoding: chunked' if 'Transfer-Encoding' is specified + if (WebSession.Headers.ContainsKey(HttpKnownHeaderNames.TransferEncoding)) + { + request.Headers.TransferEncodingChunked = true; + } + + // Set 'User-Agent' if WebSession.Headers doesn't already contain it + string userAgent = null; + if (WebSession.Headers.TryGetValue(HttpKnownHeaderNames.UserAgent, out userAgent)) + { + WebSession.UserAgent = userAgent; + } + else + { + if (SkipHeaderValidation) + { + request.Headers.TryAddWithoutValidation(HttpKnownHeaderNames.UserAgent, WebSession.UserAgent); + } + else + { + request.Headers.Add(HttpKnownHeaderNames.UserAgent, WebSession.UserAgent); + } + + } + + // Set 'Keep-Alive' to false. This means set the Connection to 'Close'. + if (DisableKeepAlive) + { + request.Headers.Add(HttpKnownHeaderNames.Connection, "Close"); + } + + // Set 'Transfer-Encoding' + if (TransferEncoding != null) + { + request.Headers.TransferEncodingChunked = true; + var headerValue = new TransferCodingHeaderValue(TransferEncoding); + if (!request.Headers.TransferEncoding.Contains(headerValue)) + { + request.Headers.TransferEncoding.Add(headerValue); + } + } + + // If the file to resume downloading exists, create the Range request header using the file size. + // If not, create a Range to request the entire file. + if (Resume.IsPresent) + { + var fileInfo = new FileInfo(QualifiedOutFile); + if (fileInfo.Exists) + { + request.Headers.Range = new RangeHeaderValue(fileInfo.Length, null); + _resumeFileSize = fileInfo.Length; + } + else + { + request.Headers.Range = new RangeHeaderValue(0, null); + } + } + + // Some web sites (e.g. Twitter) will return exception on POST when Expect100 is sent + // Default behavior is continue to send body content anyway after a short period + // Here it send the two part as a whole. + request.Headers.ExpectContinue = false; + + return (request); + } + + internal virtual void FillRequestStream(HttpRequestMessage request) + { + if (null == request) { throw new ArgumentNullException("request"); } + + // set the content type + if (ContentType != null) + { + WebSession.ContentHeaders[HttpKnownHeaderNames.ContentType] = ContentType; + //request + } + // ContentType == null + else if (Method == WebRequestMethod.Post || (IsCustomMethodSet() && CustomMethod.ToUpperInvariant() == "POST")) + { + // Win8:545310 Invoke-WebRequest does not properly set MIME type for POST + string contentType = null; + WebSession.ContentHeaders.TryGetValue(HttpKnownHeaderNames.ContentType, out contentType); + if (string.IsNullOrEmpty(contentType)) + { + WebSession.ContentHeaders[HttpKnownHeaderNames.ContentType] = "application/x-www-form-urlencoded"; + } + } + + if (null != Form) + { + // Content headers will be set by MultipartFormDataContent which will throw unless we clear them first + WebSession.ContentHeaders.Clear(); + + var formData = new MultipartFormDataContent(); + foreach (DictionaryEntry formEntry in Form) + { + // AddMultipartContent will handle PSObject unwrapping, Object type determination and enumerateing top level IEnumerables. + AddMultipartContent(fieldName: formEntry.Key, fieldValue: formEntry.Value, formData: formData, enumerate: true); + } + SetRequestContent(request, formData); + } + // coerce body into a usable form + else if (Body != null) + { + object content = Body; + + // make sure we're using the base object of the body, not the PSObject wrapper + PSObject psBody = Body as PSObject; + if (psBody != null) + { + content = psBody.BaseObject; + } + + if (content is FormObject) + { + FormObject form = content as FormObject; + SetRequestContent(request, form.Fields); + } + else if (content is IDictionary && request.Method != HttpMethod.Get) + { + IDictionary dictionary = content as IDictionary; + SetRequestContent(request, dictionary); + } + else if (content is XmlNode) + { + XmlNode xmlNode = content as XmlNode; + SetRequestContent(request, xmlNode); + } + else if (content is Stream) + { + Stream stream = content as Stream; + SetRequestContent(request, stream); + } + else if (content is byte[]) + { + byte[] bytes = content as byte[]; + SetRequestContent(request, bytes); + } + else if (content is MultipartFormDataContent multipartFormDataContent) + { + WebSession.ContentHeaders.Clear(); + SetRequestContent(request, multipartFormDataContent); + } + else + { + SetRequestContent(request, + (string)LanguagePrimitives.ConvertTo(content, typeof(string), CultureInfo.InvariantCulture)); + } + } + else if (InFile != null) // copy InFile data + { + try + { + // open the input file + SetRequestContent(request, new FileStream(InFile, FileMode.Open)); + } + catch (UnauthorizedAccessException) + { + string msg = string.Format(CultureInfo.InvariantCulture, WebCmdletStrings.AccessDenied, + _originalFilePath); + throw new UnauthorizedAccessException(msg); + } + } + + // Add the content headers + if (request.Content != null) + { + foreach (var entry in WebSession.ContentHeaders) + { + if (SkipHeaderValidation) + { + request.Content.Headers.TryAddWithoutValidation(entry.Key, entry.Value); + } + else + { + try + { + request.Content.Headers.Add(entry.Key, entry.Value); + } + catch (FormatException ex) + { + var outerEx = new ValidationMetadataException(WebCmdletStrings.ContentTypeException, ex); + ErrorRecord er = new ErrorRecord(outerEx, "WebCmdletContentTypeException", ErrorCategory.InvalidArgument, ContentType); + ThrowTerminatingError(er); + } + } + } + } + } + + // Returns true if the status code is one of the supported redirection codes. + static bool IsRedirectCode(HttpStatusCode code) + { + int intCode = (int) code; + return + ( + (intCode >= 300 && intCode < 304) + || + intCode == 307 + ); + } + + // Returns true if the status code is a redirection code and the action requires switching from POST to GET on redirection. + // NOTE: Some of these status codes map to the same underlying value but spelling them out for completeness. + static bool IsRedirectToGet(HttpStatusCode code) + { + return + ( + code == HttpStatusCode.Found + || + code == HttpStatusCode.Moved + || + code == HttpStatusCode.Redirect + || + code == HttpStatusCode.RedirectMethod + || + code == HttpStatusCode.TemporaryRedirect + || + code == HttpStatusCode.RedirectKeepVerb + || + code == HttpStatusCode.SeeOther + ); + } + + internal virtual HttpResponseMessage GetResponse(HttpClient client, HttpRequestMessage request, bool stripAuthorization) + { + if (client == null) { throw new ArgumentNullException("client"); } + if (request == null) { throw new ArgumentNullException("request"); } + + // Track the current URI being used by various requests and re-requests. + var currentUri = request.RequestUri; + + _cancelToken = new CancellationTokenSource(); + HttpResponseMessage response = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, _cancelToken.Token).GetAwaiter().GetResult(); + + if (stripAuthorization && IsRedirectCode(response.StatusCode) && response.Headers.Location != null) + { + _cancelToken.Cancel(); + _cancelToken = null; + + // if explicit count was provided, reduce it for this redirection. + if (WebSession.MaximumRedirection > 0) + { + WebSession.MaximumRedirection--; + } + // For selected redirects that used POST, GET must be used with the + // redirected Location. + // Since GET is the default; POST only occurs when -Method POST is used. + if (Method == WebRequestMethod.Post && IsRedirectToGet(response.StatusCode)) + { + // See https://msdn.microsoft.com/en-us/library/system.net.httpstatuscode(v=vs.110).aspx + Method = WebRequestMethod.Get; + } + + // recreate the HttpClient with redirection enabled since the first call suppressed redirection + currentUri = new Uri(request.RequestUri, response.Headers.Location); + using (client = GetHttpClient(false)) + using (HttpRequestMessage redirectRequest = GetRequest(currentUri, stripAuthorization:true)) + { + FillRequestStream(redirectRequest); + _cancelToken = new CancellationTokenSource(); + response = client.SendAsync(redirectRequest, HttpCompletionOption.ResponseHeadersRead, _cancelToken.Token).GetAwaiter().GetResult(); + } + } + + // Request again without the Range header because the server indicated the range was not satisfiable. + // This happens when the local file is larger than the remote file. + // If the size of the remote file is the same as the local file, there is nothing to resume. + if (Resume.IsPresent && + response.StatusCode == HttpStatusCode.RequestedRangeNotSatisfiable && + (response.Content.Headers.ContentRange.HasLength && + response.Content.Headers.ContentRange.Length != _resumeFileSize)) + { + _cancelToken.Cancel(); + + WriteVerbose(WebCmdletStrings.WebMethodResumeFailedVerboseMsg); + + // Disable the Resume switch so the subsequent calls to GetResponse() and FillRequestStream() + // are treated as a standard -OutFile request. This also disables appending local file. + Resume = new SwitchParameter(false); + + using (HttpRequestMessage requestWithoutRange = GetRequest(currentUri, stripAuthorization:false)) + { + FillRequestStream(requestWithoutRange); + long requestContentLength = 0; + if (requestWithoutRange.Content != null) + requestContentLength = requestWithoutRange.Content.Headers.ContentLength.Value; + + string reqVerboseMsg = String.Format(CultureInfo.CurrentCulture, + WebCmdletStrings.WebMethodInvocationVerboseMsg, + requestWithoutRange.Method, + requestWithoutRange.RequestUri, + requestContentLength); + WriteVerbose(reqVerboseMsg); + + return GetResponse(client, requestWithoutRange, stripAuthorization); + } + } + + _resumeSuccess = response.StatusCode == HttpStatusCode.PartialContent; + return response; + } + + internal virtual void UpdateSession(HttpResponseMessage response) + { + if (response == null) { throw new ArgumentNullException("response"); } + } + + #endregion Virtual Methods + + #region Overrides + + /// + /// the main execution method for cmdlets derived from WebRequestPSCmdlet. + /// + protected override void ProcessRecord() + { + try + { + // Set cmdlet context for write progress + ValidateParameters(); + PrepareSession(); + + // if the request contains an authorization header and PreserveAuthorizationOnRedirect is not set, + // it needs to be stripped on the first redirect. + bool stripAuthorization = null != WebSession + && + null != WebSession.Headers + && + !PreserveAuthorizationOnRedirect.IsPresent + && + WebSession.Headers.ContainsKey(HttpKnownHeaderNames.Authorization.ToString()); + + using (HttpClient client = GetHttpClient(stripAuthorization)) + { + int followedRelLink = 0; + Uri uri = Uri; + do + { + if (followedRelLink > 0) + { + string linkVerboseMsg = string.Format(CultureInfo.CurrentCulture, + WebCmdletStrings.FollowingRelLinkVerboseMsg, + uri.AbsoluteUri); + WriteVerbose(linkVerboseMsg); + } + + using (HttpRequestMessage request = GetRequest(uri, stripAuthorization:false)) + { + FillRequestStream(request); + try + { + long requestContentLength = 0; + if (request.Content != null) + requestContentLength = request.Content.Headers.ContentLength.Value; + + string reqVerboseMsg = String.Format(CultureInfo.CurrentCulture, + WebCmdletStrings.WebMethodInvocationVerboseMsg, + request.Method, + request.RequestUri, + requestContentLength); + WriteVerbose(reqVerboseMsg); + + HttpResponseMessage response = GetResponse(client, request, stripAuthorization); + + string contentType = ContentHelper.GetContentType(response); + string respVerboseMsg = string.Format(CultureInfo.CurrentCulture, + WebCmdletStrings.WebResponseVerboseMsg, + response.Content.Headers.ContentLength, + contentType); + WriteVerbose(respVerboseMsg); + + bool _isSuccess = response.IsSuccessStatusCode; + + // Check if the Resume range was not satisfiable because the file already completed downloading. + // This happens when the local file is the same size as the remote file. + if (Resume.IsPresent && + response.StatusCode == HttpStatusCode.RequestedRangeNotSatisfiable && + response.Content.Headers.ContentRange.HasLength && + response.Content.Headers.ContentRange.Length == _resumeFileSize) + { + _isSuccess = true; + WriteVerbose(String.Format(CultureInfo.CurrentCulture, WebCmdletStrings.OutFileWritingSkipped, OutFile)); + // Disable writing to the OutFile. + OutFile = null; + } + + if (!_isSuccess) + { + string message = String.Format(CultureInfo.CurrentCulture, WebCmdletStrings.ResponseStatusCodeFailure, + (int)response.StatusCode, response.ReasonPhrase); + HttpResponseException httpEx = new HttpResponseException(message, response); + ErrorRecord er = new ErrorRecord(httpEx, "WebCmdletWebResponseException", ErrorCategory.InvalidOperation, request); + string detailMsg = ""; + StreamReader reader = null; + try + { + reader = new StreamReader(StreamHelper.GetResponseStream(response)); + // remove HTML tags making it easier to read + detailMsg = System.Text.RegularExpressions.Regex.Replace(reader.ReadToEnd(), "<[^>]*>",""); + } + catch (Exception) + { + // catch all + } + finally + { + if (reader != null) + { + reader.Dispose(); + } + } + if (!String.IsNullOrEmpty(detailMsg)) + { + er.ErrorDetails = new ErrorDetails(detailMsg); + } + ThrowTerminatingError(er); + } + + if (_parseRelLink || _followRelLink) + { + ParseLinkHeader(response, uri); + } + ProcessResponse(response); + UpdateSession(response); + + // If we hit our maximum redirection count, generate an error. + // Errors with redirection counts of greater than 0 are handled automatically by .NET, but are + // impossible to detect programmatically when we hit this limit. By handling this ourselves + // (and still writing out the result), users can debug actual HTTP redirect problems. + if (WebSession.MaximumRedirection == 0) // Indicate "HttpClientHandler.AllowAutoRedirect == false" + { + if (response.StatusCode == HttpStatusCode.Found || + response.StatusCode == HttpStatusCode.Moved || + response.StatusCode == HttpStatusCode.MovedPermanently) + { + ErrorRecord er = new ErrorRecord(new InvalidOperationException(), "MaximumRedirectExceeded", ErrorCategory.InvalidOperation, request); + er.ErrorDetails = new ErrorDetails(WebCmdletStrings.MaximumRedirectionCountExceeded); + WriteError(er); + } + } + } + catch (HttpRequestException ex) + { + ErrorRecord er = new ErrorRecord(ex, "WebCmdletWebResponseException", ErrorCategory.InvalidOperation, request); + if (ex.InnerException != null) + { + er.ErrorDetails = new ErrorDetails(ex.InnerException.Message); + } + ThrowTerminatingError(er); + } + + if (_followRelLink) + { + if (!_relationLink.ContainsKey("next")) + { + return; + } + uri = new Uri(_relationLink["next"]); + followedRelLink++; + } + } + } + while (_followRelLink && (followedRelLink < _maximumFollowRelLink)); + } + } + catch (CryptographicException ex) + { + ErrorRecord er = new ErrorRecord(ex, "WebCmdletCertificateException", ErrorCategory.SecurityError, null); + ThrowTerminatingError(er); + } + catch (NotSupportedException ex) + { + ErrorRecord er = new ErrorRecord(ex, "WebCmdletIEDomNotSupportedException", ErrorCategory.NotImplemented, null); + ThrowTerminatingError(er); + } + } + + /// + /// Implementing ^C, after start the BeginGetResponse + /// + protected override void StopProcessing() + { + if (_cancelToken != null) + { + _cancelToken.Cancel(); + } + } + + #endregion Overrides + + #region Helper Methods + + /// + /// Sets the ContentLength property of the request and writes the specified content to the request's RequestStream. + /// + /// The WebRequest who's content is to be set + /// A byte array containing the content data. + /// The number of bytes written to the requests RequestStream (and the new value of the request's ContentLength property + /// + /// Because this function sets the request's ContentLength property and writes content data into the requests's stream, + /// it should be called one time maximum on a given request. + /// + internal long SetRequestContent(HttpRequestMessage request, Byte[] content) + { + if (request == null) + throw new ArgumentNullException("request"); + if (content == null) + return 0; + + var byteArrayContent = new ByteArrayContent(content); + request.Content = byteArrayContent; + + return byteArrayContent.Headers.ContentLength.Value; + } + + /// + /// Sets the ContentLength property of the request and writes the specified content to the request's RequestStream. + /// + /// The WebRequest who's content is to be set + /// A String object containing the content data. + /// The number of bytes written to the requests RequestStream (and the new value of the request's ContentLength property + /// + /// Because this function sets the request's ContentLength property and writes content data into the requests's stream, + /// it should be called one time maximum on a given request. + /// + internal long SetRequestContent(HttpRequestMessage request, string content) + { + if (request == null) + throw new ArgumentNullException("request"); + + if (content == null) + return 0; + + Encoding encoding = null; + if (ContentType != null) + { + // If Content-Type contains the encoding format (as CharSet), use this encoding format + // to encode the Body of the WebRequest sent to the server. Default Encoding format + // would be used if Charset is not supplied in the Content-Type property. + try + { + var mediaTypeHeaderValue = new MediaTypeHeaderValue(ContentType); + if (!string.IsNullOrEmpty(mediaTypeHeaderValue.CharSet)) + { + encoding = Encoding.GetEncoding(mediaTypeHeaderValue.CharSet); + } + } + catch (FormatException ex) + { + if (!SkipHeaderValidation) + { + var outerEx = new ValidationMetadataException(WebCmdletStrings.ContentTypeException, ex); + ErrorRecord er = new ErrorRecord(outerEx, "WebCmdletContentTypeException", ErrorCategory.InvalidArgument, ContentType); + ThrowTerminatingError(er); + } + } + catch (ArgumentException ex) + { + if (!SkipHeaderValidation) + { + var outerEx = new ValidationMetadataException(WebCmdletStrings.ContentTypeException, ex); + ErrorRecord er = new ErrorRecord(outerEx, "WebCmdletContentTypeException", ErrorCategory.InvalidArgument, ContentType); + ThrowTerminatingError(er); + } + } + } + + Byte[] bytes = StreamHelper.EncodeToBytes(content, encoding); + var byteArrayContent = new ByteArrayContent(bytes); + request.Content = byteArrayContent; + + return byteArrayContent.Headers.ContentLength.Value; + } + + internal long SetRequestContent(HttpRequestMessage request, XmlNode xmlNode) + { + if (request == null) + throw new ArgumentNullException("request"); + + if (xmlNode == null) + return 0; + + Byte[] bytes = null; + XmlDocument doc = xmlNode as XmlDocument; + if (doc != null && (doc.FirstChild as XmlDeclaration) != null) + { + XmlDeclaration decl = doc.FirstChild as XmlDeclaration; + Encoding encoding = Encoding.GetEncoding(decl.Encoding); + bytes = StreamHelper.EncodeToBytes(doc.OuterXml, encoding); + } + else + { + bytes = StreamHelper.EncodeToBytes(xmlNode.OuterXml); + } + + var byteArrayContent = new ByteArrayContent(bytes); + request.Content = byteArrayContent; + + return byteArrayContent.Headers.ContentLength.Value; + } + + /// + /// Sets the ContentLength property of the request and writes the specified content to the request's RequestStream. + /// + /// The WebRequest who's content is to be set + /// A Stream object containing the content data. + /// The number of bytes written to the requests RequestStream (and the new value of the request's ContentLength property + /// + /// Because this function sets the request's ContentLength property and writes content data into the requests's stream, + /// it should be called one time maximum on a given request. + /// + internal long SetRequestContent(HttpRequestMessage request, Stream contentStream) + { + if (request == null) + throw new ArgumentNullException("request"); + if (contentStream == null) + throw new ArgumentNullException("contentStream"); + + var streamContent = new StreamContent(contentStream); + request.Content = streamContent; + + return streamContent.Headers.ContentLength.Value; + } + + /// + /// Sets the ContentLength property of the request and writes the specified content to the request's RequestStream. + /// + /// The WebRequest who's content is to be set + /// A MultipartFormDataContent object containing multipart/form-data content. + /// The number of bytes written to the requests RequestStream (and the new value of the request's ContentLength property + /// + /// Because this function sets the request's ContentLength property and writes content data into the requests's stream, + /// it should be called one time maximum on a given request. + /// + internal long SetRequestContent(HttpRequestMessage request, MultipartFormDataContent multipartContent) + { + if (request == null) + { + throw new ArgumentNullException("request"); + } + if (multipartContent == null) + { + throw new ArgumentNullException("multipartContent"); + } + + request.Content = multipartContent; + + return multipartContent.Headers.ContentLength.Value; + } + + internal long SetRequestContent(HttpRequestMessage request, IDictionary content) + { + if (request == null) + throw new ArgumentNullException("request"); + if (content == null) + throw new ArgumentNullException("content"); + + string body = FormatDictionary(content); + return (SetRequestContent(request, body)); + + } + + internal void ParseLinkHeader(HttpResponseMessage response, System.Uri requestUri) + { + if (_relationLink == null) + { + // Must ignore the case of relation links. See RFC 8288 (https://tools.ietf.org/html/rfc8288) + _relationLink = new Dictionary(StringComparer.OrdinalIgnoreCase); + } + else + { + _relationLink.Clear(); + } + + // we only support the URL in angle brackets and `rel`, other attributes are ignored + // user can still parse it themselves via the Headers property + string pattern = "<(?.*?)>;\\srel=\"(?.*?)\""; + IEnumerable links; + if (response.Headers.TryGetValues("Link", out links)) + { + foreach (string linkHeader in links) + { + foreach (string link in linkHeader.Split(",")) + { + Match match = Regex.Match(link, pattern); + if (match.Success) + { + string url = match.Groups["url"].Value; + string rel = match.Groups["rel"].Value; + if (url != String.Empty && rel != String.Empty && !_relationLink.ContainsKey(rel)) + { + Uri absoluteUri = new Uri(requestUri, url); + _relationLink.Add(rel, absoluteUri.AbsoluteUri.ToString()); + } + } + } + } + } + } + + /// + /// Adds content to a . Object type detection is used to determine if the value is String, File, or Collection. + /// + /// The Field Name to use. + /// The Field Value to use. + /// The > to update. + /// If true, collection types in will be enumerated. If false, collections will be treated as single value. + private void AddMultipartContent(object fieldName, object fieldValue, MultipartFormDataContent formData, bool enumerate) + { + if (null == formData) + { + throw new ArgumentNullException("formDate"); + } + + // It is possible that the dictionary keys or values are PSObject wrapped depending on how the dictionary is defined and assigned. + // Before processing the field name and value we need to ensure we are working with the base objects and not the PSObject wrappers. + + // Unwrap fieldName PSObjects + if (fieldName is PSObject namePSObject) + { + fieldName = namePSObject.BaseObject; + } + + // Unwrap fieldValue PSObjects + if (fieldValue is PSObject valuePSObject) + { + fieldValue = valuePSObject.BaseObject; + } + + // Treat a single FileInfo as a FileContent + if (fieldValue is FileInfo file) + { + formData.Add(GetMultipartFileContent(fieldName: fieldName, file: file)); + return; + } + + // Treat Strings and other single values as a StringContent. + // If enumeration is false, also treat IEnumerables as StringContents. + // String implements IEnumerable so the explicit check is required. + if (enumerate == false || fieldValue is String || !(fieldValue is IEnumerable)) + { + formData.Add(GetMultipartStringContent(fieldName: fieldName, fieldValue: fieldValue)); + return; + } + + // Treat the value as a collection and enumerate it if enumeration is true + if (enumerate == true && fieldValue is IEnumerable items) + { + foreach (var item in items) + { + // Recruse, but do not enumerate the next level. IEnumerables will be treated as single values. + AddMultipartContent(fieldName: fieldName, fieldValue: item, formData: formData, enumerate: false); + } + } + } + + /// + /// Gets a from the supplied field name and field value. Uses to convert the objects to strings. + /// + /// The Field Name to use for the . + /// The Field Value to use for the . + private StringContent GetMultipartStringContent(Object fieldName, Object fieldValue) + { + var contentDisposition = new ContentDispositionHeaderValue("form-data"); + contentDisposition.Name = LanguagePrimitives.ConvertTo(fieldName); + + var result = new StringContent(LanguagePrimitives.ConvertTo(fieldValue)); + result.Headers.ContentDisposition = contentDisposition; + + return result; + } + + /// + /// Gets a from the supplied field name and . Uses to convert the fieldname to a string. + /// + /// The Field Name to use for the . + /// The to use for the . + private StreamContent GetMultipartStreamContent(Object fieldName, Stream stream) + { + var contentDisposition = new ContentDispositionHeaderValue("form-data"); + contentDisposition.Name = LanguagePrimitives.ConvertTo(fieldName); + + var result = new StreamContent(stream); + result.Headers.ContentDisposition = contentDisposition; + result.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); + + return result; + } + + /// + /// Gets a from the supplied field name and file. Calls to create the and then sets the file name. + /// + /// The Field Name to use for the . + /// The file to use for the . + private StreamContent GetMultipartFileContent(Object fieldName, FileInfo file) + { + var result = GetMultipartStreamContent(fieldName: fieldName, stream: new FileStream(file.FullName, FileMode.Open)); + result.Headers.ContentDisposition.FileName = file.Name; + + return result; + } + #endregion Helper Methods } } diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebResponseObject.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebResponseObject.Common.cs index d01d2bc08e7..e819f246f2d 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebResponseObject.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebResponseObject.Common.cs @@ -1,10 +1,12 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Diagnostics.CodeAnalysis; using System.IO; +using System.Text; +using System.Net.Http; +using System.Collections.Generic; namespace Microsoft.PowerShell.Commands { @@ -96,4 +98,116 @@ public sealed override string ToString() #endregion Methods } + + // TODO: Merge Partials + + /// + /// WebResponseObject + /// + public partial class WebResponseObject + { + #region Properties + + /// + /// gets or sets the BaseResponse property + /// + public HttpResponseMessage BaseResponse { get; set; } + + /// + /// gets the Headers property + /// + public Dictionary> Headers + { + get + { + if(_headers == null) + { + _headers = WebResponseHelper.GetHeadersDictionary(BaseResponse); + } + + return _headers; + } + } + + private Dictionary> _headers = null; + + /// + /// gets the RelationLink property + /// + public Dictionary RelationLink { get; internal set; } + + #endregion + + #region Constructors + + /// + /// Constructor for WebResponseObject + /// + /// + public WebResponseObject(HttpResponseMessage response) + : this(response, null) + { } + + /// + /// Constructor for WebResponseObject with contentStream + /// + /// + /// + public WebResponseObject(HttpResponseMessage response, Stream contentStream) + { + SetResponse(response, contentStream); + InitializeContent(); + InitializeRawContent(response); + } + + #endregion Constructors + + #region Methods + + private void InitializeRawContent(HttpResponseMessage baseResponse) + { + StringBuilder raw = ContentHelper.GetRawContentHeader(baseResponse); + + // Use ASCII encoding for the RawContent visual view of the content. + if (Content.Length > 0) + { + raw.Append(this.ToString()); + } + + this.RawContent = raw.ToString(); + } + + private void SetResponse(HttpResponseMessage response, Stream contentStream) + { + if (null == response) { throw new ArgumentNullException("response"); } + + BaseResponse = response; + + MemoryStream ms = contentStream as MemoryStream; + if (null != ms) + { + _rawContentStream = ms; + } + else + { + Stream st = contentStream; + if (contentStream == null) + { + st = StreamHelper.GetResponseStream(response); + } + + long contentLength = response.Content.Headers.ContentLength.Value; + if (0 >= contentLength) + { + contentLength = StreamHelper.DefaultReadBuffer; + } + int initialCapacity = (int)Math.Min(contentLength, StreamHelper.DefaultReadBuffer); + _rawContentStream = new WebResponseContentMemoryStream(st, initialCapacity, null); + } + // set the position of the content stream to the beginning + _rawContentStream.Position = 0; + } + + #endregion + } } diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs index 4057ea82a3a..dca51d7fc49 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; @@ -20,17 +19,23 @@ public class ConvertFromJsonCommand : Cmdlet #region parameters /// - /// gets or sets the InputString property + /// Gets or sets the InputString property. /// [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true)] [AllowEmptyString] public string InputObject { get; set; } /// - /// inputObjectBuffer buffers all InputObjet contents available in the pipeline. + /// InputObjectBuffer buffers all InputObject contents available in the pipeline. /// private List _inputObjectBuffer = new List(); + /// + /// Returned data structure is a Hashtable instead a CustomPSObject. + /// + [Parameter()] + public SwitchParameter AsHashtable { get; set; } + #endregion parameters #region overrides @@ -44,7 +49,7 @@ protected override void ProcessRecord() } /// - /// the main execution method for the convertfrom-json command + /// The main execution method for the ConvertFrom-Json command. /// protected override void EndProcessing() { @@ -95,7 +100,7 @@ protected override void EndProcessing() private bool ConvertFromJsonHelper(string input) { ErrorRecord error = null; - object result = JsonObject.ConvertFromJson(input, out error); + object result = JsonObject.ConvertFromJson(input, AsHashtable.IsPresent, out error); if (error != null) { diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertToJsonCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertToJsonCommand.cs index 4def219c2c6..b1a3cbac05d 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertToJsonCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertToJsonCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Diagnostics.CodeAnalysis; @@ -62,9 +61,18 @@ public class ConvertToJsonCommand : PSCmdlet /// be converted to their string equivalent. Otherwise, enum values /// will be converted to their numeric equivalent. /// - [Parameter()] + [Parameter] public SwitchParameter EnumsAsStrings { get; set; } + /// + /// Gets or sets the AsArray property. + /// If the AsArray property is set to be true, the result JSON string will + /// be returned with surrounding '[', ']' chars. Otherwise, + /// the array symbols will occur only if there is more than one input object. + /// + [Parameter] + public SwitchParameter AsArray { get; set; } + #endregion parameters #region overrides @@ -105,10 +113,18 @@ protected override void EndProcessing() { if (_inputObjects.Count > 0) { - object objectToProcess = (_inputObjects.Count > 1) ? (_inputObjects.ToArray() as object) : (_inputObjects[0]); + object objectToProcess = (_inputObjects.Count > 1 || AsArray) ? (_inputObjects.ToArray() as object) : (_inputObjects[0]); // Pre-process the object so that it serializes the same, except that properties whose // values cannot be evaluated are treated as having the value null. - object preprocessedObject = ProcessValue(objectToProcess, 0); + object preprocessedObject = null; + try + { + preprocessedObject = ProcessValue(objectToProcess, 0); + } + catch (StoppingException) + { + return; + } JsonSerializerSettings jsonSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.None, MaxDepth = 1024 }; if (EnumsAsStrings) { @@ -125,274 +141,6 @@ protected override void EndProcessing() #endregion overrides - #region convertOutputToPrettierFormat - - /// - /// Convert the Json string to a more readable format - /// - /// - /// - private string ConvertToPrettyJsonString(string json) - { - if (!json.StartsWith("{", StringComparison.OrdinalIgnoreCase) && !json.StartsWith("[", StringComparison.OrdinalIgnoreCase)) - { - return json; - } - - StringBuilder retStr = new StringBuilder(); - if (json.StartsWith("{", StringComparison.OrdinalIgnoreCase)) - { - retStr.Append('{'); - ConvertDictionary(json, 1, retStr, "", 0); - } - else if (json.StartsWith("[", StringComparison.OrdinalIgnoreCase)) - { - retStr.Append('['); - ConvertList(json, 1, retStr, "", 0); - } - - return retStr.ToString(); - } - - /// - /// Convert a Json List, which starts with '['. - /// - /// - /// - /// - /// - /// - /// - private int ConvertList(string json, int index, StringBuilder result, string padString, int numberOfSpaces) - { - result.Append("\r\n"); - StringBuilder newPadString = new StringBuilder(); - newPadString.Append(padString); - AddSpaces(numberOfSpaces, newPadString); - AddIndentations(1, newPadString); - - bool headChar = true; - - for (int i = index; i < json.Length; i++) - { - switch (json[i]) - { - case '{': - result.Append(newPadString.ToString()); - result.Append(json[i]); - i = ConvertDictionary(json, i + 1, result, newPadString.ToString(), 0); - headChar = false; - break; - case '[': - result.Append(newPadString.ToString()); - result.Append(json[i]); - i = ConvertList(json, i + 1, result, newPadString.ToString(), 0); - headChar = false; - break; - case ']': - result.Append("\r\n"); - result.Append(padString); - AddSpaces(numberOfSpaces, result); - result.Append(json[i]); - return i; - case '"': - if (headChar) - { - result.Append(newPadString.ToString()); - } - result.Append(json[i]); - i = ConvertQuotedString(json, i + 1, result); - headChar = false; - break; - case ',': - result.Append(json[i]); - result.Append("\r\n"); - headChar = true; - break; - default: - if (headChar) - { - result.Append(newPadString.ToString()); - } - result.Append(json[i]); - headChar = false; - break; - } - } - - Dbg.Diagnostics.Assert(false, "ConvertDictionary should return when encounter '}'"); - ThrowTerminatingError(NewError()); - return -1; - } - - /// - /// Convert the quoted string. - /// - /// - /// - /// - /// - private int ConvertQuotedString(string json, int index, StringBuilder result) - { - for (int i = index; i < json.Length; i++) - { - result.Append(json[i]); - if (json[i] == '"') - { - // Ensure that the quote is not escaped by iteratively searching backwards for the backslash. - // Examples: - // "a \" b" --> here second quote is escaped - // "c:\\" --> here second quote is not escaped - // - var j = i; - var escaped = false; - while (j > 0 && json[--j] == '\\') - { - escaped = !escaped; - } - - if (!escaped) - { - return i; - } - } - } - - Dbg.Diagnostics.Assert(false, "ConvertDictionary should return when encounter '}'"); - ThrowTerminatingError(NewError()); - return -1; - } - - /// - /// Convert a Json dictionary, which starts with '{'. - /// - /// - /// - /// - /// - /// - /// - private int ConvertDictionary(string json, int index, StringBuilder result, string padString, int numberOfSpaces) - { - result.Append("\r\n"); - StringBuilder newPadString = new StringBuilder(); - newPadString.Append(padString); - AddSpaces(numberOfSpaces, newPadString); - AddIndentations(1, newPadString); - - bool headChar = true; - bool beforeQuote = true; - int newSpaceCount = 0; - const int spaceCountAfterQuoteMark = 1; - - for (int i = index; i < json.Length; i++) - { - switch (json[i]) - { - case '{': - result.Append(json[i]); - i = ConvertDictionary(json, i + 1, result, newPadString.ToString(), newSpaceCount); - headChar = false; - break; - case '[': - result.Append(json[i]); - i = ConvertList(json, i + 1, result, newPadString.ToString(), newSpaceCount); - headChar = false; - break; - case '}': - result.Append("\r\n"); - result.Append(padString); - AddSpaces(numberOfSpaces, result); - result.Append(json[i]); - return i; - case '"': - if (headChar) - { - result.Append(newPadString.ToString()); - } - result.Append(json[i]); - int end = ConvertQuotedString(json, i + 1, result); - if (beforeQuote) - { - newSpaceCount = 0; - } - i = end; - headChar = false; - break; - case ':': - result.Append(json[i]); - AddSpaces(spaceCountAfterQuoteMark, result); - headChar = false; - beforeQuote = false; - break; - case ',': - result.Append(json[i]); - result.Append("\r\n"); - headChar = true; - beforeQuote = true; - newSpaceCount = 0; - break; - default: - if (headChar) - { - result.Append(newPadString.ToString()); - } - result.Append(json[i]); - if (beforeQuote) - { - newSpaceCount += 1; - } - headChar = false; - break; - } - } - - Dbg.Diagnostics.Assert(false, "ConvertDictionary should return when encounter '}'"); - ThrowTerminatingError(NewError()); - return -1; - } - - /// - /// Add tabs to result - /// - /// - /// - private void AddIndentations(int numberOfTabsToReturn, StringBuilder result) - { - int realNumber = numberOfTabsToReturn * 2; - for (int i = 0; i < realNumber; i++) - { - result.Append(' '); - } - } - - /// - /// Add spaces to result - /// - /// - /// - private void AddSpaces(int numberOfSpacesToReturn, StringBuilder result) - { - for (int i = 0; i < numberOfSpacesToReturn; i++) - { - result.Append(' '); - } - } - - private ErrorRecord NewError() - { - ErrorDetails details = new ErrorDetails(this.GetType().GetTypeInfo().Assembly, - "WebCmdletStrings", "JsonStringInBadFormat"); - ErrorRecord errorRecord = new ErrorRecord( - new InvalidOperationException(details.Message), - "JsonStringInBadFormat", - ErrorCategory.InvalidOperation, - InputObject); - return errorRecord; - } - - #endregion convertOutputToPrettierFormat - /// /// Return an alternate representation of the specified object that serializes the same JSON, except /// that properties that cannot be evaluated are treated as having the value null. @@ -404,6 +152,11 @@ private ErrorRecord NewError() /// An object suitable for serializing to JSON private object ProcessValue(object obj, int depth) { + if (Stopping) + { + throw new StoppingException(); + } + PSObject pso = obj as PSObject; if (pso != null) @@ -428,9 +181,15 @@ private object ProcessValue(object obj, int depth) { rv = obj; } + else if (obj is Newtonsoft.Json.Linq.JObject jObject) + { + rv = jObject.ToObject>(); + } else { TypeInfo t = obj.GetType().GetTypeInfo(); + WriteVerbose(StringUtil.Format(UtilityCommonStrings.ConvertToJsonProcessValueVerboseMessage, t.Name, depth)); + if (t.IsPrimitive) { @@ -682,5 +441,10 @@ private object ProcessCustomObject(object o, int depth) } return result; } + + /// + /// Exception used for Stopping. + /// + private class StoppingException : System.Exception {} } } diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/BasicHtmlWebResponseObject.CoreClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/BasicHtmlWebResponseObject.CoreClr.cs deleted file mode 100644 index f4b060430f5..00000000000 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/BasicHtmlWebResponseObject.CoreClr.cs +++ /dev/null @@ -1,55 +0,0 @@ -#if CORECLR - -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - -using System.Net.Http; -using System.IO; -using System.Text; - -namespace Microsoft.PowerShell.Commands -{ - /// - /// Response object for html content without DOM parsing - /// - public partial class BasicHtmlWebResponseObject : WebResponseObject - { - #region Constructors - - /// - /// Constructor for HtmlWebResponseObject - /// - /// - public BasicHtmlWebResponseObject(HttpResponseMessage response) - : this(response, null) - { } - - /// - /// Constructor for HtmlWebResponseObject with memory stream - /// - /// - /// - public BasicHtmlWebResponseObject(HttpResponseMessage response, Stream contentStream) - : base(response, contentStream) - { - EnsureHtmlParser(); - InitializeContent(); - InitializeRawContent(response); - } - - #endregion Constructors - - #region Methods - - private void InitializeRawContent(HttpResponseMessage baseResponse) - { - StringBuilder raw = ContentHelper.GetRawContentHeader(baseResponse); - raw.Append(Content); - this.RawContent = raw.ToString(); - } - - #endregion Methods - } -} -#endif \ No newline at end of file diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/ContentHelper.CoreClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/ContentHelper.CoreClr.cs deleted file mode 100644 index 4268bc63a98..00000000000 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/ContentHelper.CoreClr.cs +++ /dev/null @@ -1,72 +0,0 @@ -#if CORECLR - -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - -using System.Text; -using System.Linq; -using System.Net.Http; -using System.Net.Http.Headers; - -namespace Microsoft.PowerShell.Commands -{ - internal static partial class ContentHelper - { - internal static Encoding GetEncoding(HttpResponseMessage response) - { - // ContentType may not exist in response header. - string charSet = response.Content.Headers.ContentType?.CharSet; - return GetEncodingOrDefault(charSet); - } - - internal static string GetContentType(HttpResponseMessage response) - { - // ContentType may not exist in response header. Return null if not. - return response.Content.Headers.ContentType?.MediaType; - } - - internal static StringBuilder GetRawContentHeader(HttpResponseMessage response) - { - StringBuilder raw = new StringBuilder(); - - string protocol = WebResponseHelper.GetProtocol(response); - if (!string.IsNullOrEmpty(protocol)) - { - int statusCode = WebResponseHelper.GetStatusCode(response); - string statusDescription = WebResponseHelper.GetStatusDescription(response); - raw.AppendFormat("{0} {1} {2}", protocol, statusCode, statusDescription); - raw.AppendLine(); - } - - HttpHeaders[] headerCollections = - { - response.Headers, - response.Content == null ? null : response.Content.Headers - }; - - foreach (var headerCollection in headerCollections) - { - if (headerCollection == null) - { - continue; - } - foreach (var header in headerCollection) - { - // Headers may have multiple entries with different values - foreach (var headerValue in header.Value) - { - raw.Append(header.Key); - raw.Append(": "); - raw.Append(headerValue); - raw.AppendLine(); - } - } - } - - raw.AppendLine(); - return raw; - } - } -} -#endif \ No newline at end of file diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/HtmlWebResponseObject.CoreClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/HtmlWebResponseObject.CoreClr.cs deleted file mode 100644 index c87d24a0d45..00000000000 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/HtmlWebResponseObject.CoreClr.cs +++ /dev/null @@ -1,107 +0,0 @@ -#if CORECLR - -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - -using System; -using System.Management.Automation; -using System.Net.Http; -using System.IO; -using System.Text; -using ExecutionContext = System.Management.Automation.ExecutionContext; - -namespace Microsoft.PowerShell.Commands -{ - /// - /// Response object for html content - /// - public partial class HtmlWebResponseObject : WebResponseObject, IDisposable - { - #region Constructors - - /// - /// Constructor for HtmlWebResponseObject - /// - /// - /// - internal HtmlWebResponseObject(HttpResponseMessage response, ExecutionContext executionContext) - : this(response, null, executionContext) - { } - - /// - /// Constructor for HtmlWebResponseObject with memory stream - /// - /// - /// /// - internal HtmlWebResponseObject(HttpResponseMessage response, Stream contentStream, ExecutionContext executionContext) - : base(response, contentStream) - { - if (executionContext == null) - { - throw PSTraceSource.NewArgumentNullException("executionContext"); - } - - _executionContext = executionContext; - InitializeContent(); - InitializeRawContent(response); - } - - #endregion Constructors - - #region Properties - - /// - /// Gets the Encoding that was used to decode the Content - /// - /// - /// The Encoding used to decode the Content; otherwise, a null reference if the content is not text. - /// - public Encoding Encoding { get; private set; } - - #endregion Properties - - #region Methods - - // NOTE: Currently this code path is not enabled. - // See FillRequestStream in WebRequestPSCmdlet.CoreClr.cs and - // GetResponseObject in WebResponseObjectFactory.CoreClr.cs for details. - private void InitializeContent() - { - string contentType = ContentHelper.GetContentType(BaseResponse); - string content = null; - if (ContentHelper.IsText(contentType)) - { - Encoding encoding = null; - // fill the Content buffer - string characterSet = WebResponseHelper.GetCharacterSet(BaseResponse); - this.Content = StreamHelper.DecodeStream(RawContentStream, characterSet, out encoding); - this.Encoding = encoding; - } - else - { - this.Content = string.Empty; - } - } - - private void InitializeRawContent(HttpResponseMessage baseResponse) - { - StringBuilder raw = ContentHelper.GetRawContentHeader(baseResponse); - if (null != Content) - { - raw.Append(Content); - } - this.RawContent = raw.ToString(); - } - - /// - /// Dispose the the instance of the class. - /// - public void Dispose() - { - GC.SuppressFinalize(this); - } - #endregion - } -} -#endif \ No newline at end of file diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/HttpKnownHeaderNames.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/HttpKnownHeaderNames.cs index 975e89a19c5..1de3a7c14e5 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/HttpKnownHeaderNames.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/HttpKnownHeaderNames.cs @@ -1,8 +1,5 @@ -#if CORECLR - -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; @@ -108,4 +105,3 @@ internal static HashSet ContentHeaders } } } -#endif diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/InvokeRestMethodCommand.CoreClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/InvokeRestMethodCommand.CoreClr.cs deleted file mode 100644 index 1001b173022..00000000000 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/InvokeRestMethodCommand.CoreClr.cs +++ /dev/null @@ -1,134 +0,0 @@ -#if CORECLR - -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - -using System; -using System.Management.Automation; -using System.Net.Http; -using System.Text; - -namespace Microsoft.PowerShell.Commands -{ - /// - /// The Invoke-RestMethod command - /// This command makes an HTTP or HTTPS request to a web service, - /// and returns the response in an appropriate way. - /// Intended to work against the wide spectrum of "RESTful" web services - /// currently deployed across the web. - /// - [Cmdlet(VerbsLifecycle.Invoke, "RestMethod", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=217034", DefaultParameterSetName = "StandardMethod")] - public partial class InvokeRestMethodCommand : WebRequestPSCmdlet - { - #region Virtual Method Overrides - - /// - /// Process the web response and output corresponding objects. - /// - /// - internal override void ProcessResponse(HttpResponseMessage response) - { - if (null == response) { throw new ArgumentNullException("response"); } - - using (BufferingStreamReader responseStream = new BufferingStreamReader(StreamHelper.GetResponseStream(response))) - { - if (ShouldWriteToPipeline) - { - // First see if it is an RSS / ATOM feed, in which case we can - // stream it - unless the user has overridden it with a return type of "XML" - if (TryProcessFeedStream(responseStream)) - { - // Do nothing, content has been processed. - } - else - { - // determine the response type - RestReturnType returnType = CheckReturnType(response); - - // Try to get the response encoding from the ContentType header. - Encoding encoding = null; - string charSet = response.Content.Headers.ContentType?.CharSet; - if (!string.IsNullOrEmpty(charSet)) - { - // NOTE: Don't use ContentHelper.GetEncoding; it returns a - // default which bypasses checking for a meta charset value. - StreamHelper.TryGetEncoding(charSet, out encoding); - } - - object obj = null; - Exception ex = null; - - string str = StreamHelper.DecodeStream(responseStream, ref encoding); - // NOTE: Tests use this verbose output to verify the encoding. - WriteVerbose(string.Format - ( - System.Globalization.CultureInfo.InvariantCulture, - "Content encoding: {0}", - string.IsNullOrEmpty(encoding.HeaderName) ? encoding.EncodingName : encoding.HeaderName) - ); - bool convertSuccess = false; - - if (returnType == RestReturnType.Json) - { - convertSuccess = TryConvertToJson(str, out obj, ref ex) || TryConvertToXml(str, out obj, ref ex); - } - // default to try xml first since it's more common - else - { - convertSuccess = TryConvertToXml(str, out obj, ref ex) || TryConvertToJson(str, out obj, ref ex); - } - - if (!convertSuccess) - { - // fallback to string - obj = str; - } - - WriteObject(obj); - } - } - - if (ShouldSaveToOutFile) - { - StreamHelper.SaveStreamToFile(responseStream, QualifiedOutFile, this); - } - - if (!String.IsNullOrEmpty(ResponseHeadersVariable)) - { - PSVariableIntrinsics vi = SessionState.PSVariable; - vi.Set(ResponseHeadersVariable, WebResponseHelper.GetHeadersDictionary(response)); - } - } - } - - #endregion Virtual Method Overrides - - #region Helper Methods - - private RestReturnType CheckReturnType(HttpResponseMessage response) - { - if (null == response) { throw new ArgumentNullException("response"); } - - RestReturnType rt = RestReturnType.Detect; - string contentType = ContentHelper.GetContentType(response); - if (string.IsNullOrEmpty(contentType)) - { - rt = RestReturnType.Detect; - } - else if (ContentHelper.IsJson(contentType)) - { - rt = RestReturnType.Json; - } - else if (ContentHelper.IsXml(contentType)) - { - rt = RestReturnType.Xml; - } - - return (rt); - } - - #endregion Helper Methods - } -} -#endif \ No newline at end of file diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/InvokeWebRequestCommand.CoreClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/InvokeWebRequestCommand.CoreClr.cs index ebd8a659c3d..82a7ba0dc51 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/InvokeWebRequestCommand.CoreClr.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/InvokeWebRequestCommand.CoreClr.cs @@ -1,8 +1,5 @@ -#if CORECLR - -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; @@ -12,7 +9,7 @@ namespace Microsoft.PowerShell.Commands { /// - /// The Invoke-RestMethod command + /// The Invoke-WebRequest command. /// This command makes an HTTP or HTTPS request to a web server and returns the results. /// [Cmdlet(VerbsLifecycle.Invoke, "WebRequest", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=217035", DefaultParameterSetName = "StandardMethod")] @@ -36,24 +33,12 @@ internal override void ProcessResponse(HttpResponseMessage response) { if (null == response) { throw new ArgumentNullException("response"); } - // check for Server Core, throws exception if -UseBasicParsing is not used - if (ShouldWriteToPipeline && !UseBasicParsing) - { - // IE is not available in PS Linux, and may not available in PS Core depending on - // where it's running (desktop/nano/iot). - // For PS Linux and PS Core, if IE is not available, we always use basic parsing. - if (!VerifyInternetExplorerAvailable(true)) - { - UseBasicParsing = true; - } - } - Stream responseStream = StreamHelper.GetResponseStream(response); if (ShouldWriteToPipeline) { // creating a MemoryStream wrapper to response stream here to support IsStopping. responseStream = new WebResponseContentMemoryStream(responseStream, StreamHelper.ChunkSize, this); - WebResponseObject ro = WebResponseObjectFactory.GetResponseObject(response, responseStream, this.Context, UseBasicParsing); + WebResponseObject ro = WebResponseObjectFactory.GetResponseObject(response, responseStream, this.Context); ro.RelationLink = _relationLink; WriteObject(ro); @@ -73,4 +58,3 @@ internal override void ProcessResponse(HttpResponseMessage response) #endregion Virtual Method Overrides } } -#endif \ No newline at end of file diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebProxy.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebProxy.cs index 2ceb4dc3b33..a3fbb5b7049 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebProxy.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebProxy.cs @@ -1,8 +1,5 @@ -#if CORECLR - -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Net; @@ -69,4 +66,3 @@ public bool IsBypassed(Uri host) } } } -#endif \ No newline at end of file diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs deleted file mode 100644 index a730b464ee1..00000000000 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs +++ /dev/null @@ -1,870 +0,0 @@ -#if CORECLR - -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - -using System; -using System.Management.Automation; -using System.Net; -using System.Net.Http; -using System.Net.Http.Headers; -using System.IO; -using System.Text; -using System.Collections; -using System.Globalization; -using System.Security.Cryptography; -using System.Threading; -using System.Xml; -using System.Collections.Generic; -using System.Text.RegularExpressions; -using System.Linq; - -namespace Microsoft.PowerShell.Commands -{ - /// - /// Exception class for webcmdlets to enable returning HTTP error response - /// - public sealed class HttpResponseException : HttpRequestException - { - /// - /// Constructor for HttpResponseException - /// - /// Message for the exception - /// Response from the HTTP server - public HttpResponseException (string message, HttpResponseMessage response) : base(message) - { - Response = response; - } - - /// - /// HTTP error response - /// - public HttpResponseMessage Response { get; private set; } - } - - /// - /// Base class for Invoke-RestMethod and Invoke-WebRequest commands. - /// - public abstract partial class WebRequestPSCmdlet : PSCmdlet - { - - /// - /// gets or sets the PreserveAuthorizationOnRedirect property - /// - /// - /// This property overrides compatibility with web requests on Windows. - /// On FullCLR (WebRequest), authorization headers are stripped during redirect. - /// CoreCLR (HTTPClient) does not have this behavior so web requests that work on - /// PowerShell/FullCLR can fail with PowerShell/CoreCLR. To provide compatibility, - /// we'll detect requests with an Authorization header and automatically strip - /// the header when the first redirect occurs. This switch turns off this logic for - /// edge cases where the authorization header needs to be preserved across redirects. - /// - [Parameter] - public virtual SwitchParameter PreserveAuthorizationOnRedirect { get; set; } - - /// - /// gets or sets the SkipHeaderValidation property - /// - /// - /// This property adds headers to the request's header collection without validation. - /// - [Parameter] - public virtual SwitchParameter SkipHeaderValidation { get; set; } - - #region Abstract Methods - - /// - /// Read the supplied WebResponse object and push the - /// resulting output into the pipeline. - /// - /// Instance of a WebResponse object to be processed - internal abstract void ProcessResponse(HttpResponseMessage response); - - #endregion Abstract Methods - - /// - /// Cancellation token source - /// - private CancellationTokenSource _cancelToken = null; - - /// - /// Parse Rel Links - /// - internal bool _parseRelLink = false; - - /// - /// Automatically follow Rel Links - /// - internal bool _followRelLink = false; - - /// - /// Automatically follow Rel Links - /// - internal Dictionary _relationLink = null; - - /// - /// Maximum number of Rel Links to follow - /// - internal int _maximumFollowRelLink = Int32.MaxValue; - - private HttpMethod GetHttpMethod(WebRequestMethod method) - { - switch (Method) - { - case WebRequestMethod.Default: - case WebRequestMethod.Get: - return HttpMethod.Get; - case WebRequestMethod.Head: - return HttpMethod.Head; - case WebRequestMethod.Post: - return HttpMethod.Post; - case WebRequestMethod.Put: - return HttpMethod.Put; - case WebRequestMethod.Delete: - return HttpMethod.Delete; - case WebRequestMethod.Trace: - return HttpMethod.Trace; - case WebRequestMethod.Options: - return HttpMethod.Options; - default: - // Merge and Patch - return new HttpMethod(Method.ToString().ToUpperInvariant()); - } - } - - #region Virtual Methods - - // NOTE: Only pass true for handleRedirect if the original request has an authorization header - // and PreserveAuthorizationOnRedirect is NOT set. - internal virtual HttpClient GetHttpClient(bool handleRedirect) - { - // By default the HttpClientHandler will automatically decompress GZip and Deflate content - HttpClientHandler handler = new HttpClientHandler(); - handler.CookieContainer = WebSession.Cookies; - - // set the credentials used by this request - if (WebSession.UseDefaultCredentials) - { - // the UseDefaultCredentials flag overrides other supplied credentials - handler.UseDefaultCredentials = true; - } - else if (WebSession.Credentials != null) - { - handler.Credentials = WebSession.Credentials; - } - - if (NoProxy) - { - handler.UseProxy = false; - } - else if (WebSession.Proxy != null) - { - handler.Proxy = WebSession.Proxy; - } - - if (null != WebSession.Certificates) - { - handler.ClientCertificates.AddRange(WebSession.Certificates); - } - - if (SkipCertificateCheck) - { - handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; - handler.ClientCertificateOptions = ClientCertificateOption.Manual; - } - - // This indicates GetResponse will handle redirects. - if (handleRedirect) - { - handler.AllowAutoRedirect = false; - } - else if (WebSession.MaximumRedirection > -1) - { - if (WebSession.MaximumRedirection == 0) - { - handler.AllowAutoRedirect = false; - } - else - { - handler.MaxAutomaticRedirections = WebSession.MaximumRedirection; - } - } - - HttpClient httpClient = new HttpClient(handler); - - // check timeout setting (in seconds instead of milliseconds as in HttpWebRequest) - if (TimeoutSec == 0) - { - // A zero timeout means infinite - httpClient.Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite); - } - else if (TimeoutSec > 0) - { - httpClient.Timeout = new TimeSpan(0, 0, TimeoutSec); - } - - return httpClient; - } - - internal virtual HttpRequestMessage GetRequest(Uri uri, bool stripAuthorization) - { - Uri requestUri = PrepareUri(uri); - HttpMethod httpMethod = null; - - switch (ParameterSetName) - { - case "StandardMethodNoProxy": - goto case "StandardMethod"; - case "StandardMethod": - // set the method if the parameter was provided - httpMethod = GetHttpMethod(Method); - break; - case "CustomMethodNoProxy": - goto case "CustomMethod"; - case "CustomMethod": - if (!string.IsNullOrEmpty(CustomMethod)) - { - // set the method if the parameter was provided - httpMethod = new HttpMethod(CustomMethod.ToString().ToUpperInvariant()); - } - break; - } - - // create the base WebRequest object - var request = new HttpRequestMessage(httpMethod, requestUri); - - // pull in session data - if (WebSession.Headers.Count > 0) - { - WebSession.ContentHeaders.Clear(); - foreach (var entry in WebSession.Headers) - { - if (HttpKnownHeaderNames.ContentHeaders.Contains(entry.Key)) - { - WebSession.ContentHeaders.Add(entry.Key, entry.Value); - } - else - { - if (stripAuthorization - && - String.Equals(entry.Key, HttpKnownHeaderNames.Authorization.ToString(), StringComparison.OrdinalIgnoreCase) - ) - { - continue; - } - - if (SkipHeaderValidation) - { - request.Headers.TryAddWithoutValidation(entry.Key, entry.Value); - } - else - { - request.Headers.Add(entry.Key, entry.Value); - } - } - } - } - - // Set 'Transfer-Encoding: chunked' if 'Transfer-Encoding' is specified - if (WebSession.Headers.ContainsKey(HttpKnownHeaderNames.TransferEncoding)) - { - request.Headers.TransferEncodingChunked = true; - } - - // Set 'User-Agent' if WebSession.Headers doesn't already contain it - string userAgent = null; - if (WebSession.Headers.TryGetValue(HttpKnownHeaderNames.UserAgent, out userAgent)) - { - WebSession.UserAgent = userAgent; - } - else - { - if (SkipHeaderValidation) - { - request.Headers.TryAddWithoutValidation(HttpKnownHeaderNames.UserAgent, WebSession.UserAgent); - } - else - { - request.Headers.Add(HttpKnownHeaderNames.UserAgent, WebSession.UserAgent); - } - - } - - // Set 'Keep-Alive' to false. This means set the Connection to 'Close'. - if (DisableKeepAlive) - { - request.Headers.Add(HttpKnownHeaderNames.Connection, "Close"); - } - - // Set 'Transfer-Encoding' - if (TransferEncoding != null) - { - request.Headers.TransferEncodingChunked = true; - var headerValue = new TransferCodingHeaderValue(TransferEncoding); - if (!request.Headers.TransferEncoding.Contains(headerValue)) - { - request.Headers.TransferEncoding.Add(headerValue); - } - } - - // Some web sites (e.g. Twitter) will return exception on POST when Expect100 is sent - // Default behavior is continue to send body content anyway after a short period - // Here it send the two part as a whole. - request.Headers.ExpectContinue = false; - - return (request); - } - - internal virtual void FillRequestStream(HttpRequestMessage request) - { - if (null == request) { throw new ArgumentNullException("request"); } - - // set the content type - if (ContentType != null) - { - WebSession.ContentHeaders[HttpKnownHeaderNames.ContentType] = ContentType; - //request - } - // ContentType == null - else if (Method == WebRequestMethod.Post || (IsCustomMethodSet() && CustomMethod.ToUpperInvariant() == "POST")) - { - // Win8:545310 Invoke-WebRequest does not properly set MIME type for POST - string contentType = null; - WebSession.ContentHeaders.TryGetValue(HttpKnownHeaderNames.ContentType, out contentType); - if (string.IsNullOrEmpty(contentType)) - { - WebSession.ContentHeaders[HttpKnownHeaderNames.ContentType] = "application/x-www-form-urlencoded"; - } - } - - // coerce body into a usable form - if (Body != null) - { - object content = Body; - - // make sure we're using the base object of the body, not the PSObject wrapper - PSObject psBody = Body as PSObject; - if (psBody != null) - { - content = psBody.BaseObject; - } - - /* TODO: This needs to be enable after the dependency on mshtml is resolved. - var html = content as HtmlWebResponseObject; - if (html != null) - { - // use the form if it's the only one present - if (html.Forms.Count == 1) - { - SetRequestContent(request, html.Forms[0].Fields); - } - } - else if (content is FormObject) - */ - - if (content is FormObject) - { - FormObject form = content as FormObject; - SetRequestContent(request, form.Fields); - } - else if (content is IDictionary && request.Method != HttpMethod.Get) - { - IDictionary dictionary = content as IDictionary; - SetRequestContent(request, dictionary); - } - else if (content is XmlNode) - { - XmlNode xmlNode = content as XmlNode; - SetRequestContent(request, xmlNode); - } - else if (content is Stream) - { - Stream stream = content as Stream; - SetRequestContent(request, stream); - } - else if (content is byte[]) - { - byte[] bytes = content as byte[]; - SetRequestContent(request, bytes); - } - else if (content is MultipartFormDataContent multipartFormDataContent) - { - WebSession.ContentHeaders.Clear(); - SetRequestContent(request, multipartFormDataContent); - } - else - { - SetRequestContent(request, - (string)LanguagePrimitives.ConvertTo(content, typeof(string), CultureInfo.InvariantCulture)); - } - } - else if (InFile != null) // copy InFile data - { - try - { - // open the input file - SetRequestContent(request, new FileStream(InFile, FileMode.Open)); - } - catch (UnauthorizedAccessException) - { - string msg = string.Format(CultureInfo.InvariantCulture, WebCmdletStrings.AccessDenied, - _originalFilePath); - throw new UnauthorizedAccessException(msg); - } - } - - // Add the content headers - if (request.Content != null) - { - foreach (var entry in WebSession.ContentHeaders) - { - request.Content.Headers.Add(entry.Key, entry.Value); - } - } - } - - // Returns true if the status code is one of the supported redirection codes. - static bool IsRedirectCode(HttpStatusCode code) - { - int intCode = (int) code; - return - ( - (intCode >= 300 && intCode < 304) - || - intCode == 307 - ); - } - - // Returns true if the status code is a redirection code and the action requires switching from POST to GET on redirection. - // NOTE: Some of these status codes map to the same underlying value but spelling them out for completeness. - static bool IsRedirectToGet(HttpStatusCode code) - { - return - ( - code == HttpStatusCode.Found - || - code == HttpStatusCode.Moved - || - code == HttpStatusCode.Redirect - || - code == HttpStatusCode.RedirectMethod - || - code == HttpStatusCode.TemporaryRedirect - || - code == HttpStatusCode.RedirectKeepVerb - || - code == HttpStatusCode.SeeOther - ); - } - - internal virtual HttpResponseMessage GetResponse(HttpClient client, HttpRequestMessage request, bool stripAuthorization) - { - if (client == null) { throw new ArgumentNullException("client"); } - if (request == null) { throw new ArgumentNullException("request"); } - - _cancelToken = new CancellationTokenSource(); - HttpResponseMessage response = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, _cancelToken.Token).GetAwaiter().GetResult(); - - if (stripAuthorization && IsRedirectCode(response.StatusCode)) - { - _cancelToken.Cancel(); - _cancelToken = null; - - // if explicit count was provided, reduce it for this redirection. - if (WebSession.MaximumRedirection > 0) - { - WebSession.MaximumRedirection--; - } - // For selected redirects that used POST, GET must be used with the - // redirected Location. - // Since GET is the default; POST only occurs when -Method POST is used. - if (Method == WebRequestMethod.Post && IsRedirectToGet(response.StatusCode)) - { - // See https://msdn.microsoft.com/en-us/library/system.net.httpstatuscode(v=vs.110).aspx - Method = WebRequestMethod.Get; - } - - // recreate the HttpClient with redirection enabled since the first call suppressed redirection - using (client = GetHttpClient(false)) - using (HttpRequestMessage redirectRequest = GetRequest(response.Headers.Location, stripAuthorization:true)) - { - FillRequestStream(redirectRequest); - _cancelToken = new CancellationTokenSource(); - response = client.SendAsync(redirectRequest, HttpCompletionOption.ResponseHeadersRead, _cancelToken.Token).GetAwaiter().GetResult(); - } - } - return response; - } - - internal virtual void UpdateSession(HttpResponseMessage response) - { - if (response == null) { throw new ArgumentNullException("response"); } - } - - #endregion Virtual Methods - - #region Overrides - - /// - /// the main execution method for cmdlets derived from WebRequestPSCmdlet. - /// - protected override void ProcessRecord() - { - try - { - // Set cmdlet context for write progress - ValidateParameters(); - PrepareSession(); - - // if the request contains an authorization header and PreserveAuthorizationOnRedirect is not set, - // it needs to be stripped on the first redirect. - bool stripAuthorization = null != WebSession - && - null != WebSession.Headers - && - !PreserveAuthorizationOnRedirect.IsPresent - && - WebSession.Headers.ContainsKey(HttpKnownHeaderNames.Authorization.ToString()); - - using (HttpClient client = GetHttpClient(stripAuthorization)) - { - int followedRelLink = 0; - Uri uri = Uri; - do - { - if (followedRelLink > 0) - { - string linkVerboseMsg = string.Format(CultureInfo.CurrentCulture, - WebCmdletStrings.FollowingRelLinkVerboseMsg, - uri.AbsoluteUri); - WriteVerbose(linkVerboseMsg); - } - - using (HttpRequestMessage request = GetRequest(uri, stripAuthorization:false)) - { - FillRequestStream(request); - try - { - long requestContentLength = 0; - if (request.Content != null) - requestContentLength = request.Content.Headers.ContentLength.Value; - - string reqVerboseMsg = String.Format(CultureInfo.CurrentCulture, - WebCmdletStrings.WebMethodInvocationVerboseMsg, - request.Method, - request.RequestUri, - requestContentLength); - WriteVerbose(reqVerboseMsg); - - HttpResponseMessage response = GetResponse(client, request, stripAuthorization); - - string contentType = ContentHelper.GetContentType(response); - string respVerboseMsg = string.Format(CultureInfo.CurrentCulture, - WebCmdletStrings.WebResponseVerboseMsg, - response.Content.Headers.ContentLength, - contentType); - WriteVerbose(respVerboseMsg); - - if (!response.IsSuccessStatusCode) - { - string message = String.Format(CultureInfo.CurrentCulture, WebCmdletStrings.ResponseStatusCodeFailure, - (int)response.StatusCode, response.ReasonPhrase); - HttpResponseException httpEx = new HttpResponseException(message, response); - ErrorRecord er = new ErrorRecord(httpEx, "WebCmdletWebResponseException", ErrorCategory.InvalidOperation, request); - string detailMsg = ""; - StreamReader reader = null; - try - { - reader = new StreamReader(StreamHelper.GetResponseStream(response)); - // remove HTML tags making it easier to read - detailMsg = System.Text.RegularExpressions.Regex.Replace(reader.ReadToEnd(), "<[^>]*>",""); - } - catch (Exception) - { - // catch all - } - finally - { - if (reader != null) - { - reader.Dispose(); - } - } - if (!String.IsNullOrEmpty(detailMsg)) - { - er.ErrorDetails = new ErrorDetails(detailMsg); - } - ThrowTerminatingError(er); - } - - if (_parseRelLink || _followRelLink) - { - ParseLinkHeader(response, uri); - } - ProcessResponse(response); - UpdateSession(response); - - // If we hit our maximum redirection count, generate an error. - // Errors with redirection counts of greater than 0 are handled automatically by .NET, but are - // impossible to detect programmatically when we hit this limit. By handling this ourselves - // (and still writing out the result), users can debug actual HTTP redirect problems. - if (WebSession.MaximumRedirection == 0) // Indicate "HttpClientHandler.AllowAutoRedirect == false" - { - if (response.StatusCode == HttpStatusCode.Found || - response.StatusCode == HttpStatusCode.Moved || - response.StatusCode == HttpStatusCode.MovedPermanently) - { - ErrorRecord er = new ErrorRecord(new InvalidOperationException(), "MaximumRedirectExceeded", ErrorCategory.InvalidOperation, request); - er.ErrorDetails = new ErrorDetails(WebCmdletStrings.MaximumRedirectionCountExceeded); - WriteError(er); - } - } - } - catch (HttpRequestException ex) - { - ErrorRecord er = new ErrorRecord(ex, "WebCmdletWebResponseException", ErrorCategory.InvalidOperation, request); - if (ex.InnerException != null) - { - er.ErrorDetails = new ErrorDetails(ex.InnerException.Message); - } - ThrowTerminatingError(er); - } - - if (_followRelLink) - { - if (!_relationLink.ContainsKey("next")) - { - return; - } - uri = new Uri(_relationLink["next"]); - followedRelLink++; - } - } - } - while (_followRelLink && (followedRelLink < _maximumFollowRelLink)); - } - } - catch (CryptographicException ex) - { - ErrorRecord er = new ErrorRecord(ex, "WebCmdletCertificateException", ErrorCategory.SecurityError, null); - ThrowTerminatingError(er); - } - catch (NotSupportedException ex) - { - ErrorRecord er = new ErrorRecord(ex, "WebCmdletIEDomNotSupportedException", ErrorCategory.NotImplemented, null); - ThrowTerminatingError(er); - } - } - - /// - /// Implementing ^C, after start the BeginGetResponse - /// - protected override void StopProcessing() - { - if (_cancelToken != null) - { - _cancelToken.Cancel(); - } - } - - #endregion Overrides - - #region Helper Methods - - /// - /// Sets the ContentLength property of the request and writes the specified content to the request's RequestStream. - /// - /// The WebRequest who's content is to be set - /// A byte array containing the content data. - /// The number of bytes written to the requests RequestStream (and the new value of the request's ContentLength property - /// - /// Because this function sets the request's ContentLength property and writes content data into the requests's stream, - /// it should be called one time maximum on a given request. - /// - internal long SetRequestContent(HttpRequestMessage request, Byte[] content) - { - if (request == null) - throw new ArgumentNullException("request"); - if (content == null) - return 0; - - var byteArrayContent = new ByteArrayContent(content); - request.Content = byteArrayContent; - - return byteArrayContent.Headers.ContentLength.Value; - } - - /// - /// Sets the ContentLength property of the request and writes the specified content to the request's RequestStream. - /// - /// The WebRequest who's content is to be set - /// A String object containing the content data. - /// The number of bytes written to the requests RequestStream (and the new value of the request's ContentLength property - /// - /// Because this function sets the request's ContentLength property and writes content data into the requests's stream, - /// it should be called one time maximum on a given request. - /// - internal long SetRequestContent(HttpRequestMessage request, string content) - { - if (request == null) - throw new ArgumentNullException("request"); - - if (content == null) - return 0; - - Encoding encoding = null; - if (ContentType != null) - { - // If Content-Type contains the encoding format (as CharSet), use this encoding format - // to encode the Body of the WebRequest sent to the server. Default Encoding format - // would be used if Charset is not supplied in the Content-Type property. - var mediaTypeHeaderValue = new MediaTypeHeaderValue(ContentType); - if (!string.IsNullOrEmpty(mediaTypeHeaderValue.CharSet)) - { - try - { - encoding = Encoding.GetEncoding(mediaTypeHeaderValue.CharSet); - } - catch (ArgumentException ex) - { - ErrorRecord er = new ErrorRecord(ex, "WebCmdletEncodingException", ErrorCategory.InvalidArgument, ContentType); - ThrowTerminatingError(er); - } - } - } - - Byte[] bytes = StreamHelper.EncodeToBytes(content, encoding); - var byteArrayContent = new ByteArrayContent(bytes); - request.Content = byteArrayContent; - - return byteArrayContent.Headers.ContentLength.Value; - } - - internal long SetRequestContent(HttpRequestMessage request, XmlNode xmlNode) - { - if (request == null) - throw new ArgumentNullException("request"); - - if (xmlNode == null) - return 0; - - Byte[] bytes = null; - XmlDocument doc = xmlNode as XmlDocument; - if (doc != null && (doc.FirstChild as XmlDeclaration) != null) - { - XmlDeclaration decl = doc.FirstChild as XmlDeclaration; - Encoding encoding = Encoding.GetEncoding(decl.Encoding); - bytes = StreamHelper.EncodeToBytes(doc.OuterXml, encoding); - } - else - { - bytes = StreamHelper.EncodeToBytes(xmlNode.OuterXml); - } - - var byteArrayContent = new ByteArrayContent(bytes); - request.Content = byteArrayContent; - - return byteArrayContent.Headers.ContentLength.Value; - } - - /// - /// Sets the ContentLength property of the request and writes the specified content to the request's RequestStream. - /// - /// The WebRequest who's content is to be set - /// A Stream object containing the content data. - /// The number of bytes written to the requests RequestStream (and the new value of the request's ContentLength property - /// - /// Because this function sets the request's ContentLength property and writes content data into the requests's stream, - /// it should be called one time maximum on a given request. - /// - internal long SetRequestContent(HttpRequestMessage request, Stream contentStream) - { - if (request == null) - throw new ArgumentNullException("request"); - if (contentStream == null) - throw new ArgumentNullException("contentStream"); - - var streamContent = new StreamContent(contentStream); - request.Content = streamContent; - - return streamContent.Headers.ContentLength.Value; - } - - /// - /// Sets the ContentLength property of the request and writes the specified content to the request's RequestStream. - /// - /// The WebRequest who's content is to be set - /// A MultipartFormDataContent object containing multipart/form-data content. - /// The number of bytes written to the requests RequestStream (and the new value of the request's ContentLength property - /// - /// Because this function sets the request's ContentLength property and writes content data into the requests's stream, - /// it should be called one time maximum on a given request. - /// - internal long SetRequestContent(HttpRequestMessage request, MultipartFormDataContent multipartContent) - { - if (request == null) - { - throw new ArgumentNullException("request"); - } - if (multipartContent == null) - { - throw new ArgumentNullException("multipartContent"); - } - - request.Content = multipartContent; - - return multipartContent.Headers.ContentLength.Value; - } - - internal long SetRequestContent(HttpRequestMessage request, IDictionary content) - { - if (request == null) - throw new ArgumentNullException("request"); - if (content == null) - throw new ArgumentNullException("content"); - - string body = FormatDictionary(content); - return (SetRequestContent(request, body)); - - } - - internal void ParseLinkHeader(HttpResponseMessage response, System.Uri requestUri) - { - if (_relationLink == null) - { - _relationLink = new Dictionary(); - } - else - { - _relationLink.Clear(); - } - - // we only support the URL in angle brackets and `rel`, other attributes are ignored - // user can still parse it themselves via the Headers property - string pattern = "<(?.*?)>;\\srel=\"(?.*?)\""; - IEnumerable links; - if (response.Headers.TryGetValues("Link", out links)) - { - foreach(string link in links.FirstOrDefault().Split(",")) - { - Match match = Regex.Match(link, pattern); - if (match.Success) - { - string url = match.Groups["url"].Value; - string rel = match.Groups["rel"].Value; - if (url != String.Empty && rel != String.Empty && !_relationLink.ContainsKey(rel)) - { - Uri absoluteUri = new Uri(requestUri, url); - _relationLink.Add(rel, absoluteUri.AbsoluteUri.ToString()); - } - } - } - } - } - - #endregion Helper Methods - } -} -#endif diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebResponseHelper.CoreClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebResponseHelper.CoreClr.cs index fbcbdd80181..47b0367f220 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebResponseHelper.CoreClr.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebResponseHelper.CoreClr.cs @@ -1,8 +1,5 @@ -#if CORECLR - -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; @@ -18,7 +15,7 @@ internal static string GetCharacterSet(HttpResponseMessage response) string characterSet = response.Content.Headers.ContentType.CharSet; return characterSet; } - + internal static Dictionary> GetHeadersDictionary(HttpResponseMessage response) { var headers = new Dictionary>(StringComparer.OrdinalIgnoreCase); @@ -26,7 +23,7 @@ internal static Dictionary> GetHeadersDictionary(Htt { headers[entry.Key] = entry.Value; } - // In CoreFX, HttpResponseMessage separates content related headers, such as Content-Type to + // In CoreFX, HttpResponseMessage separates content related headers, such as Content-Type to // HttpResponseMessage.Content.Headers. The remaining headers are in HttpResponseMessage.Headers. // The keys in both should be unique with no duplicates between them. // Added for backwards compatibility with PowerShell 5.1 and earlier. @@ -68,4 +65,3 @@ internal static bool IsText(HttpResponseMessage response) } } } -#endif \ No newline at end of file diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebResponseObject.CoreClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebResponseObject.CoreClr.cs deleted file mode 100644 index d683a833b4b..00000000000 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebResponseObject.CoreClr.cs +++ /dev/null @@ -1,125 +0,0 @@ -#if CORECLR - -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - -using System; -using System.Text; -using System.Net.Http; -using System.Collections.Generic; -using System.IO; - -namespace Microsoft.PowerShell.Commands -{ - /// - /// WebResponseObject - /// - public partial class WebResponseObject - { - #region Properties - - /// - /// gets or sets the BaseResponse property - /// - public HttpResponseMessage BaseResponse { get; set; } - - /// - /// gets the Headers property - /// - public Dictionary> Headers - { - get - { - if(_headers == null) - { - _headers = WebResponseHelper.GetHeadersDictionary(BaseResponse); - } - - return _headers; - } - } - - private Dictionary> _headers = null; - - /// - /// gets the RelationLink property - /// - public Dictionary RelationLink { get; internal set; } - - #endregion - - #region Constructors - - /// - /// Constructor for WebResponseObject - /// - /// - public WebResponseObject(HttpResponseMessage response) - : this(response, null) - { } - - /// - /// Constructor for WebResponseObject with contentStream - /// - /// - /// - public WebResponseObject(HttpResponseMessage response, Stream contentStream) - { - SetResponse(response, contentStream); - InitializeContent(); - InitializeRawContent(response); - } - - #endregion Constructors - - #region Methods - - private void InitializeRawContent(HttpResponseMessage baseResponse) - { - StringBuilder raw = ContentHelper.GetRawContentHeader(baseResponse); - - // Use ASCII encoding for the RawContent visual view of the content. - if (Content.Length > 0) - { - raw.Append(this.ToString()); - } - - this.RawContent = raw.ToString(); - } - - private void SetResponse(HttpResponseMessage response, Stream contentStream) - { - if (null == response) { throw new ArgumentNullException("response"); } - - BaseResponse = response; - - MemoryStream ms = contentStream as MemoryStream; - if (null != ms) - { - _rawContentStream = ms; - } - else - { - Stream st = contentStream; - if (contentStream == null) - { - st = StreamHelper.GetResponseStream(response); - } - - long contentLength = response.Content.Headers.ContentLength.Value; - if (0 >= contentLength) - { - contentLength = StreamHelper.DefaultReadBuffer; - } - int initialCapacity = (int)Math.Min(contentLength, StreamHelper.DefaultReadBuffer); - _rawContentStream = new WebResponseContentMemoryStream(st, initialCapacity, null); - } - // set the position of the content stream to the beginning - _rawContentStream.Position = 0; - } - - #endregion - } -} -#endif \ No newline at end of file diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebResponseObjectFactory.CoreClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebResponseObjectFactory.CoreClr.cs index f706ae5a142..0e7689788eb 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebResponseObjectFactory.CoreClr.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebResponseObjectFactory.CoreClr.cs @@ -1,8 +1,5 @@ -#if CORECLR - -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Net.Http; using System.IO; @@ -12,22 +9,13 @@ namespace Microsoft.PowerShell.Commands { internal static class WebResponseObjectFactory { - internal static WebResponseObject GetResponseObject(HttpResponseMessage response, Stream responseStream, ExecutionContext executionContext, bool useBasicParsing = false) + internal static WebResponseObject GetResponseObject(HttpResponseMessage response, Stream responseStream, ExecutionContext executionContext) { WebResponseObject output; if (WebResponseHelper.IsText(response)) { output = new BasicHtmlWebResponseObject(response, responseStream); - // TODO: This code needs to be enable after the dependency on mshtml is resolved. - //if (useBasicParsing) - //{ - // output = new BasicHtmlWebResponseObject(response, responseStream); - //} - //else - //{ - // output = new HtmlWebResponseObject(response, responseStream, executionContext); - //} } else { @@ -37,4 +25,3 @@ internal static WebResponseObject GetResponseObject(HttpResponseMessage response } } } -#endif \ No newline at end of file diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FormObject.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FormObject.cs index 1ae2083a5d0..a4ca4ab6671 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FormObject.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FormObject.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FormObjectCollection.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FormObjectCollection.cs index 3fdfa1c6f55..601c12e2c7b 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FormObjectCollection.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FormObjectCollection.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.ObjectModel; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/BasicHtmlWebResponseObject.FullClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/BasicHtmlWebResponseObject.FullClr.cs deleted file mode 100644 index 80ee6bb1d22..00000000000 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/BasicHtmlWebResponseObject.FullClr.cs +++ /dev/null @@ -1,52 +0,0 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - -using System.Net; -using System.IO; -using System.Text; - -namespace Microsoft.PowerShell.Commands -{ - /// - /// Response object for html content without DOM parsing - /// - public partial class BasicHtmlWebResponseObject : WebResponseObject - { - #region Constructors - - /// - /// Constructor for HtmlWebResponseObject - /// - /// - public BasicHtmlWebResponseObject(WebResponse response) - : this(response, null) - { } - - /// - /// Constructor for HtmlWebResponseObject with memory stream - /// - /// - /// - public BasicHtmlWebResponseObject(WebResponse response, Stream contentStream) - : base(response, contentStream) - { - EnsureHtmlParser(); - InitializeContent(); - InitializeRawContent(response); - } - - #endregion Constructors - - #region Methods - - private void InitializeRawContent(WebResponse baseResponse) - { - StringBuilder raw = ContentHelper.GetRawContentHeader(baseResponse); - raw.Append(Content); - this.RawContent = raw.ToString(); - } - - #endregion Methods - } -} diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/ContentHelper.FullClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/ContentHelper.FullClr.cs deleted file mode 100644 index 12d7d14d946..00000000000 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/ContentHelper.FullClr.cs +++ /dev/null @@ -1,65 +0,0 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - -using System; -using System.Text; -using System.Net; - -namespace Microsoft.PowerShell.Commands -{ - internal static partial class ContentHelper - { - internal static Encoding GetEncoding(WebResponse response) - { - string characterSet = null; - HttpWebResponse httpResponse = response as HttpWebResponse; - if (null != httpResponse) - { - characterSet = httpResponse.CharacterSet; - } - - return GetEncodingOrDefault(characterSet); - } - - // Gets the content type with safe fallback - in the situation - // of FTPWebResponse that returns NotImplemented. - internal static string GetContentType(WebResponse response) - { - string contentType = null; - try - { - contentType = response.ContentType; - } - catch (NotImplementedException) { } - - return contentType; - } - - internal static StringBuilder GetRawContentHeader(WebResponse baseResponse) - { - StringBuilder raw = new StringBuilder(); - - // add protocol and status line - string protocol = WebResponseHelper.GetProtocol(baseResponse); - if (!String.IsNullOrEmpty(protocol)) - { - int statusCode = WebResponseHelper.GetStatusCode(baseResponse); - string statusDescription = WebResponseHelper.GetStatusDescription(baseResponse); - raw.AppendFormat("{0} {1} {2}", protocol, statusCode, statusDescription); - raw.AppendLine(); - } - - // add headers - foreach (string key in baseResponse.Headers.AllKeys) - { - string value = baseResponse.Headers[key]; - raw.AppendFormat("{0}: {1}", key, value); - raw.AppendLine(); - } - - raw.AppendLine(); - return raw; - } - } -} \ No newline at end of file diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/HtmlWebResponseObject.FullClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/HtmlWebResponseObject.FullClr.cs deleted file mode 100644 index 807811ef75d..00000000000 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/HtmlWebResponseObject.FullClr.cs +++ /dev/null @@ -1,65 +0,0 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - -using System; -using System.Management.Automation; -using System.Net; -using System.IO; -using System.Text; -using ExecutionContext = System.Management.Automation.ExecutionContext; - -namespace Microsoft.PowerShell.Commands -{ - /// - /// Response object for html content - /// - public partial class HtmlWebResponseObject : WebResponseObject, IDisposable - { - #region Constructors - - /// - /// Constructor for HtmlWebResponseObject - /// - /// - /// - internal HtmlWebResponseObject(WebResponse response, ExecutionContext executionContext) - : this(response, null, executionContext) - { } - - /// - /// Constructor for HtmlWebResponseObject with memory stream - /// - /// - /// - /// - internal HtmlWebResponseObject(WebResponse response, Stream contentStream, ExecutionContext executionContext) - : base(response, contentStream) - { - if (executionContext == null) - { - throw PSTraceSource.NewArgumentNullException("executionContext"); - } - - _executionContext = executionContext; - InitializeContent(); - InitializeRawContent(response); - } - - #endregion Constructors - - #region Methods - - private void InitializeRawContent(WebResponse baseResponse) - { - StringBuilder raw = ContentHelper.GetRawContentHeader(baseResponse); - if (null != Content) - { - raw.Append(Content); - } - this.RawContent = raw.ToString(); - } - - #endregion - } -} diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/InvokeRestMethodCommand.FullClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/InvokeRestMethodCommand.FullClr.cs deleted file mode 100644 index c07f151ab61..00000000000 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/InvokeRestMethodCommand.FullClr.cs +++ /dev/null @@ -1,112 +0,0 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - -using System; -using System.Management.Automation; -using System.Net; -using System.Collections; -using System.IO; -using System.Xml; -using System.Text; - -namespace Microsoft.PowerShell.Commands -{ - /// - /// The Invoke-RestMethod command - /// This command makes an HTTP or HTTPS request to a web service, - /// and returns the response in an appropriate way. - /// Intended to work against the wide spectrum of "RESTful" web services - /// currently deployed across the web. - /// - [Cmdlet(VerbsLifecycle.Invoke, "RestMethod", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=217034", DefaultParameterSetName = "StandardMethod")] - public partial class InvokeRestMethodCommand : WebRequestPSCmdlet - { - #region Virtual Method Overrides - - /// - /// Process the web response and output corresponding objects. - /// - /// - internal override void ProcessResponse(WebResponse response) - { - if (null == response) { throw new ArgumentNullException("response"); } - - using (BufferingStreamReader responseStream = new BufferingStreamReader(StreamHelper.GetResponseStream(response))) - { - if (ShouldWriteToPipeline) - { - // First see if it is an RSS / ATOM feed, in which case we can - // stream it - unless the user has overridden it with a return type of "XML" - if (TryProcessFeedStream(responseStream)) - { - // Do nothing, content has been processed. - } - else - { - // determine the response type - RestReturnType returnType = CheckReturnType(response); - // get the response encoding - Encoding encoding = ContentHelper.GetEncoding(response); - - object obj = null; - Exception ex = null; - - string str = StreamHelper.DecodeStream(responseStream, encoding); - bool convertSuccess = false; - if (returnType == RestReturnType.Json) - { - convertSuccess = TryConvertToJson(str, out obj, ref ex) || TryConvertToXml(str, out obj, ref ex); - } - // default to try xml first since it's more common - else - { - convertSuccess = TryConvertToXml(str, out obj, ref ex) || TryConvertToJson(str, out obj, ref ex); - } - - if (!convertSuccess) - { - // fallback to string - obj = str; - } - - WriteObject(obj); - } - } - - if (ShouldSaveToOutFile) - { - StreamHelper.SaveStreamToFile(responseStream, QualifiedOutFile, this); - } - } - } - - #endregion Virtual Method Overrides - - #region Helper Methods - - private RestReturnType CheckReturnType(WebResponse response) - { - if (null == response) { throw new ArgumentNullException("response"); } - - RestReturnType rt = RestReturnType.Detect; - string contentType = ContentHelper.GetContentType(response); - if (string.IsNullOrEmpty(contentType)) - { - rt = RestReturnType.Detect; - } - else if (ContentHelper.IsJson(contentType)) - { - rt = RestReturnType.Json; - } - else if (ContentHelper.IsXml(contentType)) - { - rt = RestReturnType.Xml; - } - - return (rt); - } - - #endregion Helper Methods - } -} \ No newline at end of file diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/InvokeWebRequestCommand.FullClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/InvokeWebRequestCommand.FullClr.cs deleted file mode 100644 index cb5a5710783..00000000000 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/InvokeWebRequestCommand.FullClr.cs +++ /dev/null @@ -1,58 +0,0 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - -using System; -using System.Management.Automation; -using System.Net; -using System.IO; - -namespace Microsoft.PowerShell.Commands -{ - /// - /// The Invoke-RestMethod command - /// This command makes an HTTP or HTTPS request to a web server and returns the results. - /// - [Cmdlet(VerbsLifecycle.Invoke, "WebRequest", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=217035", DefaultParameterSetName = "StandardMethod")] - public class InvokeWebRequestCommand : WebRequestPSCmdlet - { - #region Virtual Method Overrides - - /// - /// Process the web response and output corresponding objects. - /// - /// - internal override void ProcessResponse(WebResponse response) - { - if (null == response) { throw new ArgumentNullException("response"); } - - // check for Server Core, throws exception if -UseBasicParsing is not used - if (ShouldWriteToPipeline && (!UseBasicParsing)) - { - VerifyInternetExplorerAvailable(true); - } - - Stream responseStream = StreamHelper.GetResponseStream(response); - if (ShouldWriteToPipeline) - { - // creating a MemoryStream wrapper to response stream here to support IsStopping. - responseStream = new WebResponseContentMemoryStream(responseStream, StreamHelper.ChunkSize, this); - WebResponseObject ro = WebResponseObjectFactory.GetResponseObject(response, responseStream, this.Context, UseBasicParsing); - WriteObject(ro); - - // use the rawcontent stream from WebResponseObject for further - // processing of the stream. This is need because WebResponse's - // stream can be used only once. - responseStream = ro.RawContentStream; - responseStream.Seek(0, SeekOrigin.Begin); - } - - if (ShouldSaveToOutFile) - { - StreamHelper.SaveStreamToFile(responseStream, QualifiedOutFile, this); - } - } - - #endregion Virtual Method Overrides - } -} \ No newline at end of file diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/JsonObjectTypeResolver.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/JsonObjectTypeResolver.cs deleted file mode 100644 index 142b64c1d73..00000000000 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/JsonObjectTypeResolver.cs +++ /dev/null @@ -1,29 +0,0 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - -using System; -using System.Collections.Generic; -using System.Web.Script.Serialization; - -namespace Microsoft.PowerShell.Commands -{ - internal class JsonObjectTypeResolver : JavaScriptTypeResolver - { - public override Type ResolveType(string id) - { - // TODO: this seems to work, but it's still a little suspect - // and probably worth gaining a little deeper understanding. - Type type = typeof(Dictionary); - return (type); - } - - /// - /// Override abstract methods - /// - public override string ResolveTypeId(Type type) - { - return (string.Empty); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/WebRequestPSCmdlet.FullClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/WebRequestPSCmdlet.FullClr.cs deleted file mode 100644 index c1b65ba3ee3..00000000000 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/WebRequestPSCmdlet.FullClr.cs +++ /dev/null @@ -1,797 +0,0 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - -using System; -using System.Management.Automation; -using System.Net; -using System.IO; -using System.Text; -using System.Collections; -using System.Globalization; -using System.Security.Cryptography; -using System.Threading; -using System.Web; -using System.Xml; -using mshtml; - -namespace Microsoft.PowerShell.Commands -{ - /// - /// Base class for Invoke-RestMethod and Invoke-WebRequest commands. - /// - public abstract partial class WebRequestPSCmdlet : PSCmdlet - { - #region Abstract Methods - - /// - /// Read the supplied WebResponse object and push the - /// resulting output into the pipeline. - /// - /// Instance of a WebResponse object to be processed - internal abstract void ProcessResponse(WebResponse response); - - #endregion Abstract Methods - - /// - /// the WebRequest we will GetResponse for. - /// - private WebRequest _webRequest; - - #region Virtual Methods - - internal virtual WebRequest GetRequest(Uri uri) - { - uri = PrepareUri(uri); - // create the base WebRequest object - WebRequest request = WebRequest.Create(uri); - - // pull in session data - if (0 < WebSession.Headers.Count) - { - try - { - HttpWebRequest webRequest = request as HttpWebRequest; - request.Headers.Clear(); - foreach (string key in WebSession.Headers.Keys) - { - bool setHeaderViaProperty = TryMapHeaderToProperty(webRequest, key); - - if (!setHeaderViaProperty) - { - request.Headers[key] = WebSession.Headers[key]; - } - } - } - catch (NotImplementedException) - { - } - } - - // set the credentials used by this request - if (WebSession.UseDefaultCredentials) - { - // the UseDefaultCredentials flag overrides other supplied credentials - request.UseDefaultCredentials = true; - } - else if (null != WebSession.Credentials) - { - request.Credentials = WebSession.Credentials; - } - - if (NoProxy) - { - handler.UseProxy = false; - } - else if (WebSession.Proxy != null) - { - request.Proxy = WebSession.Proxy; - } - - switch (ParameterSetName) - { - case "StandardMethodNoProxy": - goto case "StandardMethod"; - case "StandardMethod": - if (WebRequestMethod.Default != Method) - { - // set the method if the parameter was provided - request.Method = Method.ToString().ToUpperInvariant(); - } - break; - case "CustomMethodNoProxy": - goto case "CustomMethod"; - case "CustomMethod": - // set the method if the parameter was provided - request.Method = CustomMethod.ToUpperInvariant(); - break; - } - - // pull in http specific properties - HttpWebRequest httpRequest = request as HttpWebRequest; - if (null != httpRequest) - { - httpRequest.CookieContainer = WebSession.Cookies; - httpRequest.UserAgent = WebSession.UserAgent; - - if (null != WebSession.Certificates) - { - httpRequest.ClientCertificates = WebSession.Certificates; - } - - if (-1 < WebSession.MaximumRedirection) - { - if (WebSession.MaximumRedirection == 0) - { - httpRequest.AllowAutoRedirect = false; - } - else - { - httpRequest.MaximumAutomaticRedirections = WebSession.MaximumRedirection; - } - } - - // check timeout setting (in seconds instead of milliseconds as in HttpWebRequest) - if (TimeoutSec == 0) - { - // A zero timeout means infinite - httpRequest.Timeout = Timeout.Infinite; - } - else if (TimeoutSec > 0) - { - // just to make sure - if (TimeoutSec > Int32.MaxValue / 1000) - { - httpRequest.Timeout = Int32.MaxValue; - } - else - { - httpRequest.Timeout = TimeoutSec * 1000; - } - } - - // check keep-alive setting - if (DisableKeepAlive) - { - // default value is true, so only need to set if false. - httpRequest.KeepAlive = false; - } - - if (null != TransferEncoding) - { - httpRequest.SendChunked = true; - httpRequest.TransferEncoding = TransferEncoding; - } - } - - return (request); - } - - private bool TryMapHeaderToProperty(HttpWebRequest webRequest, string key) - { - bool setHeaderViaProperty = false; - - // Perform header-to-property overrides - if (webRequest != null) - { - if (String.Equals("Accept", key, StringComparison.OrdinalIgnoreCase)) - { - webRequest.Accept = WebSession.Headers[key]; - setHeaderViaProperty = true; - } - - if (String.Equals("Connection", key, StringComparison.OrdinalIgnoreCase)) - { - webRequest.Connection = WebSession.Headers[key]; - setHeaderViaProperty = true; - } - - if (String.Equals("Content-Length", key, StringComparison.OrdinalIgnoreCase)) - { - webRequest.ContentLength = Convert.ToInt64(WebSession.Headers[key], CultureInfo.InvariantCulture); - setHeaderViaProperty = true; - } - - if (String.Equals("Content-Type", key, StringComparison.OrdinalIgnoreCase)) - { - webRequest.ContentType = WebSession.Headers[key]; - setHeaderViaProperty = true; - } - - if (String.Equals("Date", key, StringComparison.OrdinalIgnoreCase)) - { - webRequest.Date = DateTime.Parse(WebSession.Headers[key], CultureInfo.InvariantCulture); - setHeaderViaProperty = true; - } - - if (String.Equals("Expect", key, StringComparison.OrdinalIgnoreCase)) - { - webRequest.Expect = WebSession.Headers[key]; - setHeaderViaProperty = true; - } - - if (String.Equals("Host", key, StringComparison.OrdinalIgnoreCase)) - { - webRequest.Host = WebSession.Headers[key]; - setHeaderViaProperty = true; - } - - if (String.Equals("If-Modified-Since", key, StringComparison.OrdinalIgnoreCase)) - { - webRequest.IfModifiedSince = DateTime.Parse(WebSession.Headers[key], CultureInfo.InvariantCulture); - setHeaderViaProperty = true; - } - - if (String.Equals("Referer", key, StringComparison.OrdinalIgnoreCase)) - { - webRequest.Referer = WebSession.Headers[key]; - setHeaderViaProperty = true; - } - - if (String.Equals("Transfer-Encoding", key, StringComparison.OrdinalIgnoreCase)) - { - webRequest.SendChunked = true; - - if (String.Equals("Chunked", WebSession.Headers[key], StringComparison.OrdinalIgnoreCase)) - { - // .NET Doesn't support setting both the header and the property - webRequest.SendChunked = true; - } - else - { - webRequest.TransferEncoding = WebSession.Headers[key]; - } - - setHeaderViaProperty = true; - } - - if (String.Equals("User-Agent", key, StringComparison.OrdinalIgnoreCase)) - { - WebSession.UserAgent = WebSession.Headers[key]; - webRequest.UserAgent = WebSession.Headers[key]; - setHeaderViaProperty = true; - } - } - return setHeaderViaProperty; - } - - internal virtual void FillRequestStream(WebRequest request) - { - if (null == request) { throw new ArgumentNullException("request"); } - - // set the content type - if (null != ContentType) - { - request.ContentType = ContentType; - } - // ContentType == null - else if ((IsStandardMethodSet() && Method == WebRequestMethod.Post) - || (IsCustomMethodSet() && CustomMethod.ToUpperInvariant() == "POST")) - { - // Win8:545310 Invoke-WebRequest does not properly set MIME type for POST - if (String.IsNullOrEmpty(request.ContentType)) - { - request.ContentType = "application/x-www-form-urlencoded"; - } - } - - // coerce body into a usable form - if (null != Body) - { - object content = Body; - - // make sure we're using the base object of the body, not the PSObject wrapper - PSObject psBody = Body as PSObject; - if (null != psBody) - { - content = psBody.BaseObject; - } - - if (null != content as HtmlWebResponseObject) - { - HtmlWebResponseObject html = content as HtmlWebResponseObject; - // use the form it's the only one present - if (html.Forms.Count == 1) - { - SetRequestContent(request, html.Forms[0].Fields); - } - } - else if (null != content as FormObject) - { - FormObject form = content as FormObject; - SetRequestContent(request, form.Fields); - } - else if (null != content as IDictionary && request.Method != WebRequestMethods.Http.Get) - { - IDictionary dictionary = content as IDictionary; - SetRequestContent(request, dictionary); - } - else if (null != content as XmlNode) - { - XmlNode xmlNode = content as XmlNode; - SetRequestContent(request, xmlNode); - } - else if (null != content as Stream) - { - Stream stream = content as Stream; - SetRequestContent(request, stream); - } - else if (null != content as byte[]) - { - byte[] bytes = content as byte[]; - SetRequestContent(request, bytes); - } - else - { - SetRequestContent(request, - (string)LanguagePrimitives.ConvertTo(content, typeof(string), CultureInfo.InvariantCulture)); - } - } - else if (null != InFile) // copy InFile data - { - try - { - // open the input file - using (FileStream fs = new FileStream(InFile, FileMode.Open)) - { - SetRequestContent(request, fs); - } - } - catch (UnauthorizedAccessException) - { - string msg = string.Format(CultureInfo.InvariantCulture, WebCmdletStrings.AccessDenied, - _originalFilePath); - throw new UnauthorizedAccessException(msg); - } - } - else - { - request.ContentLength = 0; - } - } - - internal virtual WebResponse GetResponse(WebRequest request) - { - if (null == request) { throw new ArgumentNullException("request"); } - - // Construct TimeoutState - HttpWebRequest httpRequest = request as HttpWebRequest; - TimeoutState timeoutState = null; - if (httpRequest != null && httpRequest.Timeout > 0) - { - timeoutState = new TimeoutState(httpRequest); - } - - // Construct WebRequestState - _webRequest = request; - WebRequestState requestState = new WebRequestState(request); - - // Call asynchronous GetResponse - IAsyncResult asyncResult = (IAsyncResult)request.BeginGetResponse(new AsyncCallback(ResponseCallback), requestState); - // Set timeout if necessary - if (timeoutState != null) - { - ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), timeoutState, timeoutState.httpRequest.Timeout, true); - } - - // Wait on signal - requestState.waithandle.WaitOne(-1, false); - requestState.waithandle.Close(); - _webRequest = null; - - // The current thread will be waked up in three cases: - // 1. the EngGetResponse is done. In this case, we EITHER get the response (requestState.response != null), - // OR a WebException is raised (requestState.webException != null). - // 2. the ^C is typed, a PipelineStoppedException is raised. StopProcessing will abort the request. In this - // case, there will be a WebException with status 'RequestCancelled'. - // 3. the time is up. The TimeoutCallback method will abort the request. In this case, there will also be a - // WebException with status 'RequestCancelled' and timeoutState.abort will be true. - if (requestState.webException != null) - { - // Case 3. We wrap the exception to be 'Timeout' WebException - if (timeoutState != null && timeoutState.abort && requestState.webException.Status.Equals(WebExceptionStatus.RequestCanceled)) - { - throw new WebException(WebCmdletStrings.RequestTimeout, WebExceptionStatus.Timeout); - } - - // Case 1 or 2 - throw requestState.webException; - } - - return (requestState.response); - } - - internal virtual void UpdateSession(WebResponse response) - { - if (null == response) { throw new ArgumentNullException("response"); } - - // process HTTP specific session data - HttpWebResponse httpResponse = response as HttpWebResponse; - if ((null != WebSession) && (null != httpResponse)) - { - // save response cookies into the session - WebSession.Cookies.Add(httpResponse.Cookies); - } - } - - #endregion Virtual Methods - - #region Overrides - - /// - /// the main execution method for cmdlets derived from WebRequestPSCmdlet. - /// - protected override void ProcessRecord() - { - try - { - // Set cmdlet context for write progress - ValidateParameters(); - PrepareSession(); - WebRequest request = GetRequest(Uri); - FillRequestStream(request); - - // Some web sites (e.g. Twitter) will return exception on POST when Expect100 is sent - // Default behaviour is continue to send body content anyway after a short period - // Here it send the two part as a whole. - ServicePointManager.Expect100Continue = false; - - try - { - string reqVerboseMsg = String.Format(CultureInfo.CurrentCulture, - "{0} {1} with {2}-byte payload", - request.Method, - request.RequestUri, - request.ContentLength); - WriteVerbose(reqVerboseMsg); - WebResponse response = GetResponse(request); - try - { - string contentType = ContentHelper.GetContentType(response); - string respVerboseMsg = String.Format(CultureInfo.CurrentCulture, - "received {0}-byte response of content type {1}", - response.ContentLength, - contentType); - WriteVerbose(respVerboseMsg); - ProcessResponse(response); - UpdateSession(response); - - // If we hit our maximum redirection count, generate an error. - // Errors with redirection counts of greater than 0 are handled automatically by .NET, but are - // impossible to detect programmatically when we hit this limit. By handling this ourselves - // (and still writing out the result), users can debug actual HTTP redirect problems. - HttpWebRequest httpRequest = request as HttpWebRequest; - if ((httpRequest != null) && (httpRequest.AllowAutoRedirect == false)) - { - HttpWebResponse webResponse = response as HttpWebResponse; - if ((webResponse.StatusCode == HttpStatusCode.Found) || - (webResponse.StatusCode == HttpStatusCode.Moved) || - webResponse.StatusCode == HttpStatusCode.MovedPermanently) - { - ErrorRecord er = new ErrorRecord(new InvalidOperationException(), "MaximumRedirectExceeded", ErrorCategory.InvalidOperation, httpRequest); - er.ErrorDetails = new ErrorDetails(WebCmdletStrings.MaximumRedirectionCountExceeded); - WriteError(er); - } - } - } - finally - { - // Choosing to close the stream instead of Dispose as the - // response object is being written to the output pipe. - if (response != null) - { - response.Close(); - } - } - } - catch (WebException ex) - { - WebException exThrown = ex; - string detailMsg = String.Empty; - try - { - if (ex.Response != null && ex.Response.ContentLength > 0) - { - Stream input = StreamHelper.GetResponseStream(ex.Response); - StreamReader reader = new StreamReader(input); - detailMsg = reader.ReadToEnd(); - - // If we were asked to not use the IE engine (or this is Invoke-RestMethod), use a simple - // regex replace to remove tags. - if (UseBasicParsing || (this is InvokeRestMethodCommand)) - { - detailMsg = System.Text.RegularExpressions.Regex.Replace(detailMsg, "<[^>]*>", ""); - } - else - { - // Otherwise, use IE to clean it up, as errors often come back as HTML - VerifyInternetExplorerAvailable(false); - - try - { - IHTMLDocument2 _parsedHtml = (IHTMLDocument2)new HTMLDocument(); - _parsedHtml.write(detailMsg); - detailMsg = _parsedHtml.body.outerText; - } - catch (System.Runtime.InteropServices.COMException) { } - } - } - } - // catch all - catch (Exception) - { - } - ErrorRecord er = new ErrorRecord(exThrown, "WebCmdletWebResponseException", ErrorCategory.InvalidOperation, request); - if (!String.IsNullOrEmpty(detailMsg)) - { - er.ErrorDetails = new ErrorDetails(detailMsg); - } - ThrowTerminatingError(er); - } - } - catch (CryptographicException ex) - { - ErrorRecord er = new ErrorRecord(ex, "WebCmdletCertificateException", ErrorCategory.SecurityError, null); - ThrowTerminatingError(er); - } - catch (NotSupportedException ex) - { - ErrorRecord er = new ErrorRecord(ex, "WebCmdletIEDomNotSupportedException", ErrorCategory.NotImplemented, null); - ThrowTerminatingError(er); - } - } - - /// - /// Implementing ^C, after start the BeginGetResponse - /// - protected override void StopProcessing() - { - if (_webRequest != null) - { - _webRequest.Abort(); - } - } - - #endregion Overrides - - #region Helper Methods - - /// - /// Call back method for BeginGetResponse - /// - /// - private static void ResponseCallback(IAsyncResult asyncResult) - { - WebRequestState myRequestState = (WebRequestState)asyncResult.AsyncState; - - try - { - myRequestState.response = myRequestState.request.EndGetResponse(asyncResult); - } - catch (WebException ex) - { - myRequestState.response = null; - myRequestState.webException = ex; - } - finally - { - myRequestState.waithandle.Set(); - } - } - - /// - /// Call back method for timeout - /// - /// - /// - private static void TimeoutCallback(object state, bool timeout) - { - if (timeout) - { - TimeoutState timeoutState = state as TimeoutState; - if (timeoutState != null) - { - timeoutState.abort = true; - timeoutState.httpRequest.Abort(); - } - } - } - - /// - /// Sets the ContentLength property of the request and writes the specified content to the request's RequestStream. - /// - /// The WebRequest who's content is to be set - /// A byte array containing the content data. - /// The number of bytes written to the requests RequestStream (and the new value of the request's ContentLength property - /// - /// Because this function sets the request's ContentLength property and writes content data into the requests's stream, - /// it should be called one time maximum on a given request. - /// - internal long SetRequestContent(WebRequest request, Byte[] content) - { - if (request == null) - throw new ArgumentNullException("request"); - - if (content != null) - { - if (request.ContentLength == 0) - { - request.ContentLength = content.Length; - } - StreamHelper.WriteToStream(content, request.GetRequestStream()); - } - else - { - request.ContentLength = 0; - } - - return request.ContentLength; - } - - /// - /// Sets the ContentLength property of the request and writes the specified content to the request's RequestStream. - /// - /// The WebRequest who's content is to be set - /// A String object containing the content data. - /// The number of bytes written to the requests RequestStream (and the new value of the request's ContentLength property - /// - /// Because this function sets the request's ContentLength property and writes content data into the requests's stream, - /// it should be called one time maximum on a given request. - /// - internal long SetRequestContent(WebRequest request, String content) - { - if (request == null) - throw new ArgumentNullException("request"); - - if (content != null) - { - Encoding encoding = null; - if (null != ContentType) - { - // If Content-Type contains the encoding format (as CharSet), use this encoding format - // to encode the Body of the WebRequest sent to the server. Default Encoding format - // would be used if Charset is not supplied in the Content-Type property. - System.Net.Mime.ContentType mimeContentType = new System.Net.Mime.ContentType(ContentType); - if (!String.IsNullOrEmpty(mimeContentType.CharSet)) - { - try - { - encoding = Encoding.GetEncoding(mimeContentType.CharSet); - } - catch (ArgumentException ex) - { - ErrorRecord er = new ErrorRecord(ex, "WebCmdletEncodingException", ErrorCategory.InvalidArgument, ContentType); - ThrowTerminatingError(er); - } - } - } - - Byte[] bytes = StreamHelper.EncodeToBytes(content, encoding); - - if (request.ContentLength == 0) - { - request.ContentLength = bytes.Length; - } - StreamHelper.WriteToStream(bytes, request.GetRequestStream()); - } - else - { - request.ContentLength = 0; - } - - return request.ContentLength; - } - - internal long SetRequestContent(WebRequest request, XmlNode xmlNode) - { - if (request == null) - throw new ArgumentNullException("request"); - - if (xmlNode != null) - { - Byte[] bytes = null; - XmlDocument doc = xmlNode as XmlDocument; - if (doc != null && (doc.FirstChild as XmlDeclaration) != null) - { - XmlDeclaration decl = doc.FirstChild as XmlDeclaration; - Encoding encoding = Encoding.GetEncoding(decl.Encoding); - bytes = StreamHelper.EncodeToBytes(doc.OuterXml, encoding); - } - else - { - bytes = StreamHelper.EncodeToBytes(xmlNode.OuterXml); - } - - if (request.ContentLength == 0) - { - request.ContentLength = bytes.Length; - } - StreamHelper.WriteToStream(bytes, request.GetRequestStream()); - } - else - { - request.ContentLength = 0; - } - - return request.ContentLength; - } - - /// - /// Sets the ContentLength property of the request and writes the specified content to the request's RequestStream. - /// - /// The WebRequest who's content is to be set - /// A Stream object containing the content data. - /// The number of bytes written to the requests RequestStream (and the new value of the request's ContentLength property - /// - /// Because this function sets the request's ContentLength property and writes content data into the requests's stream, - /// it should be called one time maximum on a given request. - /// - internal long SetRequestContent(WebRequest request, Stream contentStream) - { - if (request == null) - throw new ArgumentNullException("request"); - if (contentStream == null) - throw new ArgumentNullException("contentStream"); - - if (request.ContentLength == 0) - { - request.ContentLength = contentStream.Length; - } - - StreamHelper.WriteToStream(contentStream, request.GetRequestStream(), this); - - return request.ContentLength; - } - - internal long SetRequestContent(WebRequest request, IDictionary content) - { - if (request == null) - throw new ArgumentNullException("request"); - if (content == null) - throw new ArgumentNullException("content"); - - string body = FormatDictionary(content); - return (SetRequestContent(request, body)); - } - - #endregion Helper Methods - - #region private State class - - /// - /// The web request state is used when place asynchronous call to get response of a web request. - /// - private class WebRequestState - { - public WebRequest request; - public WebResponse response; - public ManualResetEvent waithandle; - public WebException webException; - - public WebRequestState(WebRequest webRequest) - { - request = webRequest; - response = null; - webException = null; - waithandle = new ManualResetEvent(false); - } - } - - /// - /// The timeout state is used when the request is a http request and need to timeout - /// - private class TimeoutState - { - public HttpWebRequest httpRequest; - public bool abort; - - public TimeoutState(HttpWebRequest request) - { - httpRequest = request; - abort = false; - } - } - - #endregion private State class - } -} \ No newline at end of file diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/WebResponseHelper.FullClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/WebResponseHelper.FullClr.cs deleted file mode 100644 index 8e654276015..00000000000 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/WebResponseHelper.FullClr.cs +++ /dev/null @@ -1,72 +0,0 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - -using System; -using System.Net; -using System.Globalization; - -namespace Microsoft.PowerShell.Commands -{ - internal static partial class WebResponseHelper - { - internal static string GetCharacterSet(WebResponse response) - { - string characterSet = null; - - HttpWebResponse httpResponse = response as HttpWebResponse; - if (null != httpResponse) - { - characterSet = httpResponse.CharacterSet; - } - - return (characterSet); - } - - internal static string GetProtocol(WebResponse response) - { - string protocol = string.Empty; - - HttpWebResponse httpResponse = response as HttpWebResponse; - if (null != httpResponse) - { - protocol = string.Format(CultureInfo.InvariantCulture, - "HTTP/{0}", httpResponse.ProtocolVersion); - } - - return (protocol); - } - - internal static int GetStatusCode(WebResponse response) - { - int statusCode = 0; - - HttpWebResponse httpResponse = response as HttpWebResponse; - if (null != httpResponse) - { - statusCode = (int)httpResponse.StatusCode; - } - - return (statusCode); - } - - internal static string GetStatusDescription(WebResponse response) - { - string statusDescription = string.Empty; - - HttpWebResponse httpResponse = response as HttpWebResponse; - if (null != httpResponse) - { - statusDescription = httpResponse.StatusDescription; - } - - return (statusDescription); - } - - internal static bool IsText(WebResponse response) - { - string contentType = ContentHelper.GetContentType(response); - return (ContentHelper.IsText(contentType)); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/WebResponseObject.FullClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/WebResponseObject.FullClr.cs deleted file mode 100644 index ee9087c4623..00000000000 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/WebResponseObject.FullClr.cs +++ /dev/null @@ -1,116 +0,0 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - -using System; -using System.Text; -using System.Net; -using System.Collections.Generic; -using System.IO; - -namespace Microsoft.PowerShell.Commands -{ - /// - /// WebResponseObject - /// - public partial class WebResponseObject - { - #region Properties - - /// - /// gets or sets the BaseResponse property - /// - public WebResponse BaseResponse { get; set; } - - /// - /// gets the Headers property - /// - public Dictionary Headers - { - get - { - Dictionary headers = new Dictionary(StringComparer.OrdinalIgnoreCase); - foreach (string key in BaseResponse.Headers.Keys) - { - headers[key] = BaseResponse.Headers[key]; - } - - return headers; - } - } - - #endregion - - #region Constructors - - /// - /// Constructor for WebResponseObject - /// - /// - public WebResponseObject(WebResponse response) - : this(response, null) - { } - - /// - /// Constructor for WebResponseObject with contentStream - /// - /// - /// - public WebResponseObject(WebResponse response, Stream contentStream) - { - SetResponse(response, contentStream); - InitializeContent(); - InitializeRawContent(response); - } - - #endregion Constructors - - #region Methods - - private void InitializeRawContent(WebResponse baseResponse) - { - StringBuilder raw = ContentHelper.GetRawContentHeader(baseResponse); - - // Use ASCII encoding for the RawContent visual view of the content. - if (Content.Length > 0) - { - raw.Append(this.ToString()); - } - - this.RawContent = raw.ToString(); - } - - private void SetResponse(WebResponse response, Stream contentStream) - { - if (null == response) { throw new ArgumentNullException("response"); } - - BaseResponse = response; - - MemoryStream ms = contentStream as MemoryStream; - if (null != ms) - { - _rawContentStream = ms; - } - else - { - Stream st = contentStream; - if (contentStream == null) - { - st = StreamHelper.GetResponseStream(response); - } - - long contentLength = response.ContentLength; - if (0 >= contentLength) - { - contentLength = StreamHelper.DefaultReadBuffer; - } - int initialCapacity = (int)Math.Min(contentLength, StreamHelper.DefaultReadBuffer); - _rawContentStream = new WebResponseContentMemoryStream(st, initialCapacity, null); - } - // set the position of the content stream to the beginning - _rawContentStream.Position = 0; - } - - #endregion - } -} diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/WebResponseObjectFactory.FullClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/WebResponseObjectFactory.FullClr.cs deleted file mode 100644 index 1d42838eedb..00000000000 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/FullClr/WebResponseObjectFactory.FullClr.cs +++ /dev/null @@ -1,35 +0,0 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - -using System; -using System.Net; -using System.IO; -using System.Management.Automation; - -namespace Microsoft.PowerShell.Commands -{ - internal static class WebResponseObjectFactory - { - internal static WebResponseObject GetResponseObject(WebResponse response, Stream responseStream, ExecutionContext executionContext, bool useBasicParsing = false) - { - WebResponseObject output; - if (WebResponseHelper.IsText(response)) - { - if (!useBasicParsing) - { - output = new HtmlWebResponseObject(response, responseStream, executionContext); - } - else - { - output = new BasicHtmlWebResponseObject(response, responseStream); - } - } - else - { - output = new WebResponseObject(response, responseStream); - } - return (output); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs index 215fec32829..1096ff1c7ea 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; @@ -10,8 +9,10 @@ using System.Text.RegularExpressions; using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using System.Collections; using System.Collections.ObjectModel; using System.IO; +using System.Linq; using System.Management.Automation.Internal; using System.Reflection; @@ -26,13 +27,26 @@ public static class JsonObject private const int maxDepthAllowed = 100; /// - /// Convert a Json string back to an object + /// Convert a Json string back to an object of type PSObject. /// /// /// - /// + /// A PSObject. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] public static object ConvertFromJson(string input, out ErrorRecord error) + { + return ConvertFromJson(input, false, out error); + } + + /// + /// Convert a Json string back to an object of type PSObject or Hashtable depending on parameter . + /// + /// + /// + /// + /// A PSObject or a Hashtable if the parameter is true. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] + public static object ConvertFromJson(string input, bool returnHashTable, out ErrorRecord error) { if (input == null) { @@ -65,7 +79,14 @@ public static object ConvertFromJson(string input, out ErrorRecord error) var dictionary = obj as JObject; if (dictionary != null) { - obj = PopulateFromJDictionary(dictionary, out error); + if (returnHashTable) + { + obj = PopulateHashTableFromJDictionary(dictionary, out error); + } + else + { + obj = PopulateFromJDictionary(dictionary, out error); + } } else { @@ -73,7 +94,14 @@ public static object ConvertFromJson(string input, out ErrorRecord error) var list = obj as JArray; if (list != null) { - obj = PopulateFromJArray(list, out error); + if (returnHashTable) + { + obj = PopulateHashTableFromJArray(list, out error); + } + else + { + obj = PopulateFromJArray(list, out error); + } } } } @@ -93,14 +121,42 @@ private static PSObject PopulateFromJDictionary(JObject entries, out ErrorRecord PSObject result = new PSObject(); foreach (var entry in entries) { + if (string.IsNullOrEmpty(entry.Key)) + { + string errorMsg = string.Format(CultureInfo.InvariantCulture, + WebCmdletStrings.EmptyKeyInJsonString); + error = new ErrorRecord( + new InvalidOperationException(errorMsg), + "EmptyKeyInJsonString", + ErrorCategory.InvalidOperation, + null); + return null; + } + + // Case sensitive duplicates should normally not occur since JsonConvert.DeserializeObject + // does not throw when encountering duplicates and just uses the last entry. + if (result.Properties.Any(psPropertyInfo => psPropertyInfo.Name.Equals(entry.Key, StringComparison.InvariantCulture))) + { + string errorMsg = string.Format(CultureInfo.InvariantCulture, + WebCmdletStrings.DuplicateKeysInJsonString, entry.Key); + error = new ErrorRecord( + new InvalidOperationException(errorMsg), + "DuplicateKeysInJsonString", + ErrorCategory.InvalidOperation, + null); + return null; + } + + // Compare case insensitive to tell the user to use the -AsHashTable option instead. + // This is because PSObject cannot have keys with different casing. PSPropertyInfo property = result.Properties[entry.Key]; if (property != null) { string errorMsg = string.Format(CultureInfo.InvariantCulture, - WebCmdletStrings.DuplicateKeysInJsonString, property.Name, entry.Key); + WebCmdletStrings.KeysWithDifferentCasingInJsonString, property.Name, entry.Key); error = new ErrorRecord( new InvalidOperationException(errorMsg), - "DuplicateKeysInJsonString", + "KeysWithDifferentCasingInJsonString", ErrorCategory.InvalidOperation, null); return null; @@ -180,5 +236,101 @@ private static ICollection PopulateFromJArray(JArray list, out ErrorReco } return result.ToArray(); } + + // This function is a clone of PopulateFromDictionary using JObject as an input. + private static Hashtable PopulateHashTableFromJDictionary(JObject entries, out ErrorRecord error) + { + error = null; + Hashtable result = new Hashtable(); + foreach (var entry in entries) + { + // Case sensitive duplicates should normally not occur since JsonConvert.DeserializeObject + // does not throw when encountering duplicates and just uses the last entry. + if (result.ContainsKey(entry.Key)) + { + string errorMsg = string.Format(CultureInfo.InvariantCulture, + WebCmdletStrings.DuplicateKeysInJsonString, entry.Key); + error = new ErrorRecord( + new InvalidOperationException(errorMsg), + "DuplicateKeysInJsonString", + ErrorCategory.InvalidOperation, + null); + return null; + } + + // Array + else if (entry.Value is JArray) + { + JArray list = entry.Value as JArray; + ICollection listResult = PopulateHashTableFromJArray(list, out error); + if (error != null) + { + return null; + } + result.Add(entry.Key, listResult); + } + + // Dictionary + else if (entry.Value is JObject) + { + JObject dic = entry.Value as JObject; + Hashtable dicResult = PopulateHashTableFromJDictionary(dic, out error); + if (error != null) + { + return null; + } + result.Add(entry.Key, dicResult); + } + + // Value + else // (entry.Value is JValue) + { + JValue theValue = entry.Value as JValue; + result.Add(entry.Key, theValue.Value); + } + } + return result; + } + + // This function is a clone of PopulateFromList using JArray as input. + private static ICollection PopulateHashTableFromJArray(JArray list, out ErrorRecord error) + { + error = null; + List result = new List(); + + foreach (var element in list) + { + // Array + if (element is JArray) + { + JArray subList = element as JArray; + ICollection listResult = PopulateHashTableFromJArray(subList, out error); + if (error != null) + { + return null; + } + result.Add(listResult); + } + + // Dictionary + else if (element is JObject) + { + JObject dic = element as JObject; + Hashtable dicResult = PopulateHashTableFromJDictionary(dic, out error); + if (error != null) + { + return null; + } + result.Add(dicResult); + } + + // Value + else // (element is JValue) + { + result.Add(((JValue)element).Value); + } + } + return result.ToArray(); + } } } diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/PSUserAgent.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/PSUserAgent.cs index 4408beae622..0c1f9e63cab 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/PSUserAgent.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/PSUserAgent.cs @@ -1,11 +1,11 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; using System.Runtime.InteropServices; using System.Globalization; +using System.Text.RegularExpressions; namespace Microsoft.PowerShell.Commands { @@ -131,7 +131,8 @@ internal static string PlatformName // only generate the windows user agent once if(s_windowsUserAgent == null){ // find the version in the windows operating system description - string versionText = OS.Substring(OS.LastIndexOf(" ") +1); + Regex pattern = new Regex(@"\d+(\.\d+)+"); + string versionText = pattern.Match(OS).Value; Version windowsPlatformversion = new Version(versionText); s_windowsUserAgent = $"Windows NT {windowsPlatformversion.Major}.{windowsPlatformversion.Minor}"; } diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/StreamHelper.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/StreamHelper.cs index f4486c8771c..5c60c4058a1 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/StreamHelper.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/StreamHelper.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Text; @@ -9,12 +8,7 @@ using System.IO.Compression; using System.Management.Automation; using System.Management.Automation.Internal; - -#if CORECLR using System.Net.Http; -#else -using System.Net; -#endif namespace Microsoft.PowerShell.Commands { @@ -229,43 +223,6 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } -#if !CORECLR - /// - /// - /// - public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) - { - Initialize(); - return base.BeginRead(buffer, offset, count, callback, state); - } - - /// - /// - /// - public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) - { - Initialize(); - return base.BeginWrite(buffer, offset, count, callback, state); - } - - /// - /// - /// - public override byte[] GetBuffer() - { - Initialize(); - return base.GetBuffer(); - } - - /// - /// - /// - public override void Close() - { - base.Close(); - } -#endif - /// /// /// @@ -358,7 +315,6 @@ internal static void WriteToStream(Stream input, Stream output, PSCmdlet cmdlet) } } while (read != 0); - if (cmdlet != null) { ProgressRecord record = new ProgressRecord(ActivityId, @@ -386,9 +342,20 @@ internal static void WriteToStream(byte[] input, Stream output) /// internal static void SaveStreamToFile(Stream stream, string filePath, PSCmdlet cmdlet) { - using (FileStream output = File.Create(filePath)) + // If the web cmdlet should resume, append the file instead of overwriting. + if(cmdlet is WebRequestPSCmdlet webCmdlet && webCmdlet.ShouldResume) + { + using (FileStream output = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.Read)) + { + WriteToStream(stream, output, cmdlet); + } + } + else { - WriteToStream(stream, output, cmdlet); + using (FileStream output = File.Create(filePath)) + { + WriteToStream(stream, output, cmdlet); + } } } @@ -516,7 +483,6 @@ internal static Byte[] EncodeToBytes(String str) return EncodeToBytes(str, null); } -#if CORECLR internal static Stream GetResponseStream(HttpResponseMessage response) { Stream responseStream = response.Content.ReadAsStreamAsync().GetAwaiter().GetResult(); @@ -538,28 +504,6 @@ internal static Stream GetResponseStream(HttpResponseMessage response) return responseStream; } -#else - internal static Stream GetResponseStream(WebResponse response) - { - Stream responseStream = response.GetResponseStream(); - - // See if it had a content-encoding, wrap in a decoding stream if so. - string contentEncoding = response.Headers["Content-Encoding"]; - if (contentEncoding != null) - { - if (contentEncoding.IndexOf("gzip", StringComparison.OrdinalIgnoreCase) >= 0) - { - responseStream = new GZipStream(responseStream, CompressionMode.Decompress); - } - else if (contentEncoding.IndexOf("deflate", StringComparison.OrdinalIgnoreCase) >= 0) - { - responseStream = new DeflateStream(responseStream, CompressionMode.Decompress); - } - } - - return responseStream; - } -#endif #endregion Static Methods } diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/WebCmdletElementCollection.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/WebCmdletElementCollection.cs index 146a0707f05..4325e29054e 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/WebCmdletElementCollection.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/WebCmdletElementCollection.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Collections.ObjectModel; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/WebRequestMethod.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/WebRequestMethod.cs index 8dfe117b17d..40ae4d45a68 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/WebRequestMethod.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/WebRequestMethod.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. namespace Microsoft.PowerShell.Commands { diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/WebRequestSession.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/WebRequestSession.cs index 1f7a318ce48..43809cd39c7 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/WebRequestSession.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/WebRequestSession.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Net; @@ -20,12 +19,10 @@ public class WebRequestSession [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public Dictionary Headers { get; set; } -#if CORECLR /// /// gets or sets the content Headers when using HttpClient /// internal Dictionary ContentHeaders { get; set; } -#endif /// /// gets or sets the Cookies property @@ -74,9 +71,7 @@ public WebRequestSession() { // build the headers collection Headers = new Dictionary(StringComparer.OrdinalIgnoreCase); -#if CORECLR ContentHeaders = new Dictionary(StringComparer.OrdinalIgnoreCase); -#endif // build the cookie jar Cookies = new CookieContainer(); diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Write-Object.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Write-Object.cs index 3400fdd9cd9..a525ee6e3bc 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Write-Object.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Write-Object.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WriteAliasCommandBase.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WriteAliasCommandBase.cs index 7320cda732c..478e0cbf3a5 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WriteAliasCommandBase.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WriteAliasCommandBase.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; @@ -74,7 +73,6 @@ public SwitchParameter PassThru [Parameter] public string Scope { get; set; } - /// /// If set to true and an existing alias of the same name exists /// and is ReadOnly, the alias will be overwritten. diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WriteConsoleCmdlet.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WriteConsoleCmdlet.cs index d83ef795fbd..5aed01c5d3e 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WriteConsoleCmdlet.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WriteConsoleCmdlet.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; @@ -22,8 +21,6 @@ public sealed class WriteHostCommand : ConsoleColorCmdlet // Parameters // - - /// /// /// Object to be output. @@ -31,9 +28,9 @@ public sealed class WriteHostCommand : ConsoleColorCmdlet /// [Parameter(Position = 0, ValueFromRemainingArguments = true, ValueFromPipeline = true)] + [Alias("Msg", "Message")] public object Object { get; set; } = null; - /// /// /// False to add a newline to the end of the output string, true if not. @@ -53,8 +50,6 @@ public SwitchParameter NoNewline } } - - /// /// /// The separator to print between objects @@ -65,7 +60,6 @@ public SwitchParameter NoNewline [Parameter] public object Separator { get; set; } = " "; - // // Cmdlet Overrides // @@ -118,8 +112,6 @@ private string ProcessObject(object o) return null; } - - /// /// /// Outputs the object to the host console, with optional newline @@ -150,4 +142,4 @@ protected override void ProcessRecord() private Boolean _notAppendNewline = false; } -} // namespace Microsoft.PowerShell.Commands \ No newline at end of file +} // namespace Microsoft.PowerShell.Commands diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WriteProgressCmdlet.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WriteProgressCmdlet.cs index 8901b36e10f..7bbd3bd3370 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WriteProgressCmdlet.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WriteProgressCmdlet.cs @@ -1,15 +1,11 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; using Dbg = System.Management.Automation.Diagnostics; - - namespace Microsoft.PowerShell.Commands { /// @@ -35,7 +31,6 @@ public sealed class WriteProgressCommand : PSCmdlet HelpMessageResourceId = "ActivityParameterHelpMessage")] public string Activity { get; set; } - /// /// /// Describes the current state of the activity. @@ -50,7 +45,6 @@ public sealed class WriteProgressCommand : PSCmdlet [ValidateNotNullOrEmpty] public string Status { get; set; } = WriteProgressResourceStrings.Processing; - /// /// /// Uniquely identifies this activity for purposes of chaining subordinate activities. @@ -62,7 +56,6 @@ public sealed class WriteProgressCommand : PSCmdlet [ValidateRange(0, Int32.MaxValue)] public int Id { get; set; } = 0; - /// /// /// Percentage completion of the activity, or -1 if n/a @@ -74,7 +67,6 @@ public sealed class WriteProgressCommand : PSCmdlet [ValidateRange(-1, 100)] public int PercentComplete { get; set; } = -1; - /// /// /// Seconds remaining to complete the operation, or -1 if n/a @@ -85,7 +77,6 @@ public sealed class WriteProgressCommand : PSCmdlet [Parameter] public int SecondsRemaining { get; set; } = -1; - /// /// /// Description of current operation in activity, empty if n/a @@ -96,7 +87,6 @@ public sealed class WriteProgressCommand : PSCmdlet [Parameter] public string CurrentOperation { get; set; } - /// /// /// Identifies the parent Id of this activity, or -1 if none. @@ -108,7 +98,6 @@ public sealed class WriteProgressCommand : PSCmdlet [ValidateRange(-1, Int32.MaxValue)] public int ParentId { get; set; } = -1; - /// /// /// Identifies whether the activity has completed (and the display for it should be removed), @@ -130,8 +119,6 @@ public SwitchParameter Completed } } - - /// /// /// Identifies the source of the record. @@ -142,7 +129,6 @@ public SwitchParameter Completed [Parameter] public int SourceId { get; set; } - /// /// /// Writes a ProgressRecord created from the parameters. @@ -163,10 +149,8 @@ protected override WriteProgress(SourceId, pr); } - private bool _completed; - private const string HelpMessageBaseName = "WriteProgressResourceStrings"; } } diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/XmlCommands.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/XmlCommands.cs index 50edf754d29..ae9140f3cb6 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/XmlCommands.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/XmlCommands.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections; @@ -108,8 +107,20 @@ public SwitchParameter NoClobber /// /// [Parameter] - [ValidateSetAttribute(new string[] { "Unicode", "UTF7", "UTF8", "ASCII", "UTF32", "BigEndianUnicode", "Default", "OEM" })] - public string Encoding { get; set; } = "Unicode"; + [ArgumentToEncodingTransformationAttribute()] + [ArgumentCompletions( + EncodingConversion.Ascii, + EncodingConversion.BigEndianUnicode, + EncodingConversion.OEM, + EncodingConversion.Unicode, + EncodingConversion.Utf7, + EncodingConversion.Utf8, + EncodingConversion.Utf8Bom, + EncodingConversion.Utf8NoBom, + EncodingConversion.Utf32 + )] + [ValidateNotNullOrEmpty] + public Encoding Encoding { get; set; } = ClrFacade.GetDefaultEncoding(); #endregion Command Line Parameters @@ -125,7 +136,6 @@ protected override CreateFileStream(); } - /// /// /// @@ -302,7 +312,6 @@ public String[] LiteralPath } private bool _isLiteralPath = false; - #endregion Command Line Parameters #region IDisposable Members @@ -355,7 +364,6 @@ protected override void StopProcessing() } } - /// /// implementation for the convertto-xml command /// @@ -366,7 +374,6 @@ public sealed class ConvertToXmlCommand : PSCmdlet, IDisposable { #region Command Line Parameters - /// /// Depth of serialization /// @@ -374,7 +381,6 @@ public sealed class ConvertToXmlCommand : PSCmdlet, IDisposable [ValidateRange(1, int.MaxValue)] public int Depth { get; set; } = 0; - /// /// Input Object which is written to XML format /// @@ -382,7 +388,6 @@ public sealed class ConvertToXmlCommand : PSCmdlet, IDisposable [AllowNull] public PSObject InputObject { get; set; } - /// /// Property that sets NoTypeInformation parameter. /// @@ -410,7 +415,6 @@ public SwitchParameter NoTypeInformation #endregion Command Line Parameters - #region Overrides /// @@ -429,7 +433,6 @@ protected override void BeginProcessing() } } - /// /// override ProcessRecord /// @@ -442,7 +445,6 @@ protected override void ProcessRecord() if (null != _serializer) _serializer.SerializeAsStream(InputObject); - if (null != _serializer) { _serializer.DoneAsStream(); @@ -618,7 +620,6 @@ private void CleanUp() #endregion IDisposable Members } - /// /// Helper class to import single XML file /// @@ -730,7 +731,6 @@ internal void Import() _cmdlet.WriteObject(totalCount); } - ulong skip = _cmdlet.PagingParameters.Skip; ulong first = _cmdlet.PagingParameters.First; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/compare-object.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/compare-object.cs index 6b6fc0f3a32..68b5cd89abf 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/compare-object.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/compare-object.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/convert-HTML.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/convert-HTML.cs index 03219da4bcf..3cbcf8e7f93 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/convert-HTML.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/convert-HTML.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections; @@ -398,7 +397,6 @@ private static string SafeToString(object obj) return ""; } - /// /// /// @@ -419,7 +417,6 @@ protected override void BeginProcessing() WebUtility.HtmlEncode(_title); } - // This first line ensures w3c validation will succeed. However we are not specifying // an encoding in the HTML because we don't know where the text will be written and // if a particular encoding will be used. diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/group-object.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/group-object.cs index 1dd466add3b..f967cd3a071 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/group-object.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/group-object.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections; @@ -109,8 +108,6 @@ internal virtual void Add(PSObject groupValue) Count++; } - - private static string BuildName(List propValues) { StringBuilder sb = new StringBuilder(); @@ -141,7 +138,6 @@ private static string BuildName(List propValues) return sb.Length >= 2 ? sb.Remove(sb.Length - 2, 2).ToString() : string.Empty; } - /// /// /// Values of the group diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/new-object.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/new-object.cs index c92d77af85d..82f78f06848 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/new-object.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/new-object.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives @@ -101,7 +100,6 @@ private void CreateMemberSetValueError(SetValueException e) new ErrorRecord(ex, "SetValueException", ErrorCategory.InvalidData, null)); } - private static string ParameterSet2ResourceString(string parameterSet) { if (parameterSet.Equals(netSetName, StringComparison.OrdinalIgnoreCase)) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/neweventcommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/neweventcommand.cs index 4584ffb9977..14812d759f0 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/neweventcommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/neweventcommand.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Diagnostics.CodeAnalysis; @@ -92,7 +91,6 @@ public PSObject MessageData #endregion parameters - /// /// Add the event to the event queue /// diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/select-object.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/select-object.cs index dcc86a8e887..c11fd593cfa 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/select-object.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/select-object.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; @@ -79,7 +78,6 @@ public sealed class SelectObjectCommand : PSCmdlet [Parameter(ValueFromPipeline = true)] public PSObject InputObject { set; get; } = AutomationNull.Value; - /// /// /// @@ -147,7 +145,6 @@ public int First private int _first = 0; private bool _firstOrLastSpecified; - /// /// Skips the specified number of items from top when used with First,from end when used with Last /// @@ -293,8 +290,6 @@ public PSObject StreamingDequeue() /// private List _expandMshParameterList; - - private MshExpressionFilter _exclusionFilter; private class UniquePSObjectHelper @@ -351,7 +346,6 @@ private void ProcessObject(PSObject inputObject) return; } - //If property parameter is mentioned List matchedProperties = new List(); foreach (MshParameter p in _propertyMshParameterList) @@ -396,8 +390,6 @@ private void ProcessObject(PSObject inputObject) } } - - private void ProcessParameter(MshParameter p, PSObject inputObject, List result) { string name = p.GetEntry(NameEntryDefinition.NameEntryKey) as string; @@ -473,7 +465,6 @@ private void ProcessExpandParameter(MshParameter p, PSObject inputObject, MshExpression ex = p.GetEntry(FormatParameterDefinitionKeys.ExpressionEntryKey) as MshExpression; List expressionResults = ex.GetValues(inputObject); - if (expressionResults.Count == 0) { ErrorRecord errorRecord = new ErrorRecord( diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/sort-object.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/sort-object.cs index 1ccbbe0483b..e322af31fe5 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/sort-object.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/sort-object.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Collections.Generic; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/tee-object.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/tee-object.cs index 3892848769f..34ad1bd5bfd 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/tee-object.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/tee-object.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; @@ -29,6 +28,7 @@ public PSObject InputObject /// FilePath parameter /// [Parameter(Mandatory = true, Position = 0, ParameterSetName = "File")] + [Alias("Path")] public string FilePath { get { return _fileName; } diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/GetTracerCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/GetTracerCommand.cs index 12465f07988..26bcdaaa7f5 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/GetTracerCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/GetTracerCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Linq; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/MshHostTraceListener.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/MshHostTraceListener.cs index f366c518b63..0d8b2dd7845 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/MshHostTraceListener.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/MshHostTraceListener.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Text; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/SetTracerCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/SetTracerCommand.cs index 405857aa651..bc06b1a6663 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/SetTracerCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/SetTracerCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Collections.ObjectModel; using System.Diagnostics; @@ -43,7 +42,6 @@ public PSTraceSourceOptions Option } } // Flags - /// /// The parameter which determines the options for output from the /// trace listeners. @@ -64,7 +62,7 @@ public TraceOptions ListenerOption /// /// [Parameter(ParameterSetName = "optionsSet")] - [Alias("PSPath")] + [Alias("PSPath","Path")] public string FilePath { get { return base.FileListener; } diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceCommandBase.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceCommandBase.cs index 621c44be5a2..55faf98812e 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceCommandBase.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceCommandBase.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceExpressionCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceExpressionCommand.cs index 15ca35a3b4b..93208063e7d 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceExpressionCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceExpressionCommand.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.ObjectModel; @@ -97,7 +96,7 @@ public TraceOptions ListenerOption /// /// [Parameter] - [Alias("PSPath")] + [Alias("PSPath","Path")] public string FilePath { get { return base.FileListener; } @@ -138,7 +137,6 @@ public SwitchParameter PSHost set { base.PSHostListener = value; } } // PSHost - #endregion Parameters #region Cmdlet code @@ -153,7 +151,6 @@ protected override void BeginProcessing() Collection preconfiguredSources = null; _matchingSources = ConfigureTraceSource(base.NameInternal, false, out preconfiguredSources); - TurnOnTracing(_matchingSources, false); TurnOnTracing(preconfiguredSources, true); @@ -215,14 +212,12 @@ protected override void ProcessRecord() return; } - if (!LanguagePrimitives.IsNull(result)) { WriteObject(result, true); } } // ProcessRecord - /// /// Finishes running the command if specified and then sets the /// tracing options and listeners back to their original values. diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceListenerCommandBase.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceListenerCommandBase.cs index 7c3435d502f..ab3955a0d95 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceListenerCommandBase.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceListenerCommandBase.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; @@ -29,7 +28,6 @@ public class TraceListenerCommandBase : TraceCommandBase /// internal string[] NameInternal { get; set; } = new string[0]; - /// /// The flags to be set on the TraceSource /// @@ -441,7 +439,6 @@ internal static void RemoveListenersByName( } } // RemoveAllTraceListenersFromSource - #endregion RemoveTraceListeners #region SetTraceListenerOptions diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/update-list.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/update-list.cs index 55e4c855232..22f0e65e0ad 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/update-list.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/update-list.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections; @@ -113,7 +112,6 @@ protected override void ProcessRecord() } } - /// /// EndProcessing method. /// diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/write.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/write.cs index 99d4c8b2403..4717ff4db7e 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/write.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/write.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; @@ -26,7 +25,6 @@ public sealed class WriteDebugCommand : PSCmdlet [Alias("Msg")] public string Message { get; set; } = null; - /// /// This method implements the ProcessRecord method for Write-Debug command /// @@ -76,7 +74,6 @@ public sealed class WriteVerboseCommand : PSCmdlet [Alias("Msg")] public string Message { get; set; } = null; - /// /// This method implements the ProcessRecord method for Write-verbose command /// @@ -126,7 +123,6 @@ public sealed class WriteWarningCommand : PSCmdlet [Alias("Msg")] public string Message { get; set; } = null; - /// /// This method implements the ProcessRecord method for Write-Warning command /// @@ -172,7 +168,7 @@ public sealed class WriteInformationCommand : PSCmdlet /// Object to be sent to the Information stream. /// [Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true)] - [Alias("Msg")] + [Alias("Msg", "Message")] public Object MessageData { get; set; } /// @@ -214,7 +210,6 @@ protected override void ProcessRecord() #endregion WriteInformationCommand - #region WriteOrThrowErrorCommand /// @@ -311,7 +306,6 @@ public class WriteOrThrowErrorCommand : PSCmdlet [Alias("TargetType")] public string CategoryTargetType { get; set; } = ""; - /// /// Write an error to the output pipe, or throw a terminating error. /// @@ -493,5 +487,3 @@ protected WriteErrorException(SerializationInfo info, #endregion WriteErrorException } //namespace - - diff --git a/src/Microsoft.PowerShell.Commands.Utility/resources/CsvCommandStrings.resx b/src/Microsoft.PowerShell.Commands.Utility/resources/CsvCommandStrings.resx index 6616139c9b8..8d0ae2da593 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/resources/CsvCommandStrings.resx +++ b/src/Microsoft.PowerShell.Commands.Utility/resources/CsvCommandStrings.resx @@ -127,6 +127,9 @@ Reviewed by TArcher on 2010-06-29. + + You must specify either the -IncludeTypeInformation or -NoTypeInformation parameters, but not both. + You must specify either the -Path or -LiteralPath parameters, but not both. diff --git a/src/Microsoft.PowerShell.Commands.Utility/resources/TestJsonCmdletStrings.resx b/src/Microsoft.PowerShell.Commands.Utility/resources/TestJsonCmdletStrings.resx new file mode 100644 index 00000000000..a5c8d5d24d9 --- /dev/null +++ b/src/Microsoft.PowerShell.Commands.Utility/resources/TestJsonCmdletStrings.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Cannot parse the JSON schema. + + + Cannot parse the JSON. + + + The JSON is not valid with the schema. + + diff --git a/src/Microsoft.PowerShell.Commands.Utility/resources/UtilityCommonStrings.resx b/src/Microsoft.PowerShell.Commands.Utility/resources/UtilityCommonStrings.resx index f8e5623d8fc..ce98a182605 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/resources/UtilityCommonStrings.resx +++ b/src/Microsoft.PowerShell.Commands.Utility/resources/UtilityCommonStrings.resx @@ -174,4 +174,10 @@ '{0}' is not supported in this system. + + The file is not blocked: {0} + + + Processing object of type [{0}] at depth {1} + diff --git a/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx b/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx index 17fccac5f44..f22655aaf56 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx +++ b/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx @@ -120,17 +120,47 @@ Access to the path '{0}' is denied. + + The cmdlet cannot protect plain text secrets sent over unencrypted connections. To suppress this warning and send plain text secrets over unencrypted networks, reissue the command specifying the AllowUnencryptedAuthentication parameter. + + + The cmdlet cannot run because the following conflicting parameters are specified: Authentication and UseDefaultCredentials. Authentication does not support Default Credentials. Specify either Authentication or UseDefaultCredentials, then retry. + + + The cmdlet cannot run because the following parameter is not specified: Credential. The supplied Authentication type requires a Credential. Specify Credential, then retry. + + + The cmdlet cannot run because the following parameter is not specified: Token. The supplied Authentication type requires a Token. Specify Token, then retry. + + + The cmdlet cannot run because the following conflicting parameters are specified: Credential and Token. Specify either Credential or Token, then retry. + The cmdlet cannot run because the following conflicting parameters are specified: Body and InFile. Specify either Body or Infile, then retry. + + The cmdlet cannot run because the following conflicting parameters are specified: Body and Form. Specify either Body or Form, then retry. + + + The cmdlet cannot run because the following conflicting parameters are specified: InFile and Form. Specify either InFile or Form, then retry. + + + The cmdlet cannot run because the -ContentType parameter is not a valid Content-Type header. Specify a valid Content-Type for -ContentType, then retry. To suppress header validation, supply the -SkipHeaderValidation parameter. + The cmdlet cannot run because the following conflicting parameters are specified: Credential and UseDefaultCredentials. Specify either Credential or UseDefaultCredentials, then retry. - + Path '{0}' resolves to a directory. Specify a path including a file name, and then retry the command. + + The provided JSON includes a property whose name is an empty string, this is only supported using the -AsHashTable switch. + - Cannot convert the JSON string because a dictionary that was converted from the string contains the duplicated keys '{0}' and '{1}'. + Cannot convert the JSON string because a dictionary that was converted from the string contains the duplicated key '{0}'. + + + Cannot convert the JSON string because it contains keys with different casing. Please use the -AsHashTable switch instead. The key that was attempted to be added to the existing key '{0}' was '{1}'. The ConvertTo-Json and ConvertFrom-Json cmdlets require the installation of the .NET Client Profile, sometimes called the .NET extended profile. @@ -157,7 +187,10 @@ Path '{0}' is not a file system path. Please specify the path to a file in the file system. - The cmdlet cannot run because the following parameter is missing: OutFile. Provide a valid OutFile parameter value when using the PassThru parameter, then retry. + The cmdlet cannot run because the following parameter is missing: OutFile. Provide a valid OutFile parameter value when using the {0} parameter, then retry. + + + The file will not be re-downloaded because the remote file is the same size as the OutFile: {0} The cmdlet cannot run because the following conflicting parameters are specified: ProxyCredential and ProxyUseDefaultCredentials. Specify either ProxyCredential or ProxyUseDefaultCredentials, then retry. @@ -219,6 +252,9 @@ {0} {1} with {2}-byte payload + + The remote server indicated it could not resume downloading. The local file will be overwritten. + received {0}-byte response of content type {1} diff --git a/src/Microsoft.PowerShell.Commands.Utility/singleshell/installer/MshUtilityMshSnapin.cs b/src/Microsoft.PowerShell.Commands.Utility/singleshell/installer/MshUtilityMshSnapin.cs index af3788219dd..7248db150a2 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/singleshell/installer/MshUtilityMshSnapin.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/singleshell/installer/MshUtilityMshSnapin.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.ComponentModel; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.ConsoleHost/AssemblyInfo.cs b/src/Microsoft.PowerShell.ConsoleHost/AssemblyInfo.cs index 5ccccbcb8e1..617b095eeec 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/AssemblyInfo.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/AssemblyInfo.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System.Reflection; using System.Runtime.CompilerServices; #if !CORECLR diff --git a/src/Microsoft.PowerShell.ConsoleHost/Microsoft.PowerShell.ConsoleHost.csproj b/src/Microsoft.PowerShell.ConsoleHost/Microsoft.PowerShell.ConsoleHost.csproj index a7ec8d9ba3b..cef829db680 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/Microsoft.PowerShell.ConsoleHost.csproj +++ b/src/Microsoft.PowerShell.ConsoleHost/Microsoft.PowerShell.ConsoleHost.csproj @@ -8,7 +8,8 @@ - + + diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/CommandLineParameterParser.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/CommandLineParameterParser.cs index ff02a8dbb29..db86a208fdd 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/CommandLineParameterParser.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/CommandLineParameterParser.cs @@ -1,7 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Text; @@ -10,6 +8,7 @@ using System.IO; using System.Collections.ObjectModel; using System.Management.Automation; +using System.Management.Automation.Configuration; using System.Management.Automation.Runspaces; using System.Management.Automation.Internal; using System.Diagnostics; @@ -170,11 +169,10 @@ public override void WriteWarningLine(string message) internal class CommandLineParameterParser { internal static string[] validParameters = { - "psconsoleFile", "version", "nologo", "noexit", -#if !CORECLR +#if STAMODE "sta", "mta", #endif @@ -182,15 +180,15 @@ internal class CommandLineParameterParser "noninteractive", "inputformat", "outputformat", -#if !UNIX "windowstyle", -#endif "encodedcommand", "configurationname", "file", "executionpolicy", "command", - "help" + "settingsfile", + "help", + "workingdirectory" }; internal CommandLineParameterParser(PSHostUserInterface hostUI, string bannerText, string helpText) @@ -251,14 +249,6 @@ internal bool NoExit } } - internal bool ImportSystemModules - { - get - { - return _importSystemModules; - } - } - internal bool SkipProfiles { get @@ -398,11 +388,20 @@ internal bool NonInteractive get { return _noInteractive; } } + internal string WorkingDirectory + { + get { return _workingDirectory; } + } + private void ShowHelp() { Dbg.Assert(_helpText != null, "_helpText should not be null"); _hostUI.WriteLine(""); _hostUI.Write(_helpText); + if (_showExtendedHelp) + { + _hostUI.Write(ManagedEntranceStrings.ExtendedHelp); + } _hostUI.WriteLine(""); } @@ -416,6 +415,7 @@ private void DisplayBanner() } } +#if STAMODE internal bool StaMode { get @@ -426,17 +426,14 @@ internal bool StaMode } else { -#if CORECLR // Nano doesn't support STA COM apartment, so on Nano powershell has to use MTA as the default. - return false; -#else + // return false; // Win8: 182409 PowerShell 3.0 should run in STA mode by default return true; -#endif } } } - +#endif /// /// @@ -470,29 +467,17 @@ internal void Parse(string[] args) } } - private static string s_groupPolicyBase = @"Software\Policies\Microsoft\Windows\PowerShell"; - private static string s_consoleSessionConfigurationKey = "ConsoleSessionConfiguration"; - private static string s_enableConsoleSessionConfiguration = "EnableConsoleSessionConfiguration"; - private static string s_consoleSessionConfigurationName = "ConsoleSessionConfigurationName"; private static string GetConfigurationNameFromGroupPolicy() { // Current user policy takes precedence. - var groupPolicySettings = Utils.GetGroupPolicySetting(s_groupPolicyBase, s_consoleSessionConfigurationKey, Utils.RegCurrentUserThenLocalMachine); - if (groupPolicySettings != null) + var consoleSessionSetting = Utils.GetPolicySetting(Utils.CurrentUserThenSystemWideConfig); + if (consoleSessionSetting != null) { - object keyValue; - if (groupPolicySettings.TryGetValue(s_enableConsoleSessionConfiguration, out keyValue)) + if (consoleSessionSetting.EnableConsoleSessionConfiguration == true) { - if (String.Equals(keyValue.ToString(), "1", StringComparison.OrdinalIgnoreCase)) + if (!string.IsNullOrEmpty(consoleSessionSetting.ConsoleSessionConfigurationName)) { - if (groupPolicySettings.TryGetValue(s_consoleSessionConfigurationName, out keyValue)) - { - string consoleSessionConfigurationName = keyValue.ToString(); - if (!string.IsNullOrEmpty(consoleSessionConfigurationName)) - { - return consoleSessionConfigurationName; - } - } + return consoleSessionSetting.ConsoleSessionConfigurationName; } } } @@ -547,6 +532,7 @@ private void ParseHelper(string[] args) else if (MatchSwitch(switchKey, "help", "h") || MatchSwitch(switchKey, "?", "?")) { _showHelp = true; + _showExtendedHelp = true; _abortStartup = true; } else if (MatchSwitch(switchKey, "noexit", "noe")) @@ -554,10 +540,6 @@ private void ParseHelper(string[] args) _noExit = true; noexitSeen = true; } - else if (MatchSwitch(switchKey, "importsystemmodules", "imp")) - { - _importSystemModules = true; - } else if (MatchSwitch(switchKey, "noprofile", "nop")) { _skipUserInit = true; @@ -609,9 +591,13 @@ private void ParseHelper(string[] args) break; } } -#if !UNIX else if (MatchSwitch(switchKey, "windowstyle", "w")) { +#if UNIX + WriteCommandLineError( + CommandLineParameterParserStrings.WindowStyleArgumentNotImplemented); + break; +#else ++i; if (i >= args.Length) { @@ -632,8 +618,8 @@ private void ParseHelper(string[] args) string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.InvalidWindowStyleArgument, args[i], e.Message)); break; } - } #endif + } else if (MatchSwitch(switchKey, "file", "f")) { if (!ParseFile(args, ref i, noexitSeen)) @@ -728,7 +714,38 @@ private void ParseHelper(string[] args) break; } } -#if !CORECLR // explicit setting of the ApartmentState Not supported on NanoServer + + else if (MatchSwitch(switchKey, "settingsfile", "settings") ) + { + ++i; + if (i >= args.Length) + { + WriteCommandLineError( + CommandLineParameterParserStrings.MissingSettingsFileArgument); + break; + } + string configFile = null; + try + { + configFile = NormalizeFilePath(args[i]); + } + catch (Exception ex) + { + string error = string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.InvalidSettingsFileArgument, args[i], ex.Message); + WriteCommandLineError(error); + break; + } + + if (!System.IO.File.Exists(configFile)) + { + string error = string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.SettingsFileNotExists, configFile); + WriteCommandLineError(error); + break; + } + PowerShellConfig.Instance.SetSystemConfigFilePath(configFile); + } +#if STAMODE + // explicit setting of the ApartmentState Not supported on NanoServer else if (MatchSwitch(switchKey, "sta", "s")) { if (_staMode.HasValue) @@ -756,6 +773,18 @@ private void ParseHelper(string[] args) _staMode = false; } #endif + else if (MatchSwitch(switchKey, "workingdirectory", "wo") || MatchSwitch(switchKey, "wd", "wd")) + { + ++i; + if (i >= args.Length) + { + WriteCommandLineError( + CommandLineParameterParserStrings.MissingWorkingDirectoryArgument); + break; + } + + _workingDirectory = args[i]; + } else { // The first parameter we fail to recognize marks the beginning of the file string. @@ -867,6 +896,15 @@ private void ParseExecutionPolicy(string[] args, ref int i, ref string execution executionPolicy = args[i]; } + private static string NormalizeFilePath(string path) + { + // Normalize slashes + path = path.Replace(StringLiterals.AlternatePathSeparator, + StringLiterals.DefaultPathSeparator); + + return Path.GetFullPath(path); + } + private bool ParseFile(string[] args, ref int i, bool noexitSeen) { // Process file execution. We don't need to worry about checking -command @@ -924,10 +962,7 @@ bool TryGetBoolValue(string arg, out bool boolValue) string exceptionMessage = null; try { - // Normalize slashes - _file = args[i].Replace(StringLiterals.AlternatePathSeparator, - StringLiterals.DefaultPathSeparator); - _file = Path.GetFullPath(_file); + _file = NormalizeFilePath(args[i]); } catch (Exception e) { @@ -969,7 +1004,7 @@ bool TryGetBoolValue(string arg, out bool boolValue) } WriteCommandLineError( string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.ArgumentFileDoesNotExist, args[i]), - showBanner: false); + showHelp: true); return false; } @@ -1004,11 +1039,11 @@ bool TryGetBoolValue(string arg, out bool boolValue) string argName = arg.Substring(0, offset); if (TryGetBoolValue(argValue, out bool boolValue)) { - _collectedArgs.Add(new CommandParameter(argName, boolValue)); + _collectedArgs.Add(new CommandParameter(argName, boolValue)); } else { - _collectedArgs.Add(new CommandParameter(argName, argValue)); + _collectedArgs.Add(new CommandParameter(argName, argValue)); } } } @@ -1178,12 +1213,14 @@ private bool CollectArgs(string[] args, ref int i) private string _configurationName; private PSHostUserInterface _hostUI; private bool _showHelp; + private bool _showExtendedHelp; private bool _showBanner = true; private bool _noInteractive; private string _bannerText; private string _helpText; private bool _abortStartup; private bool _skipUserInit; +#if STAMODE // Win8: 182409 PowerShell 3.0 should run in STA mode by default // -sta and -mta are mutually exclusive..so tracking them using nullable boolean // if true, then sta is specified on the command line. @@ -1191,6 +1228,7 @@ private bool CollectArgs(string[] args, ref int i) // if null, then none is specified on the command line..use default in this case // default is sta. private bool? _staMode = null; +#endif private bool _noExit = true; private bool _explicitReadCommandsFromStdin; private bool _noPrompt; @@ -1203,7 +1241,7 @@ private bool CollectArgs(string[] args, ref int i) private Collection _collectedArgs = new Collection(); private string _file; private string _executionPolicy; - private bool _importSystemModules = false; + private string _workingDirectory; } } // namespace diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs index 0f0c7f5cc4d..13687f7d35d 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs @@ -1,8 +1,7 @@ -#if !UNIX -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +#if !UNIX // Implementation notes: In the functions that take ConsoleHandle parameters, we only assert that the handle is valid and not // closed, as opposed to doing a check and throwing an exception. This is because the win32 APIs that those functions wrap will @@ -13,7 +12,6 @@ // could do is diddle with the console buffer. #pragma warning disable 1634, 1691 - using System; using System.Text; using System.Runtime.InteropServices; @@ -724,13 +722,10 @@ internal static void SetMode(ConsoleHandle consoleHandle, ConsoleModes mode) } } - #endregion #region Input - - /// /// /// Reads input from the console device according to the mode in effect (see GetMode, SetMode) @@ -1344,7 +1339,6 @@ internal static void CheckWriteEdges( } } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called in CHK builds")] private static void CheckWriteConsoleOutputContents(BufferCell[,] contents, Rectangle contentsRegion) { @@ -2051,7 +2045,6 @@ internal static void ReadConsoleOutputCJK readRegion.Top += bufferSize.Y; } // row iteration - // The following nested loop set the value of the empty cells in contents: // character to ' ' // foreground color to console's foreground color @@ -2097,7 +2090,6 @@ out background } #endregion ReadConsoleOutput CJK - private static void ReadConsoleOutputPlain ( ConsoleHandle consoleHandle, @@ -2277,7 +2269,6 @@ out background } } - /// /// Wraps Win32 FillConsoleOutputCharacter /// @@ -2543,8 +2534,6 @@ internal static Size GetLargestConsoleWindowSize(ConsoleHandle consoleHandle) return new Size(result.X, result.Y); } - - /// /// Wraps Win32 GetConsoleTitle. 1K is the safe limit experimentally. The 64K limit /// found in the docs is disregarded because it is essentially meaningless. @@ -2608,109 +2597,6 @@ internal static void SetConsoleWindowTitle(string consoleTitle) #endregion Window -#if !CORECLR -#region Font Selection - - /// - /// UpdateLocaleSpecificFont is a helper method used to update - /// the console font based on the locale. - /// The default font face used for Powershell Console is Lucida Console. - /// However certain locales dont support Lucida Console font. Hence for such - /// locales the console font is updated to Raster dynamically. - /// - internal static void UpdateLocaleSpecificFont() - { - // Default Powershell shortcut.lnk settings. - const string defaultFontFace = "Lucida Console"; - - // Default CJK locale shortcut.lnk settings. - // Font size is hard coded here to ensure we select a supported size. - // GDI does a poor job of selecting raster font size if the requested - // size is not supported. - const string CJKFontFace = "Terminal"; - const int CJKFontFamily = 48; - const int CJKnFont = 6; - const int CJKFontWidth = 8; - const int CJKFontHeight = 12; - const int CKJFontWeight = 400; - - uint currentLocaleCodePage = (uint)ConsoleControl.NativeMethods.GetConsoleCP(); - - ConsoleHandle handle = ConsoleControl.GetActiveScreenBufferHandle(); - CONSOLE_FONT_INFO_EX fontInfo; - try - { - fontInfo = ConsoleControl.GetConsoleFontInfo(handle); - } - catch (Exception) - { - return; - } - - bool isLucidaConsoleSupportedLocale = CodePageSupportsLucida(currentLocaleCodePage); - - // The Raster font is updated for Japanese and Korean locales if the user has not manually - // altered the default settings. If the default settings are altered then the - // setting chosen by the user would be used. - if (!isLucidaConsoleSupportedLocale && - fontInfo.FontFace.Equals(defaultFontFace, StringComparison.OrdinalIgnoreCase)) - { - fontInfo.FontFace = CJKFontFace; - fontInfo.FontFamily = CJKFontFamily; - fontInfo.nFont = CJKnFont; - fontInfo.FontWidth = CJKFontWidth; - fontInfo.FontHeight = CJKFontHeight; - fontInfo.FontWeight = CKJFontWeight; - - bool result = NativeMethods.SetCurrentConsoleFontEx(handle.DangerousGetHandle(), false, ref fontInfo); - - if (result == false) - { - int err = Marshal.GetLastWin32Error(); - - HostException e = CreateHostException(err, - "SetConsoleFontInfo", - ErrorCategory.ResourceUnavailable, - ConsoleControlStrings.SetConsoleFontInfoExceptionTemplate); - - throw e; - } - } - } - - /// - /// Supported Lucida code pages obtained from Font group. - /// Contacts: alib, judysa, simonda - /// - private static HashSet LucidaSupportedCodePages = new HashSet() - { - 1251, // Latin 1 - 1250, // Latin 2 - 1251, // Cyrillic - 1253, // Greek - 1254, // Turkish - 869, // IBM Greek - 866, // MS-DOS Russian - 865, // MS-DOS Nordic - 863, // MS-DOS Canadian French - 861, // MS-DOS Icelandic - 860, // MS-DOS Portuguese - 857, // IBM Turkish - 855, // IBM Cyrillic - 852, // Latin 2 - 737, // Greek - 850, // WE/Latin 1 - 437 // US - //936, // SimplifiedChinese - According to font team this is *not* supported. - //950 // TraditionalChinese - According to font team this is *not* supported. - }; - private static bool CodePageSupportsLucida(uint currentLocaleCodePage) - { - return LucidaSupportedCodePages.Contains(currentLocaleCodePage); - } - -#endregion -#endif /// /// /// Wrap Win32 WriteConsole @@ -2819,229 +2705,6 @@ internal static void SetConsoleTextAttribute(ConsoleHandle consoleHandle, WORD a #endif #region Dealing with CJK -#if !UNIX - - /// - /// From IsConsoleFullWidth in \windows\core\ntcon\server\dbcs.c - /// Gets the CharSet for a code page - /// - /// - /// The CharSet corresponding to the codePage; defaults to OEM_CHARSET (255) - private static uint CodePageToCharSet(uint codePage) - { - const uint OEM_CHARSET = 255; - // Suppress the PreFAST warning about not using Marshal.GetLastWin32Error() to - // get the error code. -#pragma warning disable 56523 -#if CORECLR // TranslateCharsetInfo exists in an extension API set 'ext-ms-win-gdi-font-l1-1-1.dll', which is not available in NanoServer. - return OEM_CHARSET; -#else - CHARSETINFO csi; - const DWORD TCI_SRCCODEPAGE = 2; - if (!NativeMethods.TranslateCharsetInfo((IntPtr)codePage, out csi, TCI_SRCCODEPAGE)) - { - csi.ciCharset = OEM_CHARSET; - } - return csi.ciCharset; -#endif - } - - // From \windows\core\ntcon\server\dbcs.c - private static bool IsAvailableFarEastCodePage(uint codePage) - { - uint charSet = CodePageToCharSet(codePage); - return IsAnyDBCSCharSet(charSet); - } - - // From \windows\core\ntcon\server\dbcs.c - private static bool IsAnyDBCSCharSet(uint charSet) - { - const uint SHIFTJIS_CHARSET = 128; - const uint HANGUL_CHARSET = 129; - const uint CHINESEBIG5_CHARSET = 136; - const uint GB2312_CHARSET = 134; - return charSet == SHIFTJIS_CHARSET || charSet == HANGUL_CHARSET || - charSet == CHINESEBIG5_CHARSET || charSet == GB2312_CHARSET; - } - - /// - /// From IsConsoleFullWidth in \windows\core\ntcon\server\dbcs.c - /// Precondition: the current code page needs to be a Far East code page. - /// - /// char F8F8 makes this function return 1 while in CHT, CHS, and KOR it takes 2 cells. - /// I don't think we should special-case this because that ought to be a bug outside of - /// this code. - /// - /// - /// window handle - /// handle to DC; it is not released by this method - /// - /// - /// - private static int LengthInBufferCellsFE(char c, ref HWND hwnd, ref HDC hDC, ref bool istmInitialized, ref TEXTMETRIC tm) - { - if (0x20 <= c && c <= 0x7e) - { - /* ASCII */ - return 1; - } - else if (0x3041 <= c && c <= 0x3094) - { - /* Hiragana */ - return 2; - } - else if (0x30a1 <= c && c <= 0x30f6) - { - /* Katakana */ - return 2; - } - else if (0x3105 <= c && c <= 0x312c) - { - /* Bopomofo */ - return 2; - } - else if (0x3131 <= c && c <= 0x318e) - { - /* Hangul Elements */ - return 2; - } - else if (0xac00 <= c && c <= 0xd7a3) - { - /* Korean Hangul Syllables */ - return 2; - } - else if (0xff01 <= c && c <= 0xff5e) - { - /* Fullwidth ASCII variants */ - return 2; - } - else if (0xff61 <= c && c <= 0xff9f) - { - /* Halfwidth Katakana variants */ - return 1; - } - else if ((0xffa0 <= c && c <= 0xffbe) || - (0xffc2 <= c && c <= 0xffc7) || - (0xffca <= c && c <= 0xffcf) || - (0xffd2 <= c && c <= 0xffd7) || - (0xffda <= c && c <= 0xffdc)) - { - /* Halfwidth Hangul variants */ - return 1; - } - else if (0xffe0 <= c && c <= 0xffe6) - { - /* Fullwidth symbol variants */ - return 2; - } - else if (0x4e00 <= c && c <= 0x9fa5) - { - /* Han Ideographic */ - return 2; - } - else if (0xf900 <= c && c <= 0xfa2d) - { - /* Han Compatibility Ideographs */ - return 2; - } - else - { - // GetTextMetrics / GetCharWidth32 exist in an extension API set 'ext-ms-win-gdi-font-l1-1-1.dll', which is not available in NanoServer. -#if !CORECLR - /* Unknown character: need to use GDI*/ - if (hDC == (IntPtr)0) - { - hwnd = NativeMethods.GetConsoleWindow(); - if ((IntPtr)0 == hwnd) - { - int err = Marshal.GetLastWin32Error(); - //Don't throw exception so that output can continue - tracer.TraceError("Win32 Error 0x{0:X} occurred when getting the window handle to the console.", - err); - return 1; - } - hDC = NativeMethods.GetDC(hwnd); - if ((IntPtr)0 == hDC) - { - int err = Marshal.GetLastWin32Error(); - //Don't throw exception so that output can continue - tracer.TraceError("Win32 Error 0x{0:X} occurred when getting the Device Context of the console window.", - err); - return 1; - } - } - bool result = true; - if (!istmInitialized) - { - result = NativeMethods.GetTextMetrics(hDC, out tm); - if (!result) - { - int err = Marshal.GetLastWin32Error(); - //Don't throw exception so that output can continue - tracer.TraceError("Win32 Error 0x{0:X} occurred when getting the Text Metric of the console window's Device Context.", - err); - return 1; - } - istmInitialized = true; - } - int width; - result = NativeMethods.GetCharWidth32(hDC, (uint)c, (uint)c, out width); - if (!result) - { - int err = Marshal.GetLastWin32Error(); - //Don't throw exception so that output can continue - tracer.TraceError("Win32 Error 0x{0:X} occurred when getting the width of a char.", - err); - return 1; - } - if (width >= tm.tmMaxCharWidth) - { - return 2; - } -#endif - } - tracer.WriteLine("failed to locate char {0}, return 1", (int)c); - return 1; - } - - internal static int LengthInBufferCells(char c) - { - uint codePage = NativeMethods.GetConsoleOutputCP(); - return LengthInBufferCells(c, codePage); - } - - /// - /// From IsConsoleFullWidth in \windows\core\ntcon\server\dbcs.c - /// - /// - /// - /// - [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", - MessageId = "Microsoft.PowerShell.ConsoleControl+NativeMethods.ReleaseDC(System.IntPtr,System.IntPtr)")] - private static int LengthInBufferCells(char c, uint codePage) - { - if (!IsAvailableFarEastCodePage(codePage)) - { - return 1; - } - HWND hwnd = (HWND)0; - HDC hDC = (HDC)0; - bool istmInitialized = false; - TEXTMETRIC tm = new TEXTMETRIC(); ; - try - { - return LengthInBufferCellsFE(c, ref hwnd, ref hDC, ref istmInitialized, ref tm); - } - finally - { - if (hwnd != (IntPtr)0 && hDC != (IntPtr)0) - { - NativeMethods.ReleaseDC(hwnd, hDC); - } - } - } - -#endif // Return the length of a VT100 control sequence character in str starting // at the given offset. @@ -3108,38 +2771,7 @@ internal static int LengthInBufferCells(string str, int offset, bool checkEscape } } -#if UNIX return str.Length - offset - escapeSequenceAdjustment; -#else - uint codePage = NativeMethods.GetConsoleOutputCP(); - if (!IsAvailableFarEastCodePage(codePage)) - { - return str.Length - offset - escapeSequenceAdjustment; - } - - HWND hwnd = (HWND)0; - HDC hDC = (HDC)0; - bool istmInitialized = false; - TEXTMETRIC tm = new TEXTMETRIC(); ; - int length = 0; - try - { - int n = str.Length; - for (int i = offset; i < n; i++) - { - char c = str[i]; - length += LengthInBufferCellsFE(c, ref hwnd, ref hDC, ref istmInitialized, ref tm); - } - return length - escapeSequenceAdjustment; - } - finally - { - if (hwnd != (IntPtr)0 && hDC != (IntPtr)0) - { - NativeMethods.ReleaseDC(hwnd, hDC); - } - } -#endif } #if !UNIX @@ -3165,7 +2797,6 @@ internal static bool IsCJKOutputCodePage(out uint codePage) #region Cursor - /// /// Wraps Win32 SetConsoleCursorPosition /// @@ -3205,8 +2836,6 @@ internal static void SetConsoleCursorPosition(ConsoleHandle consoleHandle, Coord } } - - /// /// Wraps Win32 GetConsoleCursorInfo /// @@ -3321,6 +2950,33 @@ private static HostException CreateHostException( #endregion helper +#region + + internal static int LengthInBufferCells(char c) + { + // The following is based on http://www.cl.cam.ac.uk/~mgk25/c/wcwidth.c + // which is derived from http://www.unicode.org/Public/UCD/latest/ucd/EastAsianWidth.txt + + bool isWide = c >= 0x1100 && + (c <= 0x115f || /* Hangul Jamo init. consonants */ + c == 0x2329 || c == 0x232a || + (c >= 0x2e80 && c <= 0xa4cf && + c != 0x303f) || /* CJK ... Yi */ + (c >= 0xac00 && c <= 0xd7a3) || /* Hangul Syllables */ + (c >= 0xf900 && c <= 0xfaff) || /* CJK Compatibility Ideographs */ + (c >= 0xfe10 && c <= 0xfe19) || /* Vertical forms */ + (c >= 0xfe30 && c <= 0xfe6f) || /* CJK Compatibility Forms */ + (c >= 0xff00 && c <= 0xff60) || /* Fullwidth Forms */ + (c >= 0xffe0 && c <= 0xffe6)); + // We can ignore these ranges because .Net strings use surrogate pairs + // for this range and we do not handle surrogage pairs. + // (c >= 0x20000 && c <= 0x2fffd) || + // (c >= 0x30000 && c <= 0x3fffd) + return 1 + (isWide ? 1 : 0); + } + +#endregion + #region SendInput internal static void MimicKeyPress(INPUT[] inputs) @@ -3396,9 +3052,6 @@ NakedWin32Handle templateFileWin32Handle #region Code Page - [DllImport(PinvokeDllNames.GetConsoleCPDllName, SetLastError = false, CharSet = CharSet.Unicode)] - internal static extern uint GetConsoleCP(); - [DllImport(PinvokeDllNames.GetConsoleOutputCPDllName, SetLastError = false, CharSet = CharSet.Unicode)] internal static extern uint GetConsoleOutputCP(); @@ -3413,15 +3066,6 @@ NakedWin32Handle templateFileWin32Handle [DllImport(PinvokeDllNames.ReleaseDCDllName, SetLastError = false, CharSet = CharSet.Unicode)] internal static extern int ReleaseDC(HWND hwnd, HDC hdc); - [DllImport(PinvokeDllNames.TranslateCharsetInfoDllName, SetLastError = true, CharSet = CharSet.Unicode)] - internal static extern bool TranslateCharsetInfo(IntPtr src, out CHARSETINFO Cs, DWORD options); - - [DllImport(PinvokeDllNames.GetTextMetricsDllName, SetLastError = true, CharSet = CharSet.Unicode)] - internal static extern bool GetTextMetrics(HDC hdc, out TEXTMETRIC tm); - - [DllImport(PinvokeDllNames.GetCharWidth32DllName, SetLastError = true, CharSet = CharSet.Unicode)] - internal static extern bool GetCharWidth32(HDC hdc, uint first, uint last, out int width); - [DllImport(PinvokeDllNames.FlushConsoleInputBufferDllName, SetLastError = true, CharSet = CharSet.Unicode)] internal static extern bool FlushConsoleInputBuffer(NakedWin32Handle consoleInput); @@ -3467,7 +3111,6 @@ IntPtr reserved [DllImport(PinvokeDllNames.GetConsoleScreenBufferInfoDllName, SetLastError = true, CharSet = CharSet.Unicode)] internal static extern bool GetConsoleScreenBufferInfo(NakedWin32Handle consoleHandle, out CONSOLE_SCREEN_BUFFER_INFO consoleScreenBufferInfo); - internal enum FileType { Unknown, @@ -3476,15 +3119,9 @@ internal enum FileType Pipe }; - [DllImport(PinvokeDllNames.GetFileTypeDllName, SetLastError = true, CharSet = CharSet.Unicode)] - internal static extern FileType GetFileType(NakedWin32Handle fileHandle); - [DllImport(PinvokeDllNames.GetLargestConsoleWindowSizeDllName, SetLastError = true, CharSet = CharSet.Unicode)] internal static extern COORD GetLargestConsoleWindowSize(NakedWin32Handle consoleOutput); - [DllImport(PinvokeDllNames.GetStdHandleDllName, SetLastError = true, CharSet = CharSet.Unicode)] - internal static extern IntPtr GetStdHandle(int handleId); - [DllImport(PinvokeDllNames.ReadConsoleDllName, SetLastError = true, CharSet = CharSet.Unicode)] internal static extern bool ReadConsole ( @@ -3563,10 +3200,6 @@ ref CHAR_INFO fill [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] internal static extern bool GetCurrentConsoleFontEx(NakedWin32Handle consoleOutput, bool bMaximumWindow, ref CONSOLE_FONT_INFO_EX consoleFontInfo); - // There is no SetCurrentConsoleFontEx on Core - [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - internal static extern bool SetCurrentConsoleFontEx(NakedWin32Handle consoleOutput, bool bMaximumWindow, ref CONSOLE_FONT_INFO_EX consoleFontInfo); - [DllImport(PinvokeDllNames.GetConsoleCursorInfoDllName, SetLastError = true, CharSet = CharSet.Unicode)] internal static extern bool GetConsoleCursorInfo(NakedWin32Handle consoleOutput, out CONSOLE_CURSOR_INFO consoleCursorInfo); diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs index 62a5692eb66..f40c74a1549 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs @@ -1,8 +1,7 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ -#pragma warning disable 1634, 1691 +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +#pragma warning disable 1634, 1691 using System; using System.Diagnostics.CodeAnalysis; @@ -66,10 +65,6 @@ internal sealed partial class ConsoleHost /// /// /// - /// - /// Configuration information to use for creating runspace. - /// - /// /// /// Banner text to be displayed by ConsoleHost /// @@ -78,15 +73,9 @@ internal sealed partial class ConsoleHost /// Help text for minishell. This is displayed on 'minishell -?'. /// /// - /// - /// - /// Warning occurred prior to this point, for example, a snap-in fails to load beforehand. - /// This string will be printed out. - /// - /// /// /// - /// Command line parameters to powershell.exe + /// Command line parameters to pwsh.exe /// /// /// @@ -118,10 +107,8 @@ internal sealed partial class ConsoleHost /// /// internal static int Start( - RunspaceConfiguration configuration, string bannerText, string helpText, - string preStartWarning, string[] args) { #if DEBUG @@ -178,7 +165,7 @@ internal static int Start( HostException hostException = null; try { - s_theConsoleHost = ConsoleHost.CreateSingletonInstance(configuration); + s_theConsoleHost = ConsoleHost.CreateSingletonInstance(); } catch (HostException e) { @@ -198,6 +185,12 @@ internal static int Start( s_cpp.Parse(tempArgs); +#if UNIX + // On Unix, logging has to be deferred until after command-line parsing + // completes to allow overriding logging options. + PSEtwLog.LogConsoleStartup(); +#endif + if (s_cpp.ShowVersion) { // Alternatively, we could call s_theConsoleHost.UI.WriteLine(s_theConsoleHost.Version.ToString()); @@ -254,21 +247,9 @@ internal static int Start( throw hostException; } -#if !CORECLR - // The default font face used for Powershell Console is Lucida Console. - // However certain CJK locales dont support Lucida Console font. Hence for such - // locales the console font is updated to Raster dynamically. - ConsoleControl.UpdateLocaleSpecificFont(); -#endif - s_theConsoleHost.BindBreakHandler(); PSHost.IsStdOutputRedirected = Console.IsOutputRedirected; - if (!string.IsNullOrEmpty(preStartWarning)) - { - s_theConsoleHost.UI.WriteWarningLine(preStartWarning); - } - // Send startup telemetry for ConsoleHost startup ApplicationInsightsTelemetry.SendPSCoreStartupTelemetry(); @@ -276,7 +257,7 @@ internal static int Start( s_theConsoleHost.LoadPSReadline() ? "StartupProfileData-Interactive" : "StartupProfileData-NonInteractive"); - exitCode = s_theConsoleHost.Run(s_cpp, !string.IsNullOrEmpty(preStartWarning)); + exitCode = s_theConsoleHost.Run(s_cpp, false); } } finally @@ -297,8 +278,6 @@ internal static int Start( } private static CommandLineParameterParser s_cpp; - - #if UNIX /// /// @@ -422,10 +401,6 @@ private static void SpinUpBreakHandlerThread(bool shouldEndSession) lock (host.hostGlobalLock) { - if (host._isCtrlCDisabled) - { - return; - } bht = host._breakHandlerThread; if (!host.ShouldEndSession && shouldEndSession) { @@ -524,10 +499,10 @@ private static bool StopPipeline(Pipeline cmd) /// /// Create single instance of ConsoleHost. /// - internal static ConsoleHost CreateSingletonInstance(RunspaceConfiguration configuration) + internal static ConsoleHost CreateSingletonInstance() { Dbg.Assert(s_theConsoleHost == null, "CreateSingletonInstance should not be called multiple times"); - s_theConsoleHost = new ConsoleHost(configuration); + s_theConsoleHost = new ConsoleHost(); return s_theConsoleHost; } @@ -884,8 +859,6 @@ public override PSObject PrivateData } private PSObject _consoleColorProxy; - - /// /// /// See base class @@ -900,17 +873,11 @@ public override System.Globalization.CultureInfo CurrentCulture { lock (hostGlobalLock) { -#if !CORECLR - return NativeCultureResolver.Culture; -#else return CultureInfo.CurrentCulture; -#endif } } } - - /// /// /// See base class @@ -925,11 +892,7 @@ public override System.Globalization.CultureInfo CurrentUICulture { lock (hostGlobalLock) { -#if !CORECLR - return NativeCultureResolver.UICulture; -#else return CultureInfo.CurrentUICulture; -#endif } } } @@ -1095,7 +1058,7 @@ bool IHostProvidesTelemetryData.HostIsInteractive /// Constructs a new instance /// /// - internal ConsoleHost(RunspaceConfiguration configuration) + internal ConsoleHost() { #if !UNIX try @@ -1121,14 +1084,11 @@ internal ConsoleHost(RunspaceConfiguration configuration) InDebugMode = false; _displayDebuggerBanner = true; - _configuration = configuration; this.ui = new ConsoleHostUserInterface(this); _consoleWriter = new ConsoleTextWriter(ui); -#if !CORECLR // CurrentDomain.UnhandledException not supported on CoreCLR UnhandledExceptionEventHandler handler = new UnhandledExceptionEventHandler(UnhandledExceptionHandler); AppDomain.CurrentDomain.UnhandledException += handler; -#endif } private void BindBreakHandler() @@ -1141,7 +1101,6 @@ private void BindBreakHandler() #endif } -#if !CORECLR // Not used on NanoServer: CurrentDomain.UnhandledException not supported on CoreCLR private void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args) { // FYI: sender is a reference to the source app domain @@ -1165,7 +1124,6 @@ private void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArg ConsoleHostStrings.UnhandledExceptionShutdownMessage); ui.WriteLine(); } -#endif /// /// @@ -1290,7 +1248,6 @@ internal RunspaceRef RunspaceRef internal WrappedSerializer.DataFormat OutputFormat { get; private set; } - internal WrappedSerializer.DataFormat InputFormat { get; private set; } internal WrappedDeserializer.DataFormat ErrorFormat @@ -1438,7 +1395,11 @@ private uint Run(CommandLineParameterParser cpp, bool isPrestartWarned) // NTRAID#Windows Out Of Band Releases-915506-2005/09/09 // Removed HandleUnexpectedExceptions infrastructure - exitCode = DoRunspaceLoop(cpp.InitialCommand, cpp.SkipProfiles, cpp.Args, cpp.StaMode, cpp.ImportSystemModules, cpp.ConfigurationName); +#if STAMODE + exitCode = DoRunspaceLoop(cpp.InitialCommand, cpp.SkipProfiles, cpp.Args, cpp.StaMode, cpp.ConfigurationName); +#else + exitCode = DoRunspaceLoop(cpp.InitialCommand, cpp.SkipProfiles, cpp.Args, false, cpp.ConfigurationName); +#endif } while (false); @@ -1472,14 +1433,13 @@ private uint Run(string bannerText, string helpText, bool isPrestartWarned, stri /// The process exit code to be returned by Main. /// /// - private uint DoRunspaceLoop(string initialCommand, bool skipProfiles, Collection initialCommandArgs, bool staMode, - bool importSystemModules, string configurationName) + private uint DoRunspaceLoop(string initialCommand, bool skipProfiles, Collection initialCommandArgs, bool staMode, string configurationName) { ExitCode = ExitCodeSuccess; while (!ShouldEndSession) { - RunspaceCreationEventArgs args = new RunspaceCreationEventArgs(initialCommand, skipProfiles, staMode, importSystemModules, configurationName, initialCommandArgs); + RunspaceCreationEventArgs args = new RunspaceCreationEventArgs(initialCommand, skipProfiles, staMode, configurationName, initialCommandArgs); CreateRunspace(args); if (ExitCode == ExitCodeInitFailure) { break; } @@ -1518,10 +1478,12 @@ private uint DoRunspaceLoop(string initialCommand, bool skipProfiles, Collection _runspaceRef.Runspace.Close(); _runspaceRef = null; +#if STAMODE if (staMode) // don't recycle the Runspace in STA mode { ShouldEndSession = true; } +#endif } return ExitCode; @@ -1559,7 +1521,11 @@ private void CreateRunspace(object runspaceCreationArgs) { args = runspaceCreationArgs as RunspaceCreationEventArgs; Dbg.Assert(args != null, "Event Arguments to CreateRunspace should not be null"); - DoCreateRunspace(args.InitialCommand, args.SkipProfiles, args.StaMode, args.ImportSystemModules, args.ConfigurationName, args.InitialCommandArgs); +#if STAMODE + DoCreateRunspace(args.InitialCommand, args.SkipProfiles, args.StaMode, args.ConfigurationName, args.InitialCommandArgs); +#else + DoCreateRunspace(args.InitialCommand, args.SkipProfiles, false, args.ConfigurationName, args.InitialCommandArgs); +#endif } catch (ConsoleHostStartupException startupException) { @@ -1574,7 +1540,7 @@ private void CreateRunspace(object runspaceCreationArgs) [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] private void InitializeRunspace(string initialCommand, bool skipProfiles, Collection initialCommandArgs) { - DoCreateRunspace(initialCommand, skipProfiles, staMode: false, importSystemModules: false, configurationName: null, initialCommandArgs: initialCommandArgs); + DoCreateRunspace(initialCommand, skipProfiles, staMode: false, configurationName: null, initialCommandArgs: initialCommandArgs); } private bool LoadPSReadline() @@ -1597,14 +1563,10 @@ private bool LoadPSReadline() /// /// - //private void CreateRunspace(string initialCommand, bool skipProfiles, bool staMode, Collection initialCommandArgs) - private void DoCreateRunspace(string initialCommand, bool skipProfiles, bool staMode, bool importSystemModules, string configurationName, Collection initialCommandArgs) + private void DoCreateRunspace(string initialCommand, bool skipProfiles, bool staMode, string configurationName, Collection initialCommandArgs) { Dbg.Assert(_runspaceRef == null, "runspace should be null"); -#if !DEBUG - Dbg.Assert(_configuration != null, "configuration should be set"); -#endif - + Dbg.Assert(DefaultInitialSessionState != null, "DefaultInitialSessionState should not be null"); s_runspaceInitTracer.WriteLine("Calling RunspaceFactory.CreateRunspace"); try @@ -1612,53 +1574,45 @@ private void DoCreateRunspace(string initialCommand, bool skipProfiles, bool sta Runspace consoleRunspace = null; bool psReadlineFailed = false; - // Use InitialSessionState if available. - if (DefaultInitialSessionState != null) - { - // Load PSReadline by default unless there is no use: - // - we're running a command/file and just exiting - // - stdin is redirected by a parent process - // - we're not interactive - // - we're explicitly reading from stdin (the '-' argument) - // It's also important to have a scenario where PSReadline is not loaded so it can be updated, e.g. - // powershell -command "Update-Module PSReadline" - // This should work just fine as long as no other instances of PowerShell are running. - ReadOnlyCollection defaultImportModulesList = null; - if (LoadPSReadline()) + // Load PSReadline by default unless there is no use: + // - we're running a command/file and just exiting + // - stdin is redirected by a parent process + // - we're not interactive + // - we're explicitly reading from stdin (the '-' argument) + // It's also important to have a scenario where PSReadline is not loaded so it can be updated, e.g. + // powershell -command "Update-Module PSReadline" + // This should work just fine as long as no other instances of PowerShell are running. + ReadOnlyCollection defaultImportModulesList = null; + if (LoadPSReadline()) + { + // Create and open Runspace with PSReadline. + defaultImportModulesList = DefaultInitialSessionState.Modules; + DefaultInitialSessionState.ImportPSModule(new[] { "PSReadLine" }); + consoleRunspace = RunspaceFactory.CreateRunspace(this, DefaultInitialSessionState); + try { - // Create and open Runspace with PSReadline. - defaultImportModulesList = DefaultInitialSessionState.Modules; - DefaultInitialSessionState.ImportPSModule(new[] { "PSReadLine" }); - consoleRunspace = RunspaceFactory.CreateRunspace(this, DefaultInitialSessionState); - try - { - OpenConsoleRunspace(consoleRunspace, staMode); - } - catch (Exception) - { - consoleRunspace = null; - psReadlineFailed = true; - } + OpenConsoleRunspace(consoleRunspace, staMode); } - - if (consoleRunspace == null) + catch (Exception) { - if (psReadlineFailed) - { - // Try again but without importing the PSReadline module. - DefaultInitialSessionState.ClearPSModules(); - DefaultInitialSessionState.ImportPSModule(defaultImportModulesList); - } - consoleRunspace = RunspaceFactory.CreateRunspace(this, DefaultInitialSessionState); - OpenConsoleRunspace(consoleRunspace, staMode); + consoleRunspace = null; + psReadlineFailed = true; } } - else + + if (consoleRunspace == null) { - consoleRunspace = RunspaceFactory.CreateRunspace(this, _configuration); + if (psReadlineFailed) + { + // Try again but without importing the PSReadline module. + DefaultInitialSessionState.ClearPSModules(); + DefaultInitialSessionState.ImportPSModule(defaultImportModulesList); + } + consoleRunspace = RunspaceFactory.CreateRunspace(this, DefaultInitialSessionState); OpenConsoleRunspace(consoleRunspace, staMode); } + Runspace.PrimaryRunspace = consoleRunspace; _runspaceRef = new RunspaceRef(consoleRunspace); if (psReadlineFailed) @@ -1685,11 +1639,12 @@ private void DoCreateRunspace(string initialCommand, bool skipProfiles, bool sta // Record how long it took from process start to runspace open for telemetry. _readyForInputTimeInMS = (DateTime.Now - Process.GetCurrentProcess().StartTime).TotalMilliseconds; - DoRunspaceInitialization(importSystemModules, skipProfiles, initialCommand, configurationName, initialCommandArgs); + DoRunspaceInitialization(skipProfiles, initialCommand, configurationName, initialCommandArgs); } private void OpenConsoleRunspace(Runspace runspace, bool staMode) { +#if STAMODE // staMode will have following values: // On FullPS: 'true'/'false' = default('true'=STA) + possibility of overload through cmdline parameter '-mta' // On NanoPS: always 'false' = default('false'=MTA) + NO possibility of overload through cmdline parameter '-mta' @@ -1697,20 +1652,17 @@ private void OpenConsoleRunspace(Runspace runspace, bool staMode) if (staMode) { // we can't change ApartmentStates on CoreCLR -#if !CORECLR runspace.ApartmentState = ApartmentState.STA; -#endif - runspace.ThreadOptions = PSThreadOptions.ReuseThread; } - +#endif + runspace.ThreadOptions = PSThreadOptions.ReuseThread; runspace.EngineActivityId = EtwActivity.GetActivityId(); s_runspaceInitTracer.WriteLine("Calling Runspace.Open"); - runspace.Open(); } - private void DoRunspaceInitialization(bool importSystemModules, bool skipProfiles, string initialCommand, string configurationName, Collection initialCommandArgs) + private void DoRunspaceInitialization(bool skipProfiles, string initialCommand, string configurationName, Collection initialCommandArgs) { if (_runspaceRef.Runspace.Debugger != null) { @@ -1720,12 +1672,6 @@ private void DoRunspaceInitialization(bool importSystemModules, bool skipProfile Executor exec = new Executor(this, false, false); - // Run import system modules command - if (importSystemModules) - { - Exception exception = InitializeRunspaceHelper("ImportSystemModules", exec, Executor.ExecutionOptions.None); - } - if (!string.IsNullOrEmpty(configurationName)) { // If an endpoint configuration is specified then create a loop-back remote runspace targeting @@ -1746,46 +1692,7 @@ private void DoRunspaceInitialization(bool importSystemModules, bool skipProfile } else { - // Run the built-in scripts - RunspaceConfigurationEntryCollection scripts = new RunspaceConfigurationEntryCollection(); - if (_configuration != null) - scripts = _configuration.InitializationScripts; - - if ((scripts == null) || (scripts.Count == 0)) - { - s_runspaceInitTracer.WriteLine("There are no built-in scripts to run"); - } - else - { - foreach (ScriptConfigurationEntry s in scripts) - { - s_runspaceInitTracer.WriteLine("Running script: '{0}'", s.Name); - - // spec claims that Ctrl-C is not supposed to stop these. - - try - { - _isCtrlCDisabled = true; - Exception e = InitializeRunspaceHelper(s.Definition, exec, Executor.ExecutionOptions.AddOutputter); - if (e != null) - { - throw new ConsoleHostStartupException(ConsoleHostStrings.InitScriptFailed, e); - } - } - finally - { - _isCtrlCDisabled = false; - } - } - } - - // If -iss has been specified, then there won't be a runspace - // configuration to get the shell ID from, so we'll use the default... - string shellId = null; - if (_configuration != null) - shellId = _configuration.ShellId; - else - shellId = "Microsoft.PowerShell"; // TODO: what will happen for custom shells built using Make-Shell.exe + string shellId = "Microsoft.PowerShell"; // If the system lockdown policy says "Enforce", do so. Do this after types / formatting, default functions, etc // are loaded so that they are trusted. (Validation of their signatures is done in F&O) @@ -1845,6 +1752,31 @@ private void DoRunspaceInitialization(bool importSystemModules, bool skipProfile TelemetryAPI.ReportStartupTelemetry(this); #endif + // If working directory was specified, set it + if (s_cpp != null && s_cpp.WorkingDirectory != null) + { + Pipeline tempPipeline = exec.CreatePipeline(); + var command = new Command("Set-Location"); + command.Parameters.Add("LiteralPath", s_cpp.WorkingDirectory); + tempPipeline.Commands.Add(command); + + Exception exception; + if (IsRunningAsync) + { + exec.ExecuteCommandAsyncHelper(tempPipeline, out exception, Executor.ExecutionOptions.AddOutputter); + } + else + { + exec.ExecuteCommandHelper(tempPipeline, out exception, Executor.ExecutionOptions.AddOutputter); + } + + if (exception != null) + { + _lastRunspaceInitializationException = exception; + ReportException(exception, exec); + } + } + // If a file was specified as the argument to run, then run it... if (s_cpp != null && s_cpp.File != null) { @@ -2009,7 +1941,6 @@ private void RunProfile(string profileFileName, Executor exec) } } - /// /// /// Escapes backtick and tick characters with a backtick, returns the result @@ -2161,7 +2092,6 @@ private void ReportExceptionFallback(Exception e, string header) /// internal event EventHandler RunspacePushed; - #endregion non-overrides #region debugger @@ -2313,7 +2243,7 @@ private void ExitDebugMode(DebuggerResumeAction resumeAction) /// private void WriteDebuggerMessage(string line) { - this.ui.WriteWrappedLine(this.ui.DebugForegroundColor, this.ui.DebugBackgroundColor, line); + this.ui.WriteLine(this.ui.DebugForegroundColor, this.ui.DebugBackgroundColor, line); } #endregion debugger @@ -2525,7 +2455,7 @@ internal void Run(bool inputLoopIsNested) continue; } - if (line.Trim().Length == 0) + if (string.IsNullOrWhiteSpace(line)) { if (inBlockMode) { @@ -2900,7 +2830,7 @@ private class ConsoleHostStartupException : Exception base(message) { } -#if !CORECLR // ApplicationException & System.Runtime.Serialization.SerializationInfo are Not In CoreCLR + protected ConsoleHostStartupException( System.Runtime.Serialization.SerializationInfo info, @@ -2909,7 +2839,7 @@ private class ConsoleHostStartupException : Exception base(info, context) { } -#endif + internal ConsoleHostStartupException(string message, Exception innerException) : @@ -2940,33 +2870,15 @@ private class ConsoleHostStartupException : Exception private bool _isDisposed; internal ConsoleHostUserInterface ui; -#if CORECLR internal Lazy ConsoleIn { get; } = new Lazy(() => Console.In); -#else - internal Lazy ConsoleIn { get; } = new Lazy(() => - { - // This is a workaround for a full clr issue that causes a hang when calling PowerShell from ruby. - // They use named pipes instead of anonymous pipes, and for some reason that triggers a hang - // reading from Console.In. - var inputHandle = ConsoleControl.NativeMethods.GetStdHandle(-10); - var s = new FileStream(new ConsoleHandle(inputHandle, false), FileAccess.Read); - - uint codePage = (uint) ConsoleControl.NativeMethods.GetConsoleCP(); - Encoding encoding = Encoding.GetEncoding((int) codePage); - - return TextReader.Synchronized(new StreamReader(s, encoding, false)); - }); -#endif private string _savedWindowTitle = ""; private Version _ver = PSVersionInfo.PSVersion; private int _exitCodeFromRunspace; private bool _noExit = true; - private bool _isCtrlCDisabled; private bool _setShouldExitCalled; private bool _isRunningPromptLoop; private bool _wasInitialCommandEncoded; - private RunspaceConfiguration _configuration; // hostGlobalLock is used to sync public method calls (in case multiple threads call into the host) and access to // state that persists across method calls, like progress data. It's internal because the ui object also @@ -2993,11 +2905,8 @@ private class ConsoleHostStartupException : Exception private static ConsoleHost s_theConsoleHost; - internal static InitialSessionState DefaultInitialSessionState; - - [TraceSource("ConsoleHost", "ConsoleHost subclass of S.M.A.PSHost")] private static PSTraceSource s_tracer = PSTraceSource.GetTracer("ConsoleHost", "ConsoleHost subclass of S.M.A.PSHost"); @@ -3018,31 +2927,30 @@ internal sealed class RunspaceCreationEventArgs : EventArgs /// /// /// - /// /// /// internal RunspaceCreationEventArgs(string initialCommand, bool skipProfiles, bool staMode, - bool importSystemModules, string configurationName, Collection initialCommandArgs) { InitialCommand = initialCommand; SkipProfiles = skipProfiles; +#if STAMODE StaMode = staMode; - ImportSystemModules = importSystemModules; +#endif ConfigurationName = configurationName; InitialCommandArgs = initialCommandArgs; } internal string InitialCommand { get; set; } internal bool SkipProfiles { get; set; } +#if STAMODE internal bool StaMode { get; set; } - internal bool ImportSystemModules { get; set; } +#endif internal string ConfigurationName { get; set; } internal Collection InitialCommandArgs { get; set; } } } // namespace - diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostRawUserInterface.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostRawUserInterface.cs index ff713604d3a..8d90d6af037 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostRawUserInterface.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostRawUserInterface.cs @@ -1,9 +1,7 @@ -#if !UNIX -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +#if !UNIX using System; using System.Management.Automation; @@ -19,13 +17,11 @@ using WORD = System.UInt16; using DWORD = System.UInt32; - - namespace Microsoft.PowerShell { /// /// - /// implementation of RawConsole for powershell.exe + /// implementation of RawConsole for powershell /// /// @@ -131,8 +127,6 @@ public override } } - - /// /// /// See base class @@ -189,8 +183,6 @@ public override } } - - /// /// /// See base class @@ -234,8 +226,6 @@ public override } } - - /// /// /// See base class @@ -303,8 +293,6 @@ public override } } - - /// /// /// See base class @@ -375,8 +363,6 @@ public override } } - - /// /// /// See base class @@ -436,8 +422,6 @@ public override } } - - /// /// /// See base class @@ -570,8 +554,6 @@ public override } } - - /// /// /// See base class @@ -598,8 +580,6 @@ public override } } - - /// /// /// See base class @@ -741,8 +721,7 @@ public override if (((ConsoleControl.InputRecordEventTypes)inputRecords[0].EventType) == ConsoleControl.InputRecordEventTypes.KEY_EVENT) { - Dbg.Assert((inputRecords[0].KeyEvent.KeyDown && inputRecords[0].KeyEvent.RepeatCount != 0) || - !inputRecords[0].KeyEvent.KeyDown, + Dbg.Assert(!inputRecords[0].KeyEvent.KeyDown || inputRecords[0].KeyEvent.RepeatCount != 0, string.Format(CultureInfo.InvariantCulture, "ReadConsoleInput returns a KeyEvent that is KeyDown and RepeatCount 0")); if (inputRecords[0].KeyEvent.RepeatCount == 0) { @@ -789,8 +768,6 @@ public override return keyInfo; } - - private static void KEY_EVENT_RECORDToKeyInfo(ConsoleControl.KEY_EVENT_RECORD keyEventRecord, out KeyInfo keyInfo) @@ -802,8 +779,6 @@ private static keyEventRecord.KeyDown); } - - /// /// /// See base class @@ -827,8 +802,6 @@ public override cachedKeyEvent.RepeatCount = 0; } - - /// /// /// See base class @@ -867,8 +840,7 @@ public override if (((ConsoleControl.InputRecordEventTypes)inputRecords[i].EventType) == ConsoleControl.InputRecordEventTypes.KEY_EVENT) { - Dbg.Assert((inputRecords[i].KeyEvent.KeyDown && inputRecords[i].KeyEvent.RepeatCount != 0) || - !inputRecords[i].KeyEvent.KeyDown, + Dbg.Assert(!inputRecords[i].KeyEvent.KeyDown || inputRecords[i].KeyEvent.RepeatCount != 0, string.Format(CultureInfo.InvariantCulture, "PeekConsoleInput returns a KeyEvent that is KeyDown and RepeatCount 0")); if (inputRecords[i].KeyEvent.KeyDown && inputRecords[i].KeyEvent.RepeatCount == 0) @@ -886,7 +858,6 @@ public override } } - /// /// /// See base class @@ -1006,8 +977,6 @@ public override ConsoleControl.WriteConsoleOutput(handle, origin, contents); } - - /// /// /// If is completely outside of the screen buffer, it's a no-op. @@ -1187,8 +1156,6 @@ public override } } - - /// /// /// See base class. @@ -1273,8 +1240,6 @@ public override return contents; } - - /// /// /// See base class @@ -1388,7 +1353,6 @@ int LengthInBufferCells(string s, int offset) return ConsoleControl.LengthInBufferCells(s, offset, parent.SupportsVirtualTerminal); } - /// /// /// See base class @@ -1425,7 +1389,6 @@ internal void ClearKeyCache() #region helpers - // pass-by-ref for speed. /// /// @@ -1457,7 +1420,6 @@ private static } } - /// /// Get output buffer info /// @@ -1477,8 +1439,6 @@ private static return result; } - - #endregion helpers private ConsoleColor defaultForeground = ConsoleColor.Gray; diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostTranscript.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostTranscript.cs index d331ef66a39..61f56ee1319 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostTranscript.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostTranscript.cs @@ -1,19 +1,13 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.IO; using System.Management.Automation.Host; using System.Management.Automation.Internal; - using Dbg = System.Management.Automation.Diagnostics; - - namespace Microsoft.PowerShell { internal sealed partial @@ -39,7 +33,6 @@ class ConsoleHost } private bool _isTranscribing; - /* internal void StartTranscribing(string transcriptFilename, bool shouldAppend) { @@ -74,8 +67,6 @@ internal void StartTranscribing(string transcriptFilename, bool shouldAppend) */ private string _transcriptFileName = String.Empty; - - internal string StopTranscribing() @@ -113,8 +104,6 @@ internal void StartTranscribing(string transcriptFilename, bool shouldAppend) } } - - internal void WriteToTranscript(string text) @@ -128,11 +117,8 @@ internal void StartTranscribing(string transcriptFilename, bool shouldAppend) } } - - private StreamWriter _transcriptionWriter; private object _transcriptionStateLock = new object(); } } // namespace - diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs index 07b579ae8b9..7c57d9532b4 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.IO; @@ -24,7 +23,7 @@ namespace Microsoft.PowerShell /// /// - /// ConsoleHostUserInterface implements console-mode user interface for powershell.exe + /// ConsoleHostUserInterface implements console-mode user interface for powershell /// /// [SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling")] @@ -128,7 +127,6 @@ public override PSHostRawUserInterface RawUI // } //} - /// /// /// true if command completion is currently running @@ -190,7 +188,6 @@ public override string ReadLine() return ReadLine(false, "", out unused, true, true); } - /// /// /// See base class @@ -452,7 +449,6 @@ private object ReadLineSafe(bool isSecureString, char? printToken) } } - /// /// /// Handle writing print token with proper cursor adjustment for ReadLineSafe @@ -500,8 +496,6 @@ private void WritePrintToken( WriteToConsole(printToken, false); } - - /// /// /// Handle backspace with proper cursor adjustment for ReadLineSafe @@ -548,8 +542,6 @@ private void WriteBackSpace(Coordinates originalCursorPosition) // do nothing if cursorPosition.X is left of screen } - - /// /// Blank out at and move rawui.CursorPosition to /// @@ -561,7 +553,6 @@ private void BlankAtCursor(Coordinates cursorPosition) _rawui.CursorPosition = cursorPosition; } - #if !UNIX /// /// @@ -643,8 +634,6 @@ internal void WriteToConsole(string value, bool transcribeResult) } } - - private void WriteToConsole(ConsoleColor foregroundColor, ConsoleColor backgroundColor, string text) { ConsoleColor fg = RawUI.ForegroundColor; @@ -670,8 +659,6 @@ private void WriteLineToConsole(string text) WriteToConsole(Crlf, true); } - - private void WriteLineToConsole() { WriteToConsole(Crlf, true); @@ -679,8 +666,6 @@ private void WriteLineToConsole() #endregion WriteToConsole - - /// /// /// See base class. @@ -725,8 +710,6 @@ public override void Write(string value) } } - - /// /// /// See base class @@ -775,8 +758,6 @@ public override void Write(ConsoleColor foregroundColor, ConsoleColor background } } - - /// /// /// See base class @@ -808,8 +789,6 @@ public override void WriteLine(string value) #region Word Wrapping - - /// /// /// This is a poor-man's word-wrapping routine. It breaks a single string into segments small enough to fit within a @@ -928,15 +907,12 @@ internal List WrapText(string text, int maxWidthInBufferCells) return result; } - - /// /// /// Struct used by WrapText /// /// - [Flags] internal enum WordFlags { @@ -951,8 +927,6 @@ internal struct Word internal WordFlags Flags; } - - /// /// /// Chops text into "words," where a word is defined to be a sequence of whitespace characters, or a sequence of @@ -1066,8 +1040,6 @@ internal List ChopTextIntoWords(string text, int maxWidthInBufferCells) return result; } - - /// /// /// Helper for ChopTextIntoWords. Takes a span of characters in a string and adds it to the word list, further @@ -1148,44 +1120,6 @@ internal void AddWord(string text, int startIndex, int endIndex, } } - /// - /// - /// Writes text, wrapping a "word" boundaries when needed. - /// - /// - /// - /// - /// Foreground color to output the text. - /// - /// - /// - /// - /// Background color to output the text. - /// - /// - /// - /// - /// Text to be emitted. - /// - /// - - internal void WriteWrappedLine(ConsoleColor fg, ConsoleColor bg, string text) - { - WriteLine(fg, bg, WrapToCurrentWindowWidth(text)); - } - - - - // unused for now. - //internal - //void - //WriteWrappedLine(string text) - //{ - // WriteWrappedLine(RawUI.ForegroundColor, RawUI.BackgroundColor, text); - //} - - - internal string WrapToCurrentWindowWidth(string text) { StringBuilder sb = new StringBuilder(); @@ -1207,11 +1141,7 @@ internal string WrapToCurrentWindowWidth(string text) return sb.ToString(); } - - - #endregion Word Wrapping - - +#endregion Word Wrapping /// /// @@ -1248,7 +1178,7 @@ public override void WriteDebugLine(string message) else { // NTRAID#Windows OS Bugs-1061752-2004/12/15-sburns should read a skin setting here... - WriteWrappedLine( + WriteLine( DebugForegroundColor, DebugBackgroundColor, StringUtil.Format(ConsoleHostUserInterfaceStrings.DebugFormatString, message)); @@ -1309,14 +1239,13 @@ public override void WriteVerboseLine(string message) } else { - WriteWrappedLine( + WriteLine( VerboseForegroundColor, VerboseBackgroundColor, StringUtil.Format(ConsoleHostUserInterfaceStrings.VerboseFormatString, message)); } } - /// /// /// See base class @@ -1352,7 +1281,7 @@ public override void WriteWarningLine(string message) } else { - WriteWrappedLine( + WriteLine( WarningForegroundColor, WarningBackgroundColor, StringUtil.Format(ConsoleHostUserInterfaceStrings.WarningFormatString, message)); @@ -1398,8 +1327,6 @@ public override void WriteProgress(Int64 sourceId, ProgressRecord record) } } - - public override void WriteErrorLine(string value) { if (string.IsNullOrEmpty(value)) @@ -1450,11 +1377,8 @@ public override void WriteErrorLine(string value) #endregion Line-oriented interaction - #region implementation - - // We use System.Environment.NewLine because we are platform-agnostic internal static string Crlf = System.Environment.NewLine; @@ -1928,7 +1852,6 @@ private char GetCharacterUnderCursor(Coordinates cursorPosition) } #endif - /// /// Strip nulls from a string... /// @@ -1947,7 +1870,6 @@ private string RemoveNulls(string input) return sb.ToString(); } - /// /// /// Reads a line, and completes the input for the user if they hit tab. diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfaceProgress.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfaceProgress.cs index d070a4ed14f..d8b19a68812 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfaceProgress.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfaceProgress.cs @@ -1,15 +1,11 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; using Dbg = System.Management.Automation.Diagnostics; using System.Threading; - namespace Microsoft.PowerShell { internal partial @@ -55,8 +51,6 @@ class ConsoleHostUserInterface : System.Management.Automation.Host.PSHostUserInt } } - - /// /// /// Invoked by ConsoleHostUserInterface.WriteProgress to update the set of outstanding activities for which @@ -106,8 +100,6 @@ class ConsoleHostUserInterface : System.Management.Automation.Host.PSHostUserInt } } - - /// /// /// TimerCallback for '_progPaneUpdateTimer' to update 'progPaneUpdateFlag' @@ -131,8 +123,6 @@ class ConsoleHostUserInterface : System.Management.Automation.Host.PSHostUserInt } } - - private void PostWrite() @@ -143,8 +133,6 @@ class ConsoleHostUserInterface : System.Management.Automation.Host.PSHostUserInt } } - - private void PostWrite(string value) @@ -164,8 +152,6 @@ class ConsoleHostUserInterface : System.Management.Automation.Host.PSHostUserInt } } - - private void PreRead() @@ -176,8 +162,6 @@ class ConsoleHostUserInterface : System.Management.Automation.Host.PSHostUserInt } } - - private void PostRead() @@ -188,8 +172,6 @@ class ConsoleHostUserInterface : System.Management.Automation.Host.PSHostUserInt } } - - private void PostRead(string value) @@ -210,8 +192,6 @@ class ConsoleHostUserInterface : System.Management.Automation.Host.PSHostUserInt } } - - private ProgressPane _progPane = null; private PendingProgress _pendingProgress = null; // The timer set up 'progPaneUpdateFlag' every 'UpdateTimerThreshold' milliseconds to update 'ProgressPane' @@ -221,5 +201,3 @@ class ConsoleHostUserInterface : System.Management.Automation.Host.PSHostUserInt } } // namespace - - diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfacePrompt.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfacePrompt.cs index c740be6c61c..97ae10731d3 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfacePrompt.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfacePrompt.cs @@ -1,8 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Globalization; @@ -17,8 +14,6 @@ using Dbg = System.Management.Automation.Diagnostics; using InternalHostUserInterface = System.Management.Automation.Internal.Host.InternalHostUserInterface; - - namespace Microsoft.PowerShell { internal partial @@ -44,8 +39,6 @@ private enum PromptCommonInputErrors Overflow } - - private static bool AtLeastOneHelpMessageIsPresent(Collection descriptions) @@ -64,8 +57,6 @@ private static return false; } - - /// /// /// See base class @@ -315,31 +306,12 @@ out object convertedObj { WriteLineToConsole(WrapToCurrentWindowWidth(fieldPrompt)); PSCredential credential = null; - // the earlier implementation contained null - // for caption and message in the call below - // Passing null is a potential security risk - // as any modifications made with security in - // mind is lost. This can lead to a malicious - // server prompting the user for a request - // which can appear to come from locally. - if (!PromptUsingConsole() && desc.ModifiedByRemotingProtocol) - { - credential = - PromptForCredential( - caption, - message, - null, - string.Empty); - } - else - { - credential = - PromptForCredential( - null, // caption already written - null, // message already written - null, - string.Empty); - } + credential = + PromptForCredential( + null, // caption already written + null, // message already written + null, + string.Empty); convertedObj = credential; cancelInput = (convertedObj == null); if ((credential != null) && (credential.Password.Length == 0) && listInput) diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfacePromptForChoice.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfacePromptForChoice.cs index 7e76e37fff1..719d489904c 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfacePromptForChoice.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfacePromptForChoice.cs @@ -1,8 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Globalization; diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfaceSecurity.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfaceSecurity.cs index 10e6cacfca7..8501bffec35 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfaceSecurity.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfaceSecurity.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Security; @@ -13,7 +12,7 @@ namespace Microsoft.PowerShell { /// /// - /// ConsoleHostUserInterface implements console-mode user interface for powershell.exe + /// ConsoleHostUserInterface implements console-mode user interface for powershell /// /// internal partial @@ -78,127 +77,61 @@ public override PSCredential PromptForCredential( PSCredentialTypes allowedCredentialTypes, PSCredentialUIOptions options) { - if (!PromptUsingConsole()) - { - IntPtr mainWindowHandle = GetMainWindowHandle(); - return HostUtilities.CredUIPromptForCredential(caption, message, userName, targetName, allowedCredentialTypes, options, mainWindowHandle); - } - else - { - PSCredential cred = null; - SecureString password = null; - string userPrompt = null; - string passwordPrompt = null; - - if (!string.IsNullOrEmpty(caption)) - { - // Should be a skin lookup + PSCredential cred = null; + SecureString password = null; + string userPrompt = null; + string passwordPrompt = null; - WriteLineToConsole(); - WriteToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(caption)); - WriteLineToConsole(); - } - - if (!string.IsNullOrEmpty(message)) - { - WriteLineToConsole(WrapToCurrentWindowWidth(message)); - } + if (!string.IsNullOrEmpty(caption)) + { + // Should be a skin lookup - if (string.IsNullOrEmpty(userName)) - { - userPrompt = ConsoleHostUserInterfaceSecurityResources.PromptForCredential_User; + WriteLineToConsole(); + WriteToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(caption)); + WriteLineToConsole(); + } - // - // need to prompt for user name first - // - do - { - WriteToConsole(userPrompt, true); - userName = ReadLine(); - if (userName == null) - { - return null; - } - } - while (userName.Length == 0); - } + if (!string.IsNullOrEmpty(message)) + { + WriteLineToConsole(WrapToCurrentWindowWidth(message)); + } - passwordPrompt = StringUtil.Format(ConsoleHostUserInterfaceSecurityResources.PromptForCredential_Password, userName - ); + if (string.IsNullOrEmpty(userName)) + { + userPrompt = ConsoleHostUserInterfaceSecurityResources.PromptForCredential_User; // - // now, prompt for the password + // need to prompt for user name first // - WriteToConsole(passwordPrompt, true); - password = ReadLineAsSecureString(); - if (password == null) + do { - return null; + WriteToConsole(userPrompt, true); + userName = ReadLine(); + if (userName == null) + { + return null; + } } - WriteLineToConsole(); - - cred = new PSCredential(userName, password); - - return cred; + while (userName.Length == 0); } - } - private IntPtr GetMainWindowHandle() - { -#if CORECLR // No System.Diagnostics.Process.MainWindowHandle on CoreCLR; - // Returned WindowHandle is used only in 1 case - prompting for credential using GUI dialog, which is not used on Nano, - // because on Nano we prompt for credential using console (different code path in 'PromptForCredential' function) - return IntPtr.Zero; -#else - System.Diagnostics.Process currentProcess = System.Diagnostics.Process.GetCurrentProcess(); - IntPtr mainWindowHandle = currentProcess.MainWindowHandle; + passwordPrompt = StringUtil.Format(ConsoleHostUserInterfaceSecurityResources.PromptForCredential_Password, userName + ); - while ((mainWindowHandle == IntPtr.Zero) && (currentProcess != null)) + // + // now, prompt for the password + // + WriteToConsole(passwordPrompt, true); + password = ReadLineAsSecureString(); + if (password == null) { - currentProcess = PsUtils.GetParentProcess(currentProcess); - if (currentProcess != null) - { - mainWindowHandle = currentProcess.MainWindowHandle; - } + return null; } + WriteLineToConsole(); - return mainWindowHandle; -#endif - } - - // Determines whether we should prompt using the Console prompting - // APIs - private bool PromptUsingConsole() - { -#if CORECLR - // on Nano there is no other way to prompt except by using console - return true; -#else - bool promptUsingConsole = false; - // Get the configuration setting - try - { - promptUsingConsole = ConfigPropertyAccessor.Instance.GetConsolePrompting(); - } - catch (System.Security.SecurityException e) - { - s_tracer.TraceError("Could not read CredUI registry key: " + e.Message); - return promptUsingConsole; - } - catch (InvalidCastException e) - { - s_tracer.TraceError("Could not parse CredUI registry key: " + e.Message); - return promptUsingConsole; - } - catch (FormatException e) - { - s_tracer.TraceError("Could not parse CredUI registry key: " + e.Message); - return promptUsingConsole; - } + cred = new PSCredential(userName, password); - s_tracer.WriteLine("DetermineCredUIPolicy: policy == {0}", promptUsingConsole); - return promptUsingConsole; -#endif + return cred; } } } diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleShell.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleShell.cs index 227ee91abaf..ec3b1044b62 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleShell.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleShell.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Management.Automation; using System.Management.Automation.Runspaces; @@ -15,74 +14,19 @@ namespace Microsoft.PowerShell public static class ConsoleShell { -#if CORECLR /// Entry point in to ConsoleShell. This method is called by main of minishell. /// Banner text to be displayed by ConsoleHost /// Help text for minishell. This is displayed on 'minishell -?'. /// Commandline parameters specified by user. /// An integer value which should be used as exit code for the process. public static int Start(string bannerText, string helpText, string[] args) - { - return Start(null, bannerText, helpText, null, args); - } -#else - /// Entry point in to ConsoleShell. This method is called by main of minishell. - /// Configuration information which is used to create Runspace. - /// Banner text to be displayed by ConsoleHost - /// Help text for minishell. This is displayed on 'minishell -?'. - /// Commandline parameters specified by user. - /// An integer value which should be used as exit code for the process. - public static int Start(RunspaceConfiguration configuration, string bannerText, string helpText, string[] args) - { - return Start(configuration, bannerText, helpText, null, args); - } -#endif - - /// - /// - /// Entry point in to ConsoleShell. This method is called from the native or managed exe host application - /// - /// - /// - /// Configuration information which is used to create Runspace. - /// - /// - /// - /// Banner text to be displayed by ConsoleHost - /// - /// - /// - /// Help text for minishell. This is displayed on 'minishell -?'. - /// - /// - /// - /// Warning occurred prior to this point, for example, a snap-in fails to load beforehand. - /// This string will be printed out. - /// - /// - /// - /// Commandline parameters specified by user. - /// - /// - /// - /// An integer value which should be used as exit code for the - /// process. - /// - - internal static - int - Start(RunspaceConfiguration configuration, - string bannerText, - string helpText, - string preStartWarning, - string[] args) { if (args == null) { throw PSTraceSource.NewArgumentNullException("args"); } - return ConsoleHost.Start(configuration, bannerText, helpText, preStartWarning, args); + return ConsoleHost.Start(bannerText, helpText, args); } } } diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleTextWriter.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleTextWriter.cs index bb60e390be8..cc4cebebc3f 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleTextWriter.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleTextWriter.cs @@ -1,8 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Text; @@ -13,8 +10,6 @@ using DWORD = System.UInt32; using NakedWin32Handle = System.IntPtr; - - namespace Microsoft.PowerShell { internal @@ -30,8 +25,6 @@ class ConsoleTextWriter : TextWriter _ui = ui; } - - public override Encoding Encoding @@ -42,8 +35,6 @@ public override } } - - public override void Write(string value) @@ -51,8 +42,6 @@ public override _ui.WriteToConsole(value, true); } - - public override void WriteLine(string value) @@ -60,8 +49,6 @@ public override this.Write(value + ConsoleHostUserInterface.Crlf); } - - public override void Write(Boolean b) @@ -69,8 +56,6 @@ public override this.Write(b.ToString()); } - - public override void Write(Char c) @@ -78,8 +63,6 @@ public override this.Write(new String(c, 1)); } - - public override void Write(Char[] a) @@ -87,10 +70,7 @@ public override this.Write(new String(a)); } - - private ConsoleHostUserInterface _ui; } } // namespace - diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/Executor.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/Executor.cs index d071663ce43..c8cdc9068fe 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/Executor.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/Executor.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.ObjectModel; @@ -91,8 +90,6 @@ private void OutputObjectStreamHandler(object sender, EventArgs e) } } - - // called on the pipeline thread private void ErrorObjectStreamHandler(object sender, EventArgs e) @@ -114,7 +111,6 @@ private void ErrorObjectStreamHandler(object sender, EventArgs e) } } - /// /// This method handles the failure in executing pipeline asynchronously /// @@ -425,7 +421,6 @@ internal Collection ExecuteCommandHelper(Pipeline tempPipeline, out Ex return results; } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Needed by ProfileTests as mentioned in bug 140572")] internal Collection ExecuteCommand(string command) { diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ManagedEntrance.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ManagedEntrance.cs index 380fa7e0d41..85288357b27 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ManagedEntrance.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ManagedEntrance.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Reflection; @@ -23,7 +22,7 @@ public sealed class UnmanagedPSEntry /// Starts managed MSH /// /// - /// Console file used to create a runspace configuration to start MSH + /// Deprecated: Console file used to create a runspace configuration to start MSH /// /// /// Command line arguments to the managed MSH @@ -34,16 +33,11 @@ public static int Start(string consoleFilePath, [MarshalAs(UnmanagedType.LPArray { System.Management.Automation.Runspaces.EarlyStartup.Init(); - // Set ETW activity Id - Guid activityId = EtwActivity.GetActivityId(); - - if (activityId == Guid.Empty) - { - EtwActivity.SetActivityId(EtwActivity.CreateActivityId()); - } - - PSEtwLog.LogOperationalInformation(PSEventId.Perftrack_ConsoleStartupStart, PSOpcode.WinStart, - PSTask.PowershellConsoleStartup, PSKeyword.UseAlwaysOperational); +#if !UNIX + // NOTE: On Unix, logging has to be deferred until after command-line parsing + // complete. On Windows, deferring the call is not needed. + PSEtwLog.LogConsoleStartup(); +#endif // Windows Vista and later support non-traditional UI fallback ie., a // user on an Arabic machine can choose either French or English(US) as @@ -55,54 +49,26 @@ public static int Start(string consoleFilePath, [MarshalAs(UnmanagedType.LPArray Thread.CurrentThread.CurrentUICulture = NativeCultureResolver.UICulture; Thread.CurrentThread.CurrentCulture = NativeCultureResolver.Culture; - RunspaceConfigForSingleShell configuration = null; - PSConsoleLoadException warning = null; - // PSSnapInException will cause the control to return back to the native code - // and stuff the EXCEPINFO field with the message of the exception. - // The native code will print this out and exit the process. - if (string.IsNullOrEmpty(consoleFilePath)) - { #if DEBUG -// Special switches for debug mode to allow self-hosting on InitialSessionState instead -// of runspace configuration... - if (args.Length > 0 && !String.IsNullOrEmpty(args[0]) && args[0].Equals("-iss", StringComparison.OrdinalIgnoreCase)) - { - ConsoleHost.DefaultInitialSessionState = InitialSessionState.CreateDefault2(); - configuration = null; - } - else if (args.Length > 0 && !String.IsNullOrEmpty(args[0]) && args[0].Equals("-isswait", StringComparison.OrdinalIgnoreCase)) - { - Console.WriteLine("Attach the debugger and hit enter to continue:"); - Console.ReadLine(); - ConsoleHost.DefaultInitialSessionState = InitialSessionState.CreateDefault2(); - configuration = null; - } - else - { - ConsoleHost.DefaultInitialSessionState = InitialSessionState.CreateDefault2(); - configuration = null; - } -#else - ConsoleHost.DefaultInitialSessionState = InitialSessionState.CreateDefault2(); - configuration = null; -#endif - } - else + if (args.Length > 0 && !String.IsNullOrEmpty(args[0]) && args[0].Equals("-isswait", StringComparison.OrdinalIgnoreCase)) { - //TODO : Deprecate RunspaceConfiguration and use InitialSessionState - configuration = - RunspaceConfigForSingleShell.Create(consoleFilePath, out warning); + Console.WriteLine("Attach the debugger to continue..."); + while (!System.Diagnostics.Debugger.IsAttached) { + Thread.Sleep(100); + } + System.Diagnostics.Debugger.Break(); } +#endif + ConsoleHost.DefaultInitialSessionState = InitialSessionState.CreateDefault2(); + int exitCode = 0; try { var banner = ManagedEntranceStrings.ShellBannerNonWindowsPowerShell; var formattedBanner = string.Format(CultureInfo.InvariantCulture, banner, PSVersionInfo.GitCommitId); exitCode = Microsoft.PowerShell.ConsoleShell.Start( - configuration, formattedBanner, - ManagedEntranceStrings.ShellHelp, - warning == null ? null : warning.Message, + ManagedEntranceStrings.UsageHelp, args); } catch (System.Management.Automation.Host.HostException e) diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/PendingProgress.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/PendingProgress.cs index d383743757c..d4a6ae51ca5 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/PendingProgress.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/PendingProgress.cs @@ -1,8 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections; @@ -12,7 +9,6 @@ using Dbg = System.Management.Automation.Diagnostics; - namespace Microsoft.PowerShell { /// @@ -157,8 +153,6 @@ class PendingProgress AgeNodesAndResetStyle(); } - - private void EvictNode() @@ -183,7 +177,6 @@ class PendingProgress } } - /// /// /// Removes a node from the tree. @@ -221,7 +214,6 @@ class PendingProgress #endif } - private void RemoveNodeAndPromoteChildren(ArrayList nodes, int indexToRemove) @@ -267,8 +259,6 @@ class PendingProgress } } - - /// /// /// Adds a node to the tree, first removing the oldest node if the tree is too large. @@ -298,8 +288,6 @@ class PendingProgress #endif } - - private class FindOldestNodeVisitor : NodeVisitor { @@ -318,30 +306,21 @@ internal override return true; } - - internal ProgressNode FoundNode; - - internal ArrayList ListWhereFound; - - internal int IndexWhereFound = -1; - private int _oldestSoFar; } - - private ProgressNode FindOldestLeafmostNodeHelper(ArrayList treeToSearch, out ArrayList listWhereFound, out int indexWhereFound) @@ -367,7 +346,6 @@ internal override return v.FoundNode; } - private ProgressNode FindOldestLeafmostNode(out ArrayList listWhereFound, out int indexWhereFound) @@ -394,8 +372,6 @@ internal override return result; } - - /// /// /// Convenience overload. @@ -412,8 +388,6 @@ internal override FindNodeById(sourceId, activityId, out listWhereFound, out indexWhereFound); } - - private class FindByIdNodeVisitor : NodeVisitor { @@ -424,8 +398,6 @@ class FindByIdNodeVisitor : NodeVisitor _idToFind = activityIdToFind; } - - internal override bool Visit(ProgressNode node, ArrayList listWhereFound, int indexWhereFound) @@ -440,32 +412,22 @@ internal override return true; } - - internal ProgressNode FoundNode; - - internal ArrayList ListWhereFound; - - internal int IndexWhereFound = -1; - - private int _idToFind = -1; private Int64 _sourceIdToFind; } - - /// /// /// Finds a node with a given ActivityId in provided set of nodes. Recursively walks the set of nodes and their children. @@ -521,8 +483,6 @@ internal override return v.FoundNode; } - - /// /// /// Finds the oldest node with a given rendering style that is at least as old as a given age. @@ -593,8 +553,6 @@ internal override return found; } - - private class AgeAndResetStyleVisitor : NodeVisitor { @@ -608,8 +566,6 @@ internal override } } - - /// /// /// Increments the age of each of the nodes in the given list, and all their children. Also sets the rendering @@ -627,14 +583,10 @@ internal override NodeVisitor.VisitNodes(_topLevelNodes, arsv); } - - #endregion // Updating Code #region Rendering Code - - /// /// /// Generates an array of strings representing as much of the outstanding progress activities as possible within the given @@ -715,8 +667,6 @@ internal override return (string[])result.ToArray(typeof(string)); } - - /// /// /// Helper function for Render(). Recursively renders nodes. @@ -777,8 +727,6 @@ internal override } } - - private class HeightTallyer : NodeVisitor { @@ -845,7 +793,6 @@ private int TallyHeight(PSHostRawUserInterface rawUi, int maxHeight, int maxWidt return ht.Tally; } - #if DEBUG || ASSERTIONS_TRACE /// @@ -887,8 +834,6 @@ private int TallyHeight(PSHostRawUserInterface rawUi, int maxHeight, int maxWidt return true; } - - /// /// /// Debugging code. NodeVisitor that counts up the number of nodes in the tree. @@ -912,8 +857,6 @@ internal override Count; } - - /// /// /// Debugging code. Counts the number of nodes in the tree of nodes. @@ -936,7 +879,6 @@ internal override #endif - /// /// /// Helper function to CompressToFit. Considers compressing nodes from one level to another. @@ -1030,8 +972,6 @@ internal override return false; } - - /// /// /// "Compresses" the nodes representing the outstanding progress activities until their rendering will fit within a @@ -1130,15 +1070,10 @@ internal override return 0; } - - - #endregion // Rendering Code #region Utility Code - - private abstract class NodeVisitor { @@ -1199,16 +1134,11 @@ internal static } } - #endregion - - private ArrayList _topLevelNodes = new ArrayList(); private int _nodeCount; private const int maxNodeCount = 128; } } // namespace - - diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ProgressNode.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ProgressNode.cs index d11e78431da..2529c31927b 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ProgressNode.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ProgressNode.cs @@ -1,8 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections; @@ -12,7 +9,6 @@ using Dbg = System.Management.Automation.Diagnostics; - namespace Microsoft.PowerShell { /// @@ -52,8 +48,6 @@ namespace Microsoft.PowerShell FullPlus = 4, }; - - /// /// /// Constructs an instance from a ProgressRecord. @@ -76,8 +70,6 @@ namespace Microsoft.PowerShell this.SourceId = sourceId; } - - /// /// /// Renders a single progress node as strings of text according to that node's style. The text is appended to the @@ -340,8 +332,6 @@ private static void RenderFullDescription(string description, string indent, int } } - - /// /// /// Renders a node in the "Minimal" style. @@ -402,8 +392,6 @@ private static void RenderFullDescription(string description, string indent, int maxWidth)); } - - /// /// /// The nodes that have this node as their parent. @@ -414,8 +402,6 @@ private static void RenderFullDescription(string description, string indent, int ArrayList Children; - - /// /// /// The "age" of the node. A node's age is incremented by PendingProgress.Update each time a new ProgressRecord is @@ -433,8 +419,6 @@ private static void RenderFullDescription(string description, string indent, int int Age; - - /// /// /// The style in which this node should be rendered. @@ -445,8 +429,6 @@ private static void RenderFullDescription(string description, string indent, int RenderStyle Style = RenderStyle.FullPlus; - - /// /// /// Identifies the source of the progress record. @@ -457,7 +439,6 @@ private static void RenderFullDescription(string description, string indent, int Int64 SourceId; - /// /// /// The number of vertical BufferCells that are required to render the node in its current style. @@ -494,7 +475,6 @@ internal int LinesRequiredMethod(PSHostRawUserInterface rawUi, int maxWidth) return 0; } - /// /// /// The number of vertical BufferCells that are required to render the node in the Full style. @@ -553,7 +533,6 @@ private int LinesRequiredInFullStyleMethod(PSHostRawUserInterface rawUi, int max return lines; } - /// /// /// The number of vertical BufferCells that are required to render the node in the Compact style. @@ -586,4 +565,3 @@ private int LinesRequiredInFullStyleMethod(PSHostRawUserInterface rawUi, int max } } // namespace - diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ProgressPane.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ProgressPane.cs index e9b0ed1d692..922aad8f174 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ProgressPane.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ProgressPane.cs @@ -1,15 +1,11 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation.Host; using Dbg = System.Management.Automation.Diagnostics; - namespace Microsoft.PowerShell { /// @@ -41,8 +37,6 @@ class ProgressPane _rawui = ui.RawUI; } - - /// /// /// Indicates whether the pane is visible on the screen buffer or not. @@ -64,8 +58,6 @@ class ProgressPane } } - - /// /// /// Shows the pane in the screen buffer. Saves off the content of the region of the buffer that will be overwritten so @@ -149,8 +141,6 @@ class ProgressPane } } - - /// /// /// Hides the pane by restoring the saved contents of the region of the buffer that the pane occupies. If the pane is @@ -175,8 +165,6 @@ class ProgressPane } } - - /// /// /// Updates the pane with the rendering of the supplied PendingProgress, and shows it. @@ -257,8 +245,6 @@ class ProgressPane } } - - private Coordinates _location = new Coordinates(0, 0); private Coordinates _savedCursor; private Size _bufSize; @@ -269,6 +255,3 @@ class ProgressPane } } // namespace - - - diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/Serialization.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/Serialization.cs index f73c26107f0..760570099cb 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/Serialization.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/Serialization.cs @@ -1,17 +1,13 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.IO; using System.Management.Automation; using System.Xml; - using Dbg = System.Management.Automation.Diagnostics; - - namespace Microsoft.PowerShell { /// @@ -56,8 +52,6 @@ internal enum DataFormat None = 2 } - - protected Serialization(DataFormat dataFormat, string streamName) { @@ -67,16 +61,12 @@ internal enum DataFormat this.streamName = streamName; } - - protected static string XmlCliTag = "#< CLIXML"; protected string streamName; protected DataFormat format; } - - internal class WrappedSerializer : Serialization { @@ -106,8 +96,6 @@ class WrappedSerializer : Serialization } } - - internal void Serialize(object o) @@ -138,7 +126,6 @@ class WrappedSerializer : Serialization } } - internal void End() @@ -162,15 +149,12 @@ class WrappedSerializer : Serialization } } - internal TextWriter textWriter; private XmlWriter _xmlWriter; private Serializer _xmlSerializer; private bool _firstCall = true; } - - internal class WrappedDeserializer : Serialization { @@ -208,8 +192,6 @@ class WrappedDeserializer : Serialization } } - - internal object Deserialize() @@ -250,8 +232,6 @@ class WrappedDeserializer : Serialization return o; } - - internal bool AtEnd @@ -279,8 +259,6 @@ class WrappedDeserializer : Serialization } } - - internal void End() @@ -297,7 +275,6 @@ class WrappedDeserializer : Serialization } } - internal TextReader textReader; private XmlReader _xmlReader; private Deserializer _xmlDeserializer; @@ -306,4 +283,3 @@ class WrappedDeserializer : Serialization } } // namespace - diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/StartTranscriptCmdlet.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/StartTranscriptCmdlet.cs index 7a99f62091e..06009b22d2a 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/StartTranscriptCmdlet.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/StartTranscriptCmdlet.cs @@ -1,8 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.ObjectModel; @@ -10,7 +7,6 @@ using System.Management.Automation; using System.Management.Automation.Internal; - namespace Microsoft.PowerShell.Commands { /// @@ -147,7 +143,6 @@ public SwitchParameter IncludeInvocationHeader get; set; } - /// /// /// Starts the transcription @@ -344,5 +339,3 @@ private void ReportMultipleFilesNotSupported() } } - - diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/StopTranscriptCmdlet.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/StopTranscriptCmdlet.cs index a856759b607..fa60872b01f 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/StopTranscriptCmdlet.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/StopTranscriptCmdlet.cs @@ -1,14 +1,10 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; using System.Management.Automation.Internal; - namespace Microsoft.PowerShell.Commands { /// @@ -49,6 +45,3 @@ protected override } } } - - - diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/Telemetry.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/Telemetry.cs index 58987b322a3..4548d3b8145 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/Telemetry.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/Telemetry.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using Microsoft.ApplicationInsights; using Microsoft.ApplicationInsights.DataContracts; @@ -16,16 +19,8 @@ namespace Microsoft.PowerShell /// internal static class ApplicationInsightsTelemetry { - // The semaphore file which indicates whether telemetry should be sent - // This is temporary code waiting on the acceptance and implementation of the configuration spec - // The name of the file by when present in $PSHOME will enable telemetry. - // If this file is not present, no telemetry will be sent. - private const string TelemetrySemaphoreFilename = "DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY"; - - // The path to the semaphore file which enables telemetry - private static string TelemetrySemaphoreFilePath = Path.Combine( - Utils.DefaultPowerShellAppBase, - TelemetrySemaphoreFilename); + // If this env var is true, yes, or 1, telemetry will NOT be sent. + private const string TelemetryOptoutEnvVar = "POWERSHELL_TELEMETRY_OPTOUT"; // Telemetry client to be reused when we start sending more telemetry private static TelemetryClient _telemetryClient = null; @@ -42,6 +37,28 @@ static ApplicationInsightsTelemetry() TelemetryConfiguration.Active.TelemetryChannel.DeveloperMode = _developerMode; } + private static bool GetEnvironmentVariableAsBool(string name, bool defaultValue) { + var str = Environment.GetEnvironmentVariable(name); + if (string.IsNullOrEmpty(str)) + { + return defaultValue; + } + + switch (str.ToLowerInvariant()) + { + case "true": + case "1": + case "yes": + return true; + case "false": + case "0": + case "no": + return false; + default: + return defaultValue; + } + } + /// /// Send the telemetry /// @@ -49,15 +66,18 @@ private static void SendTelemetry(string eventName, Dictionarypay { try { - // if the semaphore file exists, try to send telemetry - if (Utils.NativeFileExists(TelemetrySemaphoreFilePath)) + var enabled = !GetEnvironmentVariableAsBool(name : TelemetryOptoutEnvVar, defaultValue : false); + + if (!enabled) + { + return; + } + + if (_telemetryClient == null) { - if ( _telemetryClient == null ) - { - _telemetryClient = new TelemetryClient(); - } - _telemetryClient.TrackEvent(eventName, payload, null); + _telemetryClient = new TelemetryClient(); } + _telemetryClient.TrackEvent(eventName, payload, null); } catch (Exception) { diff --git a/src/Microsoft.PowerShell.ConsoleHost/resources/CommandLineParameterParserStrings.resx b/src/Microsoft.PowerShell.ConsoleHost/resources/CommandLineParameterParserStrings.resx index 7ad30993383..8c6eda44cac 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/resources/CommandLineParameterParserStrings.resx +++ b/src/Microsoft.PowerShell.ConsoleHost/resources/CommandLineParameterParserStrings.resx @@ -186,7 +186,22 @@ Cannot process the command because -Configuration requires an argument that is a remote endpoint configuration name. Specify this argument and try again. + + Cannot process the command because -SettingsFile requires an argument that is a file path. + + + Processing -SettingsFile '{0}' failed: {1}. Specify a valid path for the -SettingsFile parameter. + + + The argument '{0}' passed to the -SettingsFile does not exist. Provide the path to an existing json file as an argument to the -SettingsFile parameter. + Invalid argument '{0}', did you mean: + + Parameter -WindowStyle is not implemented on this platform. + + + Cannot process the command because -WorkingDirectory requires an argument that is a directory path. + diff --git a/src/Microsoft.PowerShell.ConsoleHost/resources/ManagedEntranceStrings.resx b/src/Microsoft.PowerShell.ConsoleHost/resources/ManagedEntranceStrings.resx index 81021421024..72ae00245d9 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/resources/ManagedEntranceStrings.resx +++ b/src/Microsoft.PowerShell.ConsoleHost/resources/ManagedEntranceStrings.resx @@ -119,22 +119,29 @@ PowerShell {0} -Copyright (C) Microsoft Corporation. All rights reserved. - - - Usage: powershell[.exe] [[-File] <filePath> [args]] - [-Command { - | <script-block> [-args <arg-array>] - | <string> [<CommandParameters>] } ] - [-ConfigurationName <string>] [-EncodedCommand <Base64EncodedCommand>] - [-ExecutionPolicy <ExecutionPolicy>] [-InputFormat {Text | XML}] - [-Interactive] [-NoExit] [-NoLogo] [-NonInteractive] [-NoProfile] - [-OutputFormat {Text | XML}] [-Version] [-WindowStyle <style>] +Copyright (c) Microsoft Corporation. All rights reserved. - powershell[.exe] -h | -Help | -? | /? +https://aka.ms/pscore6-docs +Type 'help' to get help. + + + Usage: pwsh[.exe] [[-File] <filePath> [args]] + [-Command { - | <script-block> [-args <arg-array>] + | <string> [<CommandParameters>] } ] + [-ConfigurationName <string>] [-EncodedCommand <Base64EncodedCommand>] + [-ExecutionPolicy <ExecutionPolicy>] [-InputFormat {Text | XML}] + [-Interactive] [-NoExit] [-NoLogo] [-NonInteractive] [-NoProfile] + [-OutputFormat {Text | XML}] [-Version] [-WindowStyle <style>] + [-WorkingDirectory <directoryPath>] + + pwsh[.exe] -h | -Help | -? | /? PowerShell Online Help https://aka.ms/pscore6-docs -All parameters are case-insensitive. +All parameters are case-insensitive. + + + -Command | -c Executes the specified commands (and any parameters) as though they were typed @@ -144,8 +151,8 @@ All parameters are case-insensitive. If the value of Command is "-", the command text is read from standard input. If the value of Command is a script block, the script block must be enclosed - in braces ({}). You can specify a script block only when running 'powershell' - in PowerShell. The results of the script block are returned to the + in braces ({}). You can specify a script block only when running 'pwsh' + in a PowerShell session. The results of the script block are returned to the parent shell as deserialized XML objects, not live objects. If the value of Command is a string, Command must be the last parameter in the command, @@ -157,15 +164,15 @@ All parameters are case-insensitive. causes the command to be executed. Example: - powershell -Command {Get-WinEvent -LogName security} - powershell -command "& {Get-WinEvent -LogName security}" + pwsh -Command {Get-WinEvent -LogName security} + pwsh -command "& {Get-WinEvent -LogName security}" -ConfigurationName | -config Specifies a configuration endpoint in which PowerShell is run. This can be any endpoint registered on the local machine including the default PowerShell remoting endpoints or a custom endpoint having specific user role capabilities. - Example: powershell -configurationmame AdminRoles + Example: pwsh -ConfigurationName AdminRoles -EncodedCommand | -e | -ec Accepts a base64 encoded string version of a command. Use this parameter to submit @@ -175,7 +182,7 @@ All parameters are case-insensitive. $command = 'dir "c:\program files" ' $bytes = [System.Text.Encoding]::Unicode.GetBytes($command) $encodedCommand = [Convert]::ToBase64String($bytes) - powershell -encodedcommand $encodedCommand + pwsh -encodedcommand $encodedCommand -ExecutionPolicy | -ex | -ep Sets the default execution policy for the current session and saves it @@ -183,7 +190,7 @@ All parameters are case-insensitive. This parameter does not change the PowerShell execution policy that is set in the registry. - Example: powershell -ExecutionPolicy RemoteSigned + Example: pwsh -ExecutionPolicy RemoteSigned -File | -f Default parameter if no parameters is present but any values is present in the command line. @@ -193,12 +200,10 @@ All parameters are case-insensitive. in the command, because all characters typed after the File parameter name are interpreted as the script file path followed by the script parameters. - Example: powershell HelloWorld.ps1 + Example: pwsh HelloWorld.ps1 -Help | -h | -? | /? - Shows this message. If you are typing a 'powershell' command in PowerShell on Windows - system, prepend the command parameters with a hyphen (-), not a forward slash (/). - You can use either a hyphen or forward slash in Cmd.exe. + Shows this help message. -InputFormat | -in | -if Describes the format of data sent to PowerShell. @@ -210,7 +215,7 @@ All parameters are case-insensitive. -NoExit | -noe Does not exit after running startup commands. - Example: powershell.exe -NoExit -Command Get-Date + Example: pwsh -NoExit -Command Get-Date -NoLogo | -nol Hides the copyright banner at startup. @@ -226,15 +231,31 @@ All parameters are case-insensitive. are "Text" (text strings) or "XML" (serialized CLIXML format). Default is "Text". - Example: powershell -o XML -c Get-Date + Example: pwsh -o XML -c Get-Date + +-SettingsFile | -settings + Overrides the system-wide powershell.config.json settings file for the session. + By default, system-wide settings are read from the powershell.config.json + in the $PSHOME directory. + + Note that these settings are not used by the endpoint specified + by the -ConfigurationName argument. + + Example: pwsh -SettingsFile c:\myproject\powershell.config.json -Version | -v Shows the version of PowerShell and exits. Additional arguments are ignored. - Example: powershell -v + Example: pwsh -v -WindowStyle | -w Sets the window style to Normal, Minimized, Maximized or Hidden. + +-WorkingDirectory | -wd + Sets the working directory at the start of PowerShell given a valid PowerShell directory path. + Executing `Set-Location -LiteralPath <path>` at startup. + + Example: pwsh -WorkingDirectory ~ diff --git a/src/Microsoft.PowerShell.ConsoleHost/singleshell/installer/EngineInstaller.cs b/src/Microsoft.PowerShell.ConsoleHost/singleshell/installer/EngineInstaller.cs index 2df6f9e1103..82755a31493 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/singleshell/installer/EngineInstaller.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/singleshell/installer/EngineInstaller.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.ConsoleHost/singleshell/installer/MshHostMshSnapin.cs b/src/Microsoft.PowerShell.ConsoleHost/singleshell/installer/MshHostMshSnapin.cs index 7eeed217bd6..63f2a974552 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/singleshell/installer/MshHostMshSnapin.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/singleshell/installer/MshHostMshSnapin.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.ComponentModel; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/AssemblyInfo.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/AssemblyInfo.cs index a504b27b286..e9ec9e8826a 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/AssemblyInfo.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/AssemblyInfo.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System.Runtime.CompilerServices; using System.Reflection; [assembly: InternalsVisibleTo("System.Management.Automation,PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")] diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/EventDescriptor.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/EventDescriptor.cs index 65f77f22543..2b8cbcfc39e 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/EventDescriptor.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/EventDescriptor.cs @@ -1,8 +1,5 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -//------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Globalization; using System.Runtime.InteropServices; diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/EventProvider.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/EventProvider.cs index 8d78ad9c84c..baa14c16e8a 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/EventProvider.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/EventProvider.cs @@ -1,8 +1,5 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -//------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Globalization; using System.Runtime.InteropServices; @@ -266,7 +263,6 @@ private static void SetLastError(int error) } } - [System.Security.SecurityCritical] private static unsafe string EncodeObject(ref object data, EventData* dataDescriptor, byte* dataBuffer) /*++ @@ -427,7 +423,6 @@ to fill the passed in ETW data descriptor. return null; } - /// /// WriteMessageEvent, method to write a string with level and Keyword. /// The activity ID will be propagated only if the call stays on the same native thread as SetActivityId(). @@ -487,7 +482,6 @@ public bool WriteMessageEvent(string eventMessage) return WriteMessageEvent(eventMessage, 0, 0); } - /// /// WriteEvent method to write parameters with event schema properties /// @@ -597,7 +591,6 @@ protected bool WriteEvent(ref EventDescriptor eventDescriptor, int dataCount, In return true; } - /// /// WriteTransferEvent, method to write a parameters with event schema properties /// @@ -767,7 +760,6 @@ private static Guid GetActivityId() return t_activityId; } - [System.Security.SecurityCritical] public static void SetActivityId(ref Guid id) { diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/EventProviderTraceListener.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/EventProviderTraceListener.cs index d699a76ec7c..c2a9c026e54 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/EventProviderTraceListener.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/EventProviderTraceListener.cs @@ -1,8 +1,5 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -//------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System.Text; using System.Globalization; diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/CoTaskMemSafeHandle.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/CoTaskMemSafeHandle.cs index 120738c142e..71be5f4ca3e 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/CoTaskMemSafeHandle.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/CoTaskMemSafeHandle.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** @@ -34,7 +36,6 @@ internal IntPtr GetMemory() return handle; } - public override bool IsInvalid { get diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/CoTaskMemUnicodeSafeHandle.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/CoTaskMemUnicodeSafeHandle.cs index eecfcb274e5..6e7694949a6 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/CoTaskMemUnicodeSafeHandle.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/CoTaskMemUnicodeSafeHandle.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** @@ -40,7 +42,6 @@ internal IntPtr GetMemory() return handle; } - public override bool IsInvalid { get diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventBookmark.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventBookmark.cs index 8b700059f05..bc937391a21 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventBookmark.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventBookmark.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventKeyword.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventKeyword.cs index 435556b0148..3d7c298d821 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventKeyword.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventKeyword.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLevel.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLevel.cs index 909f18f5ad0..bac4f8db586 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLevel.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLevel.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogConfiguration.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogConfiguration.cs index 88a9942df0e..c8580091f0d 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogConfiguration.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogConfiguration.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** @@ -284,7 +286,6 @@ public void Dispose() GC.SuppressFinalize(this); } - [System.Security.SecuritySafeCritical] protected virtual void Dispose(bool disposing) { diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogException.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogException.cs index 14010a4bdb4..486c45e5723 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogException.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogException.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogHandle.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogHandle.cs index fbb5dd8b66c..06222aa8081 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogHandle.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogHandle.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogInformation.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogInformation.cs index 6311574009f..daebcc3787d 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogInformation.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogInformation.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** @@ -26,7 +28,6 @@ public sealed class EventLogInformation private long? _oldestRecordNumber; private bool? _isLogFull; - [System.Security.SecuritySafeCritical] internal EventLogInformation(EventLogSession session, string channelName, PathType pathType) { diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogLink.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogLink.cs index c40819565fa..59417750283 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogLink.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogLink.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** @@ -78,7 +80,6 @@ private void PrepareData() } } - public string LogName { get diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogPropertySelector.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogPropertySelector.cs index c9bed16f3b5..f1ba68016da 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogPropertySelector.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogPropertySelector.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogQuery.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogQuery.cs index 570a8811a4a..65eaee0e6d6 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogQuery.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogQuery.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogReader.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogReader.cs index 0adbeab0686..7190cb04a02 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogReader.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogReader.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** @@ -305,16 +307,7 @@ public void Seek(SeekOrigin origin, long offset) } else { - //if inside the current buffer, we still cannot read the events, as the handles. - //may have already been closed. - if (_currentIndex + offset >= 0) - { - SeekCommon(offset); - } - else //outside the current buffer - { - SeekCommon(offset); - } + SeekCommon(offset); } return; } diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogRecord.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogRecord.cs index d71761c08a4..ae1ea29482f 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogRecord.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogRecord.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** @@ -68,7 +70,6 @@ internal EventLogHandle Handle } } - internal void PrepareSystemData() { if (_systemProperties.filled) @@ -285,7 +286,6 @@ public IEnumerable MatchedQueryIds } } - public override EventBookmark Bookmark { [System.Security.SecuritySafeCritical] @@ -340,7 +340,6 @@ public override string LevelDisplayName } } - public override string OpcodeDisplayName { get @@ -392,7 +391,6 @@ public override IEnumerable KeywordsDisplayNames } } - public override IList Properties { get diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogSession.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogSession.cs index 8ed35125315..9bf610ca61a 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogSession.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogSession.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** @@ -60,7 +62,6 @@ public class EventLogSession : IDisposable // private EventLogHandle _handle = EventLogHandle.Zero; - //setup the System Context, once for all the EventRecords. [System.Security.SecuritySafeCritical] internal void SetupSystemContext() diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogStatus.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogStatus.cs index 0b12cedf3e0..489c47e6e79 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogStatus.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventLogStatus.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventMetadata.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventMetadata.cs index c6ae17d208e..6a016d50662 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventMetadata.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventMetadata.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** @@ -105,7 +107,6 @@ public EventTask Task } } - public IEnumerable Keywords { get diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventOpcode.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventOpcode.cs index f6bc7ad2ea7..64c35238bfb 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventOpcode.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventOpcode.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventProperty.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventProperty.cs index 4cde07513ab..dd9cdecfb4d 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventProperty.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventProperty.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventPropertyContext.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventPropertyContext.cs index 035d053edd2..99c6219955b 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventPropertyContext.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventPropertyContext.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventRecord.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventRecord.cs index 671b8312892..53f3e9132e2 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventRecord.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventRecord.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventTask.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventTask.cs index 620d7135523..1d9e1732578 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventTask.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/EventTask.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** @@ -27,7 +29,6 @@ public sealed class EventTask private ProviderMetadata _pmReference; private object _syncObject; - //called from EventMetadata internal EventTask(int value, ProviderMetadata pmReference) { diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/NativeWrapper.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/NativeWrapper.cs index 73a8d428ce9..0e048b0fc32 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/NativeWrapper.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/NativeWrapper.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** @@ -64,7 +66,6 @@ public static EventLogHandle EvtQuery( return handle; } - [System.Security.SecurityCritical] public static void EvtSeek( EventLogHandle resultSet, @@ -213,7 +214,6 @@ public static void EvtSaveChannelConfig(EventLogHandle channelConfig, int flags) EventLogException.Throw(win32Error); } - [System.Security.SecurityCritical] public static EventLogHandle EvtOpenLog(EventLogHandle session, string path, PathType flags) { @@ -429,7 +429,6 @@ public static object EvtGetPublisherMetadataProperty(EventLogHandle pmHandle, Un } } - [System.Security.SecurityCritical] internal static EventLogHandle EvtGetPublisherMetadataPropertyHandle(EventLogHandle pmHandle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId thePropertyId) { @@ -466,7 +465,6 @@ internal static EventLogHandle EvtGetPublisherMetadataPropertyHandle(EventLogHan } } - // implies UnsafeNativeMethods.EvtFormatMessageFlags.EvtFormatMessageId flag. [System.Security.SecurityCritical] public static string EvtFormatMessage(EventLogHandle handle, uint msgId) @@ -987,7 +985,6 @@ public static string EvtFormatMessageRenderName(EventLogHandle pmHandle, EventLo return sb.ToString(); } - //The EvtFormatMessage used for the obtaining of the Keywords names. [System.Security.SecuritySafeCritical] public static IEnumerable EvtFormatMessageRenderKeywords(EventLogHandle pmHandle, EventLogHandle eventHandle, UnsafeNativeMethods.EvtFormatMessageFlags flag) @@ -1087,7 +1084,6 @@ public static string EvtRenderBookmark(EventLogHandle eventHandle) } } - //Get the formatted description, using the msgId for FormatDescription(string []) [System.Security.SecuritySafeCritical] public static string EvtFormatMessageFormatDescription(EventLogHandle handle, EventLogHandle eventHandle, string[] values) @@ -1265,7 +1261,6 @@ public static object ConvertToObject(UnsafeNativeMethods.EvtVariant val, UnsafeN if (val.Type != (int)desiredType) throw new EventLogInvalidDataException(); - return ConvertToObject(val); } @@ -1287,7 +1282,6 @@ public static string ConvertToAnsiString(UnsafeNativeMethods.EvtVariant val) return Marshal.PtrToStringAnsi(val.AnsiString); } - [System.Security.SecurityCritical] public static EventLogHandle ConvertToSafeHandle(UnsafeNativeMethods.EvtVariant val) { @@ -1297,7 +1291,6 @@ public static EventLogHandle ConvertToSafeHandle(UnsafeNativeMethods.EvtVariant return new EventLogHandle(val.Handle, true); } - [System.Security.SecurityCritical] public static Array ConvertToArray(UnsafeNativeMethods.EvtVariant val, int size) where T : struct { @@ -1381,7 +1374,6 @@ public static Array ConvertToSysTimeArray(UnsafeNativeMethods.EvtVariant val) } } - [System.Security.SecurityCritical] public static string[] ConvertToStringArray(UnsafeNativeMethods.EvtVariant val, bool ansi) { diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/ProviderMetadata.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/ProviderMetadata.cs index 0843386d611..5ff0706e3c3 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/ProviderMetadata.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/ProviderMetadata.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** @@ -178,7 +180,6 @@ public IList LogLinks List channelList = new List(arraySize); - for (int index = 0; index < arraySize; index++) { string channelName = (string)NativeWrapper.EvtGetObjectArrayProperty(elHandle, index, (int)UnsafeNativeMethods.EvtPublisherMetadataPropertyId.EvtPublisherMetadataChannelReferencePath); @@ -405,7 +406,6 @@ internal object GetProviderListProperty(EventLogHandle providerHandle, UnsafeNat generalDisplayName = NativeWrapper.EvtFormatMessage(providerHandle, unchecked((uint)generalMessageId)); } - switch (objectTypeName) { case ObjectTypeName.Level: @@ -445,7 +445,6 @@ internal object GetProviderListProperty(EventLogHandle providerHandle, UnsafeNat } } - public IList Levels { get @@ -498,7 +497,6 @@ public IList Keywords } } - public IList Tasks { get @@ -516,7 +514,6 @@ public IList Tasks } } - public IEnumerable Events { [System.Security.SecurityCritical] diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/ProviderMetadataCachedInformation.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/ProviderMetadataCachedInformation.cs index 6fedf2f149f..feb1823cc3c 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/ProviderMetadataCachedInformation.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/ProviderMetadataCachedInformation.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** @@ -129,7 +131,6 @@ private void DeleteCacheEntry(ProviderMetadataId key) value.ProviderMetadata.Dispose(); } - private void AddCacheEntry(ProviderMetadataId key, ProviderMetadata pm) { if (IsCacheFull()) diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/Winmeta.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/Winmeta.cs index 47746d76868..0534158c2a8 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/Winmeta.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/Winmeta.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. /*============================================================ ** diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/UnsafeNativeMethods.cs b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/UnsafeNativeMethods.cs index c2a43ba09e9..3089ce8b17e 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/UnsafeNativeMethods.cs +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/UnsafeNativeMethods.cs @@ -1,4 +1,5 @@ - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. namespace System.Diagnostics.Eventing { @@ -78,7 +79,6 @@ internal static class UnsafeNativeMethods private const int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000; private const int FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000; - [DllImport(FormatMessageDllName, CharSet = CharSet.Unicode, BestFitMapping = false)] [SecurityCritical] internal static extern int FormatMessage(int dwFlags, IntPtr lpSource, @@ -140,7 +140,6 @@ [In][Out]ref long registrationHandle [SecurityCritical] internal static extern int EventUnregister([In] long registrationHandle); - // // Control (Is Enabled) APIs // @@ -524,7 +523,6 @@ internal struct EvtRpcLogin public int Flags; } - //SEEK [Flags] internal enum EvtSeekFlags @@ -682,7 +680,6 @@ internal static extern bool EvtGetEventMetadataProperty( out int eventMetadataPropertyBufferUsed ); - //Channel Configuration Native Api [DllImport(WEVTAPI, CharSet = CharSet.Unicode, SetLastError = true)] @@ -703,7 +700,6 @@ internal static extern bool EvtNextChannelPath( out int channelPathBufferUsed ); - [DllImport(WEVTAPI, CharSet = CharSet.Unicode, SetLastError = true)] [SecurityCritical] internal static extern EventLogHandle EvtOpenPublisherEnum( @@ -737,7 +733,6 @@ internal static extern bool EvtSaveChannelConfig( int flags ); - [DllImport(WEVTAPI, CharSet = CharSet.Unicode, SetLastError = true)] [SecurityCritical] [return: MarshalAs(UnmanagedType.Bool)] @@ -748,7 +743,6 @@ internal static extern bool EvtSetChannelConfigProperty( ref EvtVariant propertyValue ); - [DllImport(WEVTAPI, CharSet = CharSet.Unicode, SetLastError = true)] [SecurityCritical] [return: MarshalAs(UnmanagedType.Bool)] @@ -771,7 +765,6 @@ internal static extern EventLogHandle EvtOpenLog( [MarshalAs(UnmanagedType.I4)]PathType flags ); - [DllImport(WEVTAPI, CharSet = CharSet.Unicode, SetLastError = true)] [SecurityCritical] [return: MarshalAs(UnmanagedType.Bool)] @@ -839,7 +832,6 @@ internal static extern bool EvtRender( out int propCount ); - [DllImport(WEVTAPI, EntryPoint = "EvtRender", CallingConvention = CallingConvention.Winapi, SetLastError = true)] [SecurityCritical] [return: MarshalAs(UnmanagedType.Bool)] @@ -853,7 +845,6 @@ internal static extern bool EvtRender( out int propCount ); - [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)] internal struct EvtStringVariant { diff --git a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj index e222112cfb6..3c9921115e9 100644 --- a/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj +++ b/src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj @@ -23,7 +23,8 @@ - + + diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/AddLocalGroupMemberCommand.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/AddLocalGroupMemberCommand.cs index 65540314dcc..70b2e9f18cc 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/AddLocalGroupMemberCommand.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/AddLocalGroupMemberCommand.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #region Using directives using System; using System.Collections.Generic; @@ -11,7 +14,6 @@ using System.Diagnostics.CodeAnalysis; #endregion - namespace Microsoft.PowerShell.Commands { /// @@ -94,7 +96,6 @@ public System.Security.Principal.SecurityIdentifier SID private System.Security.Principal.SecurityIdentifier sid; #endregion Parameter Properties - #region Cmdlet Overrides /// /// BeginProcessing method. @@ -104,7 +105,6 @@ protected override void BeginProcessing() sam = new Sam(); } - /// /// ProcessRecord method. /// @@ -125,7 +125,6 @@ protected override void ProcessRecord() } } - /// /// EndProcessing method. /// @@ -209,7 +208,6 @@ private LocalPrincipal MakePrincipal(string groupId, LocalPrincipal member) return null; } - /// /// Determine if a principal should be processed. /// Just a wrapper around Cmdlet.ShouldProcess, with localized string diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/DisableLocalUserCommand.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/DisableLocalUserCommand.cs index 9d7d4c5ca3c..eb47f20ec8a 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/DisableLocalUserCommand.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/DisableLocalUserCommand.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #region Using directives using System; using System.Collections.Generic; @@ -10,7 +13,6 @@ using System.Diagnostics.CodeAnalysis; #endregion - namespace Microsoft.PowerShell.Commands { /// @@ -91,7 +93,6 @@ public System.Security.Principal.SecurityIdentifier[] SID private System.Security.Principal.SecurityIdentifier[] sid; #endregion Parameter Properties - #region Cmdlet Overrides /// /// BeginProcessing method. @@ -101,7 +102,6 @@ protected override void BeginProcessing() sam = new Sam(); } - /// /// ProcessRecord method. /// @@ -119,7 +119,6 @@ protected override void ProcessRecord() } } - /// /// EndProcessing method. /// diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/EnableLocalUserCommand.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/EnableLocalUserCommand.cs index cf0562f23f5..f872439c55c 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/EnableLocalUserCommand.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/EnableLocalUserCommand.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #region Using directives using System; using System.Collections.Generic; @@ -10,7 +13,6 @@ using System.Diagnostics.CodeAnalysis; #endregion - namespace Microsoft.PowerShell.Commands { /// @@ -91,9 +93,6 @@ public System.Security.Principal.SecurityIdentifier[] SID private System.Security.Principal.SecurityIdentifier[] sid; #endregion Parameter Properties - - - #region Cmdlet Overrides /// /// BeginProcessing method. @@ -103,7 +102,6 @@ protected override void BeginProcessing() sam = new Sam(); } - /// /// ProcessRecord method. /// @@ -121,7 +119,6 @@ protected override void ProcessRecord() } } - /// /// EndProcessing method. /// diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/GetLocalGroupCommand.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/GetLocalGroupCommand.cs index bd93d56fa6e..69c1416a787 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/GetLocalGroupCommand.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/GetLocalGroupCommand.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #region Using directives using System; using System.Management.Automation; @@ -8,7 +11,6 @@ using System.Diagnostics.CodeAnalysis; #endregion - namespace Microsoft.PowerShell.Commands { /// @@ -61,9 +63,6 @@ public System.Security.Principal.SecurityIdentifier[] SID private System.Security.Principal.SecurityIdentifier[] sid; #endregion Parameter Properties - - - #region Cmdlet Overrides /// /// BeginProcessing method. @@ -73,7 +72,6 @@ protected override void BeginProcessing() sam = new Sam(); } - /// /// ProcessRecord method. /// @@ -91,7 +89,6 @@ protected override void ProcessRecord() ProcessSids(); } - /// /// EndProcessing method. /// diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/GetLocalGroupMemberCommand.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/GetLocalGroupMemberCommand.cs index 0acb4d03ded..a9f28b792c3 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/GetLocalGroupMemberCommand.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/GetLocalGroupMemberCommand.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #region Using directives using System; using System.Collections.Generic; @@ -8,7 +11,6 @@ using System.Management.Automation.SecurityAccountsManager.Extensions; #endregion - namespace Microsoft.PowerShell.Commands { /// @@ -92,7 +94,6 @@ public System.Security.Principal.SecurityIdentifier SID private System.Security.Principal.SecurityIdentifier sid; #endregion Parameter Properties - #region Cmdlet Overrides /// /// BeginProcessing method. @@ -102,7 +103,6 @@ protected override void BeginProcessing() sam = new Sam(); } - /// /// ProcessRecord method. /// @@ -128,7 +128,6 @@ protected override void ProcessRecord() } } - /// /// EndProcessing method. /// diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/GetLocalUserCommand.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/GetLocalUserCommand.cs index e37acc70611..d5a33ac357e 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/GetLocalUserCommand.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/GetLocalUserCommand.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #region Using directives using System; using System.Collections.Generic; @@ -8,7 +11,6 @@ using System.Management.Automation.SecurityAccountsManager.Extensions; #endregion - namespace Microsoft.PowerShell.Commands { /// @@ -64,8 +66,6 @@ public System.Security.Principal.SecurityIdentifier[] SID private System.Security.Principal.SecurityIdentifier[] sid; #endregion Parameter Properties - - #region Cmdlet Overrides /// /// BeginProcessing method. @@ -75,7 +75,6 @@ protected override void BeginProcessing() sam = new Sam(); } - /// /// ProcessRecord method. /// @@ -93,7 +92,6 @@ protected override void ProcessRecord() ProcessSids(); } - /// /// EndProcessing method. /// diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/NewLocalGroupCommand.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/NewLocalGroupCommand.cs index 35a6272de96..d7283d54308 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/NewLocalGroupCommand.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/NewLocalGroupCommand.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #region Using directives using System; using System.Management.Automation; @@ -8,7 +11,6 @@ using Microsoft.PowerShell.LocalAccounts; #endregion - namespace Microsoft.PowerShell.Commands { /// @@ -57,8 +59,6 @@ public string Name private string name; #endregion Parameter Properties - - #region Cmdlet Overrides /// /// BeginProcessing method. @@ -68,7 +68,6 @@ protected override void BeginProcessing() sam = new Sam(); } - /// /// ProcessRecord method. /// @@ -93,7 +92,6 @@ protected override void ProcessRecord() } } - /// /// EndProcessing method. /// diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/NewLocalUserCommand.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/NewLocalUserCommand.cs index 70690eb8584..566a3039c0c 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/NewLocalUserCommand.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/NewLocalUserCommand.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #region Using directives using System; using System.Management.Automation; @@ -8,7 +11,6 @@ using Microsoft.PowerShell.LocalAccounts; #endregion - namespace Microsoft.PowerShell.Commands { /// @@ -179,8 +181,6 @@ public System.Management.Automation.SwitchParameter UserMayNotChangePassword private System.Management.Automation.SwitchParameter usermaynotchangepassword; #endregion Parameter Properties - - #region Cmdlet Overrides /// /// BeginProcessing method. @@ -195,7 +195,6 @@ protected override void BeginProcessing() sam = new Sam(); } - /// /// ProcessRecord method. /// @@ -250,7 +249,6 @@ protected override void ProcessRecord() } } - /// /// EndProcessing method. /// diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/RemoveLocalGroupCommand.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/RemoveLocalGroupCommand.cs index cb93071ca5d..cccc31e7915 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/RemoveLocalGroupCommand.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/RemoveLocalGroupCommand.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #region Using directives using System; using System.Management.Automation; @@ -9,7 +12,6 @@ using System.Diagnostics.CodeAnalysis; #endregion - namespace Microsoft.PowerShell.Commands { /// @@ -84,7 +86,6 @@ public System.Security.Principal.SecurityIdentifier[] SID private System.Security.Principal.SecurityIdentifier[] sid; #endregion Parameter Properties - #region Cmdlet Overrides /// /// BeginProcessing method. @@ -94,7 +95,6 @@ protected override void BeginProcessing() sam = new Sam(); } - /// /// ProcessRecord method. /// @@ -112,7 +112,6 @@ protected override void ProcessRecord() } } - /// /// EndProcessing method. /// diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/RemoveLocalGroupMemberCommand.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/RemoveLocalGroupMemberCommand.cs index b8c87bef98a..26c5914fafb 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/RemoveLocalGroupMemberCommand.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/RemoveLocalGroupMemberCommand.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #region Using directives using System; using System.Collections.Generic; @@ -11,7 +14,6 @@ using System.Diagnostics.CodeAnalysis; #endregion - namespace Microsoft.PowerShell.Commands { /// @@ -94,7 +96,6 @@ public System.Security.Principal.SecurityIdentifier SID private System.Security.Principal.SecurityIdentifier sid; #endregion Parameter Properties - #region Cmdlet Overrides /// /// BeginProcessing method. @@ -104,7 +105,6 @@ protected override void BeginProcessing() sam = new Sam(); } - /// /// ProcessRecord method. /// @@ -125,7 +125,6 @@ protected override void ProcessRecord() } } - /// /// EndProcessing method. /// diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/RemoveLocalUserCommand.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/RemoveLocalUserCommand.cs index cbcef6ef48f..a5e36fcc81f 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/RemoveLocalUserCommand.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/RemoveLocalUserCommand.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #region Using directives using System; using System.Management.Automation; @@ -9,7 +12,6 @@ using System.Diagnostics.CodeAnalysis; #endregion - namespace Microsoft.PowerShell.Commands { /// @@ -85,8 +87,6 @@ public System.Security.Principal.SecurityIdentifier[] SID private System.Security.Principal.SecurityIdentifier[] sid; #endregion Parameter Properties - - #region Cmdlet Overrides /// /// BeginProcessing method. @@ -96,7 +96,6 @@ protected override void BeginProcessing() sam = new Sam(); } - /// /// ProcessRecord method. /// @@ -114,7 +113,6 @@ protected override void ProcessRecord() } } - /// /// EndProcessing method. /// diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/RenameLocalGroupCommand.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/RenameLocalGroupCommand.cs index 25254cf05fc..a1e458e6d10 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/RenameLocalGroupCommand.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/RenameLocalGroupCommand.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #region Using directives using System; using System.Management.Automation; @@ -8,7 +11,6 @@ using Microsoft.PowerShell.LocalAccounts; #endregion - namespace Microsoft.PowerShell.Commands { /// @@ -95,7 +97,6 @@ public System.Security.Principal.SecurityIdentifier SID private System.Security.Principal.SecurityIdentifier sid; #endregion Parameter Properties - #region Cmdlet Overrides /// /// BeginProcessing method. @@ -105,7 +106,6 @@ protected override void BeginProcessing() sam = new Sam(); } - /// /// ProcessRecord method. /// @@ -123,7 +123,6 @@ protected override void ProcessRecord() } } - /// /// EndProcessing method. /// diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/RenameLocalUserCommand.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/RenameLocalUserCommand.cs index 4a48b659e62..c731820caa6 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/RenameLocalUserCommand.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/RenameLocalUserCommand.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #region Using directives using System; using System.Management.Automation; @@ -8,7 +11,6 @@ using Microsoft.PowerShell.LocalAccounts; #endregion - namespace Microsoft.PowerShell.Commands { /// @@ -95,8 +97,6 @@ public System.Security.Principal.SecurityIdentifier SID private System.Security.Principal.SecurityIdentifier sid; #endregion Parameter Properties - - #region Cmdlet Overrides /// /// BeginProcessing method. @@ -106,7 +106,6 @@ protected override void BeginProcessing() sam = new Sam(); } - /// /// ProcessRecord method. /// @@ -124,7 +123,6 @@ protected override void ProcessRecord() } } - /// /// EndProcessing method. /// diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/SetLocalGroupCommand.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/SetLocalGroupCommand.cs index eeaf701bffd..b22806aad9d 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/SetLocalGroupCommand.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/SetLocalGroupCommand.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #region Using directives using System; using System.Management.Automation; @@ -8,7 +11,6 @@ using Microsoft.PowerShell.LocalAccounts; #endregion - namespace Microsoft.PowerShell.Commands { /// @@ -93,8 +95,6 @@ public System.Security.Principal.SecurityIdentifier SID private System.Security.Principal.SecurityIdentifier sid; #endregion Parameter Properties - - #region Cmdlet Overrides /// /// BeginProcessing method. @@ -104,7 +104,6 @@ protected override void BeginProcessing() sam = new Sam(); } - /// /// ProcessRecord method. /// @@ -148,7 +147,6 @@ protected override void ProcessRecord() } } - /// /// EndProcessing method. /// diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/SetLocalUserCommand.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/SetLocalUserCommand.cs index 4ae4e422d39..0b3e4b2fbec 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/SetLocalUserCommand.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/SetLocalUserCommand.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #region Using directives using System; using System.Management.Automation; @@ -8,7 +11,6 @@ using Microsoft.PowerShell.LocalAccounts; #endregion - namespace Microsoft.PowerShell.Commands { /// @@ -185,8 +187,6 @@ public System.Boolean UserMayChangePassword private System.Boolean usermaychangepassword; #endregion Parameter Properties - - #region Cmdlet Overrides /// /// BeginProcessing method. @@ -201,7 +201,6 @@ protected override void BeginProcessing() sam = new Sam(); } - /// /// ProcessRecord method. /// @@ -278,7 +277,6 @@ protected override void ProcessRecord() } } - /// /// EndProcessing method. /// diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Exceptions.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Exceptions.cs index a9f7193efe4..679c89d009b 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Exceptions.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Exceptions.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using System.Management.Automation; using System.Management.Automation.SecurityAccountsManager; using System.Runtime.Serialization; diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Extensions.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Extensions.cs index 86ef63e3ef7..0a956c10867 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Extensions.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Extensions.cs @@ -1,4 +1,7 @@ -using System.Runtime.InteropServices; +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Runtime.InteropServices; using System.Security; using System.Security.Principal; using System.Text.RegularExpressions; diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/LocalGroup.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/LocalGroup.cs index 170493522fb..eb544986332 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/LocalGroup.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/LocalGroup.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.PowerShell.LocalAccounts; @@ -47,7 +50,6 @@ private LocalGroup(LocalGroup other) } #endregion Construction - #region Public Methods /// /// Provides a string representation of the LocalGroup object. diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/LocalPrincipal.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/LocalPrincipal.cs index 94e5972d265..eef3d02b30f 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/LocalPrincipal.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/LocalPrincipal.cs @@ -1,4 +1,7 @@ -using System.Security.Principal; +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Security.Principal; namespace Microsoft.PowerShell.Commands { diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/LocalUser.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/LocalUser.cs index fb27679feac..12e8832bf0e 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/LocalUser.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/LocalUser.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using Microsoft.PowerShell.LocalAccounts; @@ -52,7 +55,6 @@ public class LocalUser : LocalPrincipal /// public bool UserMayChangePassword { get; set; } - /// /// Indicates whether the user must have a password (true) or not (false). /// @@ -69,7 +71,6 @@ public class LocalUser : LocalPrincipal public DateTime? LastLogon { get; set; } #endregion Public Properties - #region Construction /// /// Initializes a new LocalUser object. diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Native.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Native.cs index 4a085d7867f..e7a7d0ec7f8 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Native.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Native.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using System.Runtime.InteropServices; using System.Text; @@ -162,7 +165,6 @@ public void Dispose() } } - // These structures are filled in by Marshalling, so fields will be initialized // invisibly to the C# compiler, and some fields will not be used in C# code. #pragma warning disable 0649, 0169 @@ -195,7 +197,6 @@ internal static class Win32 internal const UInt32 STANDARD_RIGHTS_WRITE = READ_CONTROL; internal const UInt32 STANDARD_RIGHTS_EXECUTE = READ_CONTROL; - internal const UInt32 STANDARD_RIGHTS_ALL = 0x001F0000; internal const UInt32 SPECIFIC_RIGHTS_ALL = 0x0000FFFF; @@ -209,7 +210,6 @@ internal static class Win32 internal const UInt32 GENERIC_EXECUTE = 0x20000000; internal const UInt32 GENERIC_ALL = 0x10000000; - // These constants control the behavior of the FormatMessage Windows API function internal const uint FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100; internal const uint FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200; @@ -335,7 +335,6 @@ internal static class Win32 internal const int NERR_LastAdmin = NERR_BASE + 352; // This operation is not allowed on the last administrative account. #endregion Win32 Error Codes - #region SECURITY_DESCRIPTOR Control Flags internal const UInt16 SE_DACL_PRESENT = 0x0004; internal const UInt16 SE_SELF_RELATIVE = 0x8000; @@ -366,7 +365,6 @@ internal static extern bool LookupAccountName(string systemName, ref uint domainNameLength, out SID_NAME_USE peUse); - [DllImport(PInvokeDllNames.GetSecurityDescriptorDaclDllName, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool GetSecurityDescriptorDacl(IntPtr pSecurityDescriptor, diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/NtStatus.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/NtStatus.cs index 59e00f0b252..231909c9171 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/NtStatus.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/NtStatus.cs @@ -1,4 +1,6 @@ - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System.Diagnostics.CodeAnalysis; namespace System.Management.Automation.SecurityAccountsManager.Native @@ -18,7 +20,6 @@ internal static class NtStatus public const UInt32 STATUS_SEVERITY_INFORMATIONAL = 0x1; public const UInt32 STATUS_SEVERITY_ERROR = 0x3; - public const UInt32 STATUS_SUCCESS = 0x00000000; // // MessageText: @@ -28,11 +29,6 @@ internal static class NtStatus public const UInt32 STATUS_MORE_ENTRIES = 0x00000105; - - - - - ///////////////////////////////////////////////////////////////////////// // // Standard Information values @@ -453,7 +449,6 @@ public static bool IsError(UInt32 ntstatus) return Severity(ntstatus) == STATUS_SEVERITY_ERROR; } - /// /// Determine if an NTSTATUS value indicates a Warning /// @@ -480,7 +475,6 @@ public static bool IsInformational(UInt32 ntstatus) return Severity(ntstatus) == STATUS_SEVERITY_INFORMATIONAL; } - /// /// Return the Severity part of an NTSTATUS value /// @@ -493,7 +487,6 @@ public static uint Severity(UInt32 ntstatus) return ntstatus >> 30; } - /// /// Return the Facility part of an NSTATUS value /// @@ -508,7 +501,6 @@ public static uint Facility(UInt32 ntstatus) return (ntstatus >> 16) & 0x0FFF; } - /// /// Return the Code part of an NTSTATUS value /// diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/PInvokeDllNames.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/PInvokeDllNames.cs index cdc55996036..026a47ca6f6 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/PInvokeDllNames.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/PInvokeDllNames.cs @@ -1,6 +1,5 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. namespace System.Management.Automation { diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Sam.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Sam.cs index b74184e1685..6afc175ae84 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Sam.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Sam.cs @@ -1,4 +1,7 @@ -using System.Collections.Generic; +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Collections.Generic; using System.Runtime.InteropServices; using System.Security.AccessControl; using System.Security.Principal; @@ -44,7 +47,6 @@ internal class SamRidEnumeration #endregion Additional members } - /// /// Provides methods for manipulating local Users and Groups. /// @@ -176,7 +178,6 @@ internal enum DomainAccess : uint Max = Win32.MAXIMUM_ALLOWED } - /// /// The operation under way. Used in the class. /// @@ -855,7 +856,6 @@ internal void RemoveLocalUser(LocalUser user) RemoveUser(user.SID); } - /// /// Rename a local user. /// diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/SamApi.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/SamApi.cs index e0c686ea7c7..a4598947308 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/SamApi.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/SamApi.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; using System.Collections.Generic; using System.Runtime.InteropServices; @@ -210,7 +213,6 @@ internal struct USER_LOGON_HOURS_INFORMATION public LOGON_HOURS LogonHours; } - [StructLayout(LayoutKind.Sequential)] internal struct POLICY_PRIMARY_DOMAIN_INFO { @@ -273,7 +275,6 @@ internal static class SamApi internal const UInt32 SAM_USER_ENUMERATION_FILTER_INTERNET = 0x00000002; internal const UInt32 SAM_SERVER_LOOKUP_DOMAIN = 0x0020; - // // Bits to be used in UserAllInformation's WhichFields field (to indicate // which items were queried or set). @@ -311,7 +312,6 @@ internal static class SamApi internal const UInt32 USER_ALL_UNDEFINED_MASK = 0xC0000000; - // // Bit masks for the UserAccountControl member of the USER_ALL_INFORMATION structure // @@ -351,7 +351,6 @@ public static extern UInt32 SamConnect(ref UNICODE_STRING serverName, UInt32 desiredAccess, ref OBJECT_ATTRIBUTES objectAttributes); - [DllImport("samlib.dll")] internal static extern UInt32 SamRidToSid(IntPtr objectHandle, UInt32 rid, out IntPtr sid); @@ -444,7 +443,6 @@ internal static extern UInt32 SamCreateUser2InDomain(IntPtr domainHandle, out UInt32 grantedAccess, out UInt32 relativeId); - [DllImport("samlib.dll")] internal static extern UInt32 SamQueryInformationUser(IntPtr userHandle, USER_INFORMATION_CLASS userInformationClass, diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/StringUtil.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/StringUtil.cs index afc20f12612..24943c563c3 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/StringUtil.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/StringUtil.cs @@ -1,4 +1,7 @@ -using System.Globalization; +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Globalization; using System.Management.Automation.SecurityAccountsManager.Native; namespace System.Management.Automation.SecurityAccountsManager diff --git a/src/Microsoft.PowerShell.PSReadLine/AssemblyInfo.cs b/src/Microsoft.PowerShell.PSReadLine/AssemblyInfo.cs index be77dec90f8..f77c6653060 100644 --- a/src/Microsoft.PowerShell.PSReadLine/AssemblyInfo.cs +++ b/src/Microsoft.PowerShell.PSReadLine/AssemblyInfo.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System.Reflection; diff --git a/src/Microsoft.PowerShell.PSReadLine/BasicEditing.cs b/src/Microsoft.PowerShell.PSReadLine/BasicEditing.cs index 8737a88c0bf..377aa154cd1 100644 --- a/src/Microsoft.PowerShell.PSReadLine/BasicEditing.cs +++ b/src/Microsoft.PowerShell.PSReadLine/BasicEditing.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/Cmdlets.cs b/src/Microsoft.PowerShell.PSReadLine/Cmdlets.cs index 21a3ed15dcd..7146e28a0b9 100644 --- a/src/Microsoft.PowerShell.PSReadLine/Cmdlets.cs +++ b/src/Microsoft.PowerShell.PSReadLine/Cmdlets.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/Completion.cs b/src/Microsoft.PowerShell.PSReadLine/Completion.cs index 932397ec385..aadee01d815 100644 --- a/src/Microsoft.PowerShell.PSReadLine/Completion.cs +++ b/src/Microsoft.PowerShell.PSReadLine/Completion.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/Completion.vi.cs b/src/Microsoft.PowerShell.PSReadLine/Completion.vi.cs index 97deef45174..2e5eb7458de 100644 --- a/src/Microsoft.PowerShell.PSReadLine/Completion.vi.cs +++ b/src/Microsoft.PowerShell.PSReadLine/Completion.vi.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/ConsoleBufferBuilder.cs b/src/Microsoft.PowerShell.PSReadLine/ConsoleBufferBuilder.cs index fad206fcc7c..df5244c4f81 100644 --- a/src/Microsoft.PowerShell.PSReadLine/ConsoleBufferBuilder.cs +++ b/src/Microsoft.PowerShell.PSReadLine/ConsoleBufferBuilder.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/ConsoleKeyChordConverter.cs b/src/Microsoft.PowerShell.PSReadLine/ConsoleKeyChordConverter.cs index bb34f27f92b..1af6c7aecf4 100644 --- a/src/Microsoft.PowerShell.PSReadLine/ConsoleKeyChordConverter.cs +++ b/src/Microsoft.PowerShell.PSReadLine/ConsoleKeyChordConverter.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/ConsoleLib.cs b/src/Microsoft.PowerShell.PSReadLine/ConsoleLib.cs index 462207bbad8..177f0779fa7 100644 --- a/src/Microsoft.PowerShell.PSReadLine/ConsoleLib.cs +++ b/src/Microsoft.PowerShell.PSReadLine/ConsoleLib.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/History.cs b/src/Microsoft.PowerShell.PSReadLine/History.cs index 417c24d4cfb..0b77feb70f5 100644 --- a/src/Microsoft.PowerShell.PSReadLine/History.cs +++ b/src/Microsoft.PowerShell.PSReadLine/History.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/HistoryQueue.cs b/src/Microsoft.PowerShell.PSReadLine/HistoryQueue.cs index 1034d94db17..ea6e86d485b 100644 --- a/src/Microsoft.PowerShell.PSReadLine/HistoryQueue.cs +++ b/src/Microsoft.PowerShell.PSReadLine/HistoryQueue.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/KeyBindings.cs b/src/Microsoft.PowerShell.PSReadLine/KeyBindings.cs index 7ec4e4f41e6..05f55382095 100644 --- a/src/Microsoft.PowerShell.PSReadLine/KeyBindings.cs +++ b/src/Microsoft.PowerShell.PSReadLine/KeyBindings.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/KeyBindings.vi.cs b/src/Microsoft.PowerShell.PSReadLine/KeyBindings.vi.cs index eb6f76da620..dd9f09b633a 100644 --- a/src/Microsoft.PowerShell.PSReadLine/KeyBindings.vi.cs +++ b/src/Microsoft.PowerShell.PSReadLine/KeyBindings.vi.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/Keys.cs b/src/Microsoft.PowerShell.PSReadLine/Keys.cs index 3119be8dd9e..df66e6baae5 100644 --- a/src/Microsoft.PowerShell.PSReadLine/Keys.cs +++ b/src/Microsoft.PowerShell.PSReadLine/Keys.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/KillYank.cs b/src/Microsoft.PowerShell.PSReadLine/KillYank.cs index dac5b9e02d4..b06be4cc928 100644 --- a/src/Microsoft.PowerShell.PSReadLine/KillYank.cs +++ b/src/Microsoft.PowerShell.PSReadLine/KillYank.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/Movement.cs b/src/Microsoft.PowerShell.PSReadLine/Movement.cs index 8469a04c14e..b309b3245b5 100644 --- a/src/Microsoft.PowerShell.PSReadLine/Movement.cs +++ b/src/Microsoft.PowerShell.PSReadLine/Movement.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/Movement.vi.cs b/src/Microsoft.PowerShell.PSReadLine/Movement.vi.cs index 43ddaf60fe9..7c1c8a7bf21 100644 --- a/src/Microsoft.PowerShell.PSReadLine/Movement.vi.cs +++ b/src/Microsoft.PowerShell.PSReadLine/Movement.vi.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/Options.cs b/src/Microsoft.PowerShell.PSReadLine/Options.cs index 0a385cf0882..63b440f145a 100644 --- a/src/Microsoft.PowerShell.PSReadLine/Options.cs +++ b/src/Microsoft.PowerShell.PSReadLine/Options.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/PSReadLine.psd1 b/src/Microsoft.PowerShell.PSReadLine/PSReadLine.psd1 index 6af2eea6f73..a634495d19d 100644 --- a/src/Microsoft.PowerShell.PSReadLine/PSReadLine.psd1 +++ b/src/Microsoft.PowerShell.PSReadLine/PSReadLine.psd1 @@ -5,7 +5,7 @@ ModuleVersion = '1.2' GUID = '5714753b-2afd-4492-a5fd-01d9e2cff8b5' Author = 'Microsoft Corporation' CompanyName = 'Microsoft Corporation' -Copyright = '(c) Microsoft Corporation. All rights reserved.' +Copyright = 'Copyright (c) Microsoft Corporation. All rights reserved.' Description = 'Great command line editing in the PowerShell console host' PowerShellVersion = '3.0' DotNetFrameworkVersion = '4.0' @@ -13,5 +13,5 @@ CLRVersion = '4.0' FunctionsToExport = 'PSConsoleHostReadline' CmdletsToExport = 'Get-PSReadlineKeyHandler','Set-PSReadlineKeyHandler','Remove-PSReadlineKeyHandler', 'Get-PSReadlineOption','Set-PSReadlineOption' -HelpInfoURI = 'https://go.microsoft.com/fwlink/?LinkId=528806' +HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=855966' } diff --git a/src/Microsoft.PowerShell.PSReadLine/PublicAPI.cs b/src/Microsoft.PowerShell.PSReadLine/PublicAPI.cs index 3f0163a781d..2db274ec43b 100644 --- a/src/Microsoft.PowerShell.PSReadLine/PublicAPI.cs +++ b/src/Microsoft.PowerShell.PSReadLine/PublicAPI.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/ReadLine.cs b/src/Microsoft.PowerShell.PSReadLine/ReadLine.cs index 0282d77841f..0aede96f921 100644 --- a/src/Microsoft.PowerShell.PSReadLine/ReadLine.cs +++ b/src/Microsoft.PowerShell.PSReadLine/ReadLine.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/ReadLine.vi.cs b/src/Microsoft.PowerShell.PSReadLine/ReadLine.vi.cs index 9c7b79289da..304663f06a4 100644 --- a/src/Microsoft.PowerShell.PSReadLine/ReadLine.vi.cs +++ b/src/Microsoft.PowerShell.PSReadLine/ReadLine.vi.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/Render.cs b/src/Microsoft.PowerShell.PSReadLine/Render.cs index e0aec994daf..632fdeb9cc3 100644 --- a/src/Microsoft.PowerShell.PSReadLine/Render.cs +++ b/src/Microsoft.PowerShell.PSReadLine/Render.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/Replace.vi.cs b/src/Microsoft.PowerShell.PSReadLine/Replace.vi.cs index cf8c39e750c..c4960e5b703 100644 --- a/src/Microsoft.PowerShell.PSReadLine/Replace.vi.cs +++ b/src/Microsoft.PowerShell.PSReadLine/Replace.vi.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/SamplePSReadlineProfile.ps1 b/src/Microsoft.PowerShell.PSReadLine/SamplePSReadlineProfile.ps1 index cfde8a0c817..a1f618c315a 100644 --- a/src/Microsoft.PowerShell.PSReadLine/SamplePSReadlineProfile.ps1 +++ b/src/Microsoft.PowerShell.PSReadLine/SamplePSReadlineProfile.ps1 @@ -425,7 +425,6 @@ Set-PSReadlineKeyHandler -Key F1 ` } } - # # Ctrl+Shift+j then type a key to mark the current directory. # Ctrj+j then the same key will change back to that directory without diff --git a/src/Microsoft.PowerShell.PSReadLine/ScreenCapture.cs b/src/Microsoft.PowerShell.PSReadLine/ScreenCapture.cs index e35d83a5c57..4404c4866b4 100644 --- a/src/Microsoft.PowerShell.PSReadLine/ScreenCapture.cs +++ b/src/Microsoft.PowerShell.PSReadLine/ScreenCapture.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ #if !UNIX diff --git a/src/Microsoft.PowerShell.PSReadLine/UndoRedo.cs b/src/Microsoft.PowerShell.PSReadLine/UndoRedo.cs index b451231e1a6..e25aa8ad85f 100644 --- a/src/Microsoft.PowerShell.PSReadLine/UndoRedo.cs +++ b/src/Microsoft.PowerShell.PSReadLine/UndoRedo.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/UndoRedo.vi.cs b/src/Microsoft.PowerShell.PSReadLine/UndoRedo.vi.cs index 11e5f452d32..ed0d127f028 100644 --- a/src/Microsoft.PowerShell.PSReadLine/UndoRedo.vi.cs +++ b/src/Microsoft.PowerShell.PSReadLine/UndoRedo.vi.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/VisualEditing.vi.cs b/src/Microsoft.PowerShell.PSReadLine/VisualEditing.vi.cs index 59a14053eab..b93a6f36b4a 100644 --- a/src/Microsoft.PowerShell.PSReadLine/VisualEditing.vi.cs +++ b/src/Microsoft.PowerShell.PSReadLine/VisualEditing.vi.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.PSReadLine/Words.cs b/src/Microsoft.PowerShell.PSReadLine/Words.cs index 5aa0eca46a9..fe8f3c8ecc9 100644 --- a/src/Microsoft.PowerShell.PSReadLine/Words.cs +++ b/src/Microsoft.PowerShell.PSReadLine/Words.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.PSReadLine/Words.vi.cs b/src/Microsoft.PowerShell.PSReadLine/Words.vi.cs index eab0df2f4f8..219499737c0 100644 --- a/src/Microsoft.PowerShell.PSReadLine/Words.vi.cs +++ b/src/Microsoft.PowerShell.PSReadLine/Words.vi.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.PSReadLine/YankPaste.vi.cs b/src/Microsoft.PowerShell.PSReadLine/YankPaste.vi.cs index 93e383cb08f..1f894a72fea 100644 --- a/src/Microsoft.PowerShell.PSReadLine/YankPaste.vi.cs +++ b/src/Microsoft.PowerShell.PSReadLine/YankPaste.vi.cs @@ -1,5 +1,5 @@ /********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; diff --git a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj index 31187624128..267db6412c9 100644 --- a/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj +++ b/src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj @@ -15,17 +15,21 @@ - - + + + + - - - - - - + + + + + + + + diff --git a/src/Microsoft.PowerShell.ScheduledJob/AssemblyInfo.cs b/src/Microsoft.PowerShell.ScheduledJob/AssemblyInfo.cs index 8be32293508..08853e30b8b 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/AssemblyInfo.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/AssemblyInfo.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System.Reflection; using System.Resources; diff --git a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJob.cs b/src/Microsoft.PowerShell.ScheduledJob/ScheduledJob.cs index c9835bde440..5754ed682cf 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJob.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/ScheduledJob.cs @@ -1,6 +1,6 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -335,7 +335,6 @@ public override void UnblockJobAsync() throw new PSNotSupportedException(); } - /// /// StopJob /// @@ -375,7 +374,6 @@ public override void SuspendJobAsync(bool force, string reason) throw new PSNotSupportedException(); } - #endregion #region Implementation of ISerializable diff --git a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobDefinition.cs b/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobDefinition.cs index 9f678ec597f..a0485ed55c3 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobDefinition.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobDefinition.cs @@ -1,6 +1,6 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.Collections.ObjectModel; using System.Collections.Generic; @@ -42,7 +42,7 @@ public sealed class ScheduledJobDefinition : ISerializable, IDisposable private bool _isDisposed; // Task Action strings. - private const string TaskExecutionPath = @"powershell.exe"; + private const string TaskExecutionPath = @"pwsh.exe"; private const string TaskArguments = @"-NoLogo -NonInteractive -WindowStyle Hidden -Command ""Import-Module PSScheduledJob; $jobDef = [Microsoft.PowerShell.ScheduledJob.ScheduledJobDefinition]::LoadFromStore('{0}', '{1}'); $jobDef.Run()"""; private static object LockObject = new object(); private static int CurrentId = 0; diff --git a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobOptions.cs b/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobOptions.cs index 2fa6bd0505c..858288f3c4c 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobOptions.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobOptions.cs @@ -1,6 +1,6 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.Collections.Generic; using System.Linq; diff --git a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobSourceAdapter.cs b/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobSourceAdapter.cs index 328625d49fc..5e14b5f12c7 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobSourceAdapter.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobSourceAdapter.cs @@ -1,6 +1,6 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.Collections.Generic; using System.Collections.ObjectModel; diff --git a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobStore.cs b/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobStore.cs index 68bc4f14022..a145b5b5c16 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobStore.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobStore.cs @@ -1,6 +1,6 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.Collections.Generic; using System.Collections.ObjectModel; diff --git a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobTrigger.cs b/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobTrigger.cs index 9e0dbfd47c4..9daebe32810 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobTrigger.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobTrigger.cs @@ -1,6 +1,6 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.Collections.Generic; using System.Collections.ObjectModel; diff --git a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobWTS.cs b/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobWTS.cs index 3aec4228383..36713a7a885 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobWTS.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/ScheduledJobWTS.cs @@ -1,6 +1,6 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.Collections.Generic; using System.Collections.ObjectModel; diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/AddJobTrigger.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/AddJobTrigger.cs index dee94eeb212..4837a664865 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/AddJobTrigger.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/commands/AddJobTrigger.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/DisableJobDefinition.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/DisableJobDefinition.cs index 0c8f97fe19c..bd1ed864a14 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/DisableJobDefinition.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/commands/DisableJobDefinition.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/DisableJobDefinitionBase.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/DisableJobDefinitionBase.cs index 0fb83a2a642..a6f7f037ed2 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/DisableJobDefinitionBase.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/commands/DisableJobDefinitionBase.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/DisableJobTrigger.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/DisableJobTrigger.cs index 2c80beb7cdb..ebc4db8774c 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/DisableJobTrigger.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/commands/DisableJobTrigger.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/EnableDisableCmdletBase.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/EnableDisableCmdletBase.cs index 2d4f6a51a61..f51ceced32f 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/EnableDisableCmdletBase.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/commands/EnableDisableCmdletBase.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/EnableJobDefinition.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/EnableJobDefinition.cs index 4bcd6eedb7c..67584690694 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/EnableJobDefinition.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/commands/EnableJobDefinition.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/EnableJobTrigger.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/EnableJobTrigger.cs index 023591ad4f1..494fd080811 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/EnableJobTrigger.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/commands/EnableJobTrigger.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/GetJobDefinition.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/GetJobDefinition.cs index e138a570475..fb1539f6bad 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/GetJobDefinition.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/commands/GetJobDefinition.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/GetJobTrigger.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/GetJobTrigger.cs index ab1b05e9494..dc188dc0676 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/GetJobTrigger.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/commands/GetJobTrigger.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/GetScheduledJobOption.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/GetScheduledJobOption.cs index f8eb680db93..07058f03a72 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/GetScheduledJobOption.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/commands/GetScheduledJobOption.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/NewJobTrigger.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/NewJobTrigger.cs index 27ffc5a8006..f7a83d88c92 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/NewJobTrigger.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/commands/NewJobTrigger.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/NewScheduledJobOption.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/NewScheduledJobOption.cs index d6ec042cd73..55fb9a4c0bd 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/NewScheduledJobOption.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/commands/NewScheduledJobOption.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/RegisterJobDefinition.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/RegisterJobDefinition.cs index d49b4c071fd..cb8e47aa228 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/RegisterJobDefinition.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/commands/RegisterJobDefinition.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; @@ -27,12 +26,12 @@ public sealed class RegisterScheduledJobCommand : ScheduleJobCmdletBase private const string FilePathParameterSet = "FilePath"; private const string ScriptBlockParameterSet = "ScriptBlock"; - /// /// File path for script to be run in job. /// [Parameter(Position = 1, Mandatory = true, ParameterSetName = RegisterScheduledJobCommand.FilePathParameterSet)] + [Alias("Path")] [ValidateNotNullOrEmpty] public string FilePath { diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/RemoveJobTrigger.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/RemoveJobTrigger.cs index b3a487bd367..2456b46de6e 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/RemoveJobTrigger.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/commands/RemoveJobTrigger.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/SchedJobCmdletBase.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/SchedJobCmdletBase.cs index 17568de908d..6021aa6ea97 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/SchedJobCmdletBase.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/commands/SchedJobCmdletBase.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/ScheduledJobOptionCmdletBase.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/ScheduledJobOptionCmdletBase.cs index dc506b92491..89571e90e56 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/ScheduledJobOptionCmdletBase.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/commands/ScheduledJobOptionCmdletBase.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/SetJobDefinition.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/SetJobDefinition.cs index eb044874995..b94dd190d36 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/SetJobDefinition.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/commands/SetJobDefinition.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; @@ -26,7 +25,6 @@ public sealed class SetScheduledJobCommand : ScheduleJobCmdletBase private const string ScriptBlockParameterSet = "ScriptBlock"; private const string FilePathParameterSet = "FilePath"; - /// /// Name of scheduled job definition. /// @@ -44,6 +42,7 @@ public string Name /// File path for script to be run in job. /// [Parameter(ParameterSetName = SetScheduledJobCommand.FilePathParameterSet)] + [Alias("Path")] [ValidateNotNullOrEmpty] public string FilePath { diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/SetJobTrigger.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/SetJobTrigger.cs index cea8cf487ce..7a365ea12d2 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/SetJobTrigger.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/commands/SetJobTrigger.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/SetScheduledJobOption.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/SetScheduledJobOption.cs index 917d6c187f4..3ebe841629d 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/SetScheduledJobOption.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/commands/SetScheduledJobOption.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.ScheduledJob/commands/UnregisterJobDefinition.cs b/src/Microsoft.PowerShell.ScheduledJob/commands/UnregisterJobDefinition.cs index 2f85e7d3eb9..bde525a2944 100644 --- a/src/Microsoft.PowerShell.ScheduledJob/commands/UnregisterJobDefinition.cs +++ b/src/Microsoft.PowerShell.ScheduledJob/commands/UnregisterJobDefinition.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections.Generic; diff --git a/src/Microsoft.PowerShell.Security/security/AclCommands.cs b/src/Microsoft.PowerShell.Security/security/AclCommands.cs index 3d1a73f6358..40cf6aa33da 100644 --- a/src/Microsoft.PowerShell.Security/security/AclCommands.cs +++ b/src/Microsoft.PowerShell.Security/security/AclCommands.cs @@ -1,8 +1,5 @@ -#pragma warning disable 1634, 1691 - -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #pragma warning disable 1634, 1691 #pragma warning disable 56506 @@ -107,7 +104,6 @@ internal CmdletProviderContext CmdletProviderContext } } // CmdletProviderContext - #region brokered properties /// diff --git a/src/Microsoft.PowerShell.Security/security/CatalogCommands.cs b/src/Microsoft.PowerShell.Security/security/CatalogCommands.cs index aa6c222fdf6..08051337a53 100644 --- a/src/Microsoft.PowerShell.Security/security/CatalogCommands.cs +++ b/src/Microsoft.PowerShell.Security/security/CatalogCommands.cs @@ -1,8 +1,7 @@ -#if !UNIX +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +#if !UNIX using System; using System.Management.Automation; @@ -95,7 +94,7 @@ protected override void ProcessRecord() { foreach (PathInfo tempPath in SessionState.Path.GetResolvedPSPathFromPSPath(p)) { - if (ShouldProcess(tempPath.ProviderPath)) + if (ShouldProcess("Including path " + tempPath.ProviderPath, "", "")) { paths.Add(tempPath.ProviderPath); } @@ -103,17 +102,16 @@ protected override void ProcessRecord() } } - // We add 'paths.Count > 0' to support 'ShouldProcess()' - if (paths.Count > 0 ) - { - string drive = null; + string drive = null; - // resolve catalog destination Path - if (!SessionState.Path.IsPSAbsolute(catalogFilePath, out drive) && !System.IO.Path.IsPathRooted(catalogFilePath)) - { - catalogFilePath = SessionState.Path.GetUnresolvedProviderPathFromPSPath(catalogFilePath); - } + // resolve catalog destination Path + if (!SessionState.Path.IsPSAbsolute(catalogFilePath, out drive) && !System.IO.Path.IsPathRooted(catalogFilePath)) + { + catalogFilePath = SessionState.Path.GetUnresolvedProviderPathFromPSPath(catalogFilePath); + } + if (ShouldProcess(catalogFilePath)) + { PerformAction(paths, catalogFilePath); } } diff --git a/src/Microsoft.PowerShell.Security/security/CertificateCommands.cs b/src/Microsoft.PowerShell.Security/security/CertificateCommands.cs index bc753548268..d748526894f 100644 --- a/src/Microsoft.PowerShell.Security/security/CertificateCommands.cs +++ b/src/Microsoft.PowerShell.Security/security/CertificateCommands.cs @@ -1,7 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using Dbg = System.Management.Automation.Diagnostics; @@ -64,12 +62,23 @@ public string[] LiteralPath } private bool _isLiteralPath = false; + /// + /// Gets or sets the password for unlocking the certificate. + /// + [Parameter(Mandatory = false)] + public SecureString Password { get; set; } + + /// + /// Do not prompt for password if not given. + /// + [Parameter(Mandatory = false)] + public SwitchParameter NoPromptForPassword { get; set; } + // // list of files that were not found // private ArrayList _filesNotFound = new ArrayList(); - /// /// Initializes a new instance of the GetPfxCertificateCommand /// class @@ -123,54 +132,41 @@ protected override void ProcessRecord() string resolvedProviderPath = SecurityUtils.GetFilePathOfExistingFile(this, resolvedPath); - if (resolvedProviderPath == null) { _filesNotFound.Add(p); } else { + if (Password == null && !NoPromptForPassword.IsPresent) + { + try + { + cert = GetCertFromPfxFile(resolvedProviderPath, null); + WriteObject(cert); + continue; + } + catch (CryptographicException) + { + Password = SecurityUtils.PromptForSecureString( + Host.UI, + CertificateCommands.GetPfxCertPasswordPrompt); + } + } + try { - cert = GetCertFromPfxFile(resolvedProviderPath); + cert = GetCertFromPfxFile(resolvedProviderPath, Password); } - catch (CryptographicException) + catch (CryptographicException e) { - // - // CryptographicException is thrown when any error - // occurs inside the crypto class library. It has a - // protected member HResult that indicates the exact - // error but it is not available outside the class. - // Thus we have to assume that the above exception - // was thrown because the pfx file is password - // protected. - // - SecureString password = null; - - string prompt = null; - prompt = CertificateCommands.GetPfxCertPasswordPrompt; - - password = SecurityUtils.PromptForSecureString(Host.UI, prompt); - try - { - cert = GetCertFromPfxFile(resolvedProviderPath, - password); - } - catch (CryptographicException e) - { - // - // since we cannot really figure out the - // meaning of a given CryptographicException - // we have to use NotSpecified category here - // - ErrorRecord er = - new ErrorRecord(e, - "GetPfxCertificateUnknownCryptoError", - ErrorCategory.NotSpecified, - null); - WriteError(er); - continue; - } + ErrorRecord er = + new ErrorRecord(e, + "GetPfxCertificateUnknownCryptoError", + ErrorCategory.NotSpecified, + null); + WriteError(er); + continue; } WriteObject(cert); @@ -210,12 +206,6 @@ protected override void ProcessRecord() } } - private static X509Certificate2 GetCertFromPfxFile(string path) - { - X509Certificate2 cert = new X509Certificate2(path); - return cert; - } - private static X509Certificate2 GetCertFromPfxFile(string path, SecureString password) { var cert = new X509Certificate2(path, password, X509KeyStorageFlags.DefaultKeySet); diff --git a/src/Microsoft.PowerShell.Security/security/CertificateProvider.cs b/src/Microsoft.PowerShell.Security/security/CertificateProvider.cs index b282a3510f1..01e2db04f11 100644 --- a/src/Microsoft.PowerShell.Security/security/CertificateProvider.cs +++ b/src/Microsoft.PowerShell.Security/security/CertificateProvider.cs @@ -1,7 +1,7 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #if !UNIX -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ using System; using System.Management.Automation; @@ -614,7 +614,6 @@ public CertificateProvider() } } // constructor - /// /// Removes an item at the specified path /// @@ -1321,7 +1320,6 @@ private void AttemptToImportPkiModule() return; } - CommandInfo commandInfo = new CmdletInfo( "Import-Module", @@ -1369,7 +1367,6 @@ private string MyGetChildName(string path) int separatorIndex = path.LastIndexOf(StringLiterals.DefaultPathSeparator); - // Since there was no path separator return the entire path if (separatorIndex == -1) { @@ -2218,7 +2215,6 @@ protected override void GetChildNames( GetChildItemsOrNames(path, false, returnContainers, true, GetFilter()); } // GetChildNames - /// /// Determines if the item at the specified path is a store /// or location. @@ -2877,7 +2873,6 @@ string ICmdletProviderSupportsHelp.GetHelpMaml(string helpItemName, string path) nsMgr.AddNamespace("msh", HelpCommentsParser.mshURI); nsMgr.AddNamespace("command", HelpCommentsParser.commandURI); - // Compose XPath query to select the appropriate node based on the cmdlet string xpathQuery = String.Format( CultureInfo.InvariantCulture, @@ -3245,7 +3240,6 @@ public sealed class EnhancedKeyUsageProperty { private List _ekuList = new List(); - /// /// get property of EKUList /// @@ -3371,7 +3365,6 @@ public DnsNameProperty(X509Certificate2 cert) } } - /// /// downlevel helper function to determine if the OS is WIN8 and above /// @@ -3525,7 +3518,6 @@ internal static List GetStoreNamesAtLocation(StoreLocation location) Security.NativeMethods.CertEnumSystemStoreCallBackProto callBack = new Security.NativeMethods.CertEnumSystemStoreCallBackProto(CertEnumSystemStoreCallBack); - // Return a new list to avoid synchronization issues. List names = new List(); @@ -3544,7 +3536,6 @@ internal static List GetStoreNamesAtLocation(StoreLocation location) return names; } - /// /// call back function used by CertEnumSystemStore /// diff --git a/src/Microsoft.PowerShell.Security/security/CmsCommands.cs b/src/Microsoft.PowerShell.Security/security/CmsCommands.cs index 40ca423458e..944d14ae46b 100644 --- a/src/Microsoft.PowerShell.Security/security/CmsCommands.cs +++ b/src/Microsoft.PowerShell.Security/security/CmsCommands.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; @@ -228,7 +227,6 @@ public string LiteralPath } private string _resolvedPath = null; - /// /// Validate / convert arguments /// @@ -438,7 +436,6 @@ protected override void BeginProcessing() } } - /// /// Processes records from the input pipeline. /// For each input object, the command gets the information diff --git a/src/Microsoft.PowerShell.Security/security/CredentialCommands.cs b/src/Microsoft.PowerShell.Security/security/CredentialCommands.cs index cc5a871fbb1..cdf7a3ce4c4 100644 --- a/src/Microsoft.PowerShell.Security/security/CredentialCommands.cs +++ b/src/Microsoft.PowerShell.Security/security/CredentialCommands.cs @@ -1,11 +1,9 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; - namespace Microsoft.PowerShell.Commands { /// diff --git a/src/Microsoft.PowerShell.Security/security/ExecutionPolicyCommands.cs b/src/Microsoft.PowerShell.Security/security/ExecutionPolicyCommands.cs index 47a998f15d1..f0c318021af 100644 --- a/src/Microsoft.PowerShell.Security/security/ExecutionPolicyCommands.cs +++ b/src/Microsoft.PowerShell.Security/security/ExecutionPolicyCommands.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. #region Using directives diff --git a/src/Microsoft.PowerShell.Security/security/SecureStringCommands.cs b/src/Microsoft.PowerShell.Security/security/SecureStringCommands.cs index 9dd8e96fb8e..83b40529c96 100644 --- a/src/Microsoft.PowerShell.Security/security/SecureStringCommands.cs +++ b/src/Microsoft.PowerShell.Security/security/SecureStringCommands.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.IO; @@ -199,7 +198,6 @@ protected override void ProcessRecord() } } - /// /// Defines the implementation of the 'ConvertTo-SecureString' cmdlet. /// This cmdlet imports a new SecureString from encrypted data -- @@ -278,7 +276,6 @@ public SwitchParameter Force } private bool _force; - /// /// Processes records from the input pipeline. /// For each input object, the command decrypts the data, diff --git a/src/Microsoft.PowerShell.Security/security/SignatureCommands.cs b/src/Microsoft.PowerShell.Security/security/SignatureCommands.cs index 1e6a3ae6a04..b7a3e1cb856 100644 --- a/src/Microsoft.PowerShell.Security/security/SignatureCommands.cs +++ b/src/Microsoft.PowerShell.Security/security/SignatureCommands.cs @@ -1,7 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ - +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Management.Automation; diff --git a/src/Microsoft.PowerShell.Security/security/Utils.cs b/src/Microsoft.PowerShell.Security/security/Utils.cs index f9e9c1842ff..2f865bbb739 100644 --- a/src/Microsoft.PowerShell.Security/security/Utils.cs +++ b/src/Microsoft.PowerShell.Security/security/Utils.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.IO; @@ -157,7 +156,6 @@ ErrorRecord CreateNotSupportedErrorRecord(string resourceStr, return er; } - /// /// Create an error record for 'operation not supported' condition /// @@ -183,7 +181,6 @@ ErrorRecord CreateInvalidArgumentErrorRecord(Exception e, return er; } - /// /// convert the specified provider path to a provider path /// and make sure that all of the following is true: diff --git a/src/Microsoft.PowerShell.Security/security/certificateproviderexceptions.cs b/src/Microsoft.PowerShell.Security/security/certificateproviderexceptions.cs index ba21f0c351d..0a1f7372f2e 100644 --- a/src/Microsoft.PowerShell.Security/security/certificateproviderexceptions.cs +++ b/src/Microsoft.PowerShell.Security/security/certificateproviderexceptions.cs @@ -1,7 +1,7 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + #if !UNIX -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ using System; using System.Runtime.Serialization; diff --git a/src/Microsoft.PowerShell.Security/singleshell/installer/MshSecurityMshSnapin.cs b/src/Microsoft.PowerShell.Security/singleshell/installer/MshSecurityMshSnapin.cs index dbaa0e32c8e..43a3eb71411 100644 --- a/src/Microsoft.PowerShell.Security/singleshell/installer/MshSecurityMshSnapin.cs +++ b/src/Microsoft.PowerShell.Security/singleshell/installer/MshSecurityMshSnapin.cs @@ -1,6 +1,5 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. using System; using System.Collections; diff --git a/src/Microsoft.WSMan.Management/ConfigProvider.cs b/src/Microsoft.WSMan.Management/ConfigProvider.cs index a300e55085b..c4d01b9e3bc 100644 --- a/src/Microsoft.WSMan.Management/ConfigProvider.cs +++ b/src/Microsoft.WSMan.Management/ConfigProvider.cs @@ -1,6 +1,6 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.Collections.Generic; using System.Collections; @@ -176,7 +176,6 @@ string ICmdletProviderSupportsHelp.GetHelpMaml(string helpItemName, string path) #endregion - #region DriveCmdletProvider /// /// @@ -221,7 +220,6 @@ protected override PSDriveInfo RemoveDrive(PSDriveInfo drive) return drive; } - #endregion #region ItemCmdletProvider @@ -390,8 +388,6 @@ protected override bool HasChildItems(string path) object sessionobj; SessionObjCache.TryGetValue(host, out sessionobj); - - /* WsMan Config Can be divided in to Four Fixed Regions to Check Whether it has Child Items. @@ -574,7 +570,6 @@ protected override void GetItem(string path) return; } - if (path.Contains(WSManStringLiterals.DefaultPathSeparator.ToString())) { //Get the ChildName @@ -866,7 +861,6 @@ protected override void SetItem(string path, object value) return; } - if (path.Contains(WSManStringLiterals.DefaultPathSeparator.ToString())) { //Get the ChildName @@ -1353,7 +1347,6 @@ protected override object SetItemDynamicParameters(string path, object value) return null; } - #endregion #region ContainerCmdletProvider @@ -1426,8 +1419,6 @@ protected override bool IsItemContainer(string path) object sessionobj; SessionObjCache.TryGetValue(host, out sessionobj); - - /* WsMan Config Can be divided in to Four Fixed Regions to Check Whether Item is Container @@ -1491,7 +1482,6 @@ WsMan Config Can be divided in to Four Fixed Regions to Check Whether Item is Co strPathCheck = strPathCheck + WSManStringLiterals.DefaultPathSeparator; XmlDocument xmlPlugins = FindResourceValue(sessionobj, WsManURI, null); - string currentpluginname = string.Empty; GetPluginNames(xmlPlugins, out objPluginNames, out currentpluginname, path); strPathCheck = strPathCheck + currentpluginname; @@ -1616,7 +1606,6 @@ protected override void RemoveItem(string path, bool recurse) string host = GetHostName(path); string uri = NormalizePath(path, host); - //Chk for Winrm Service if (IsPathLocalMachine(host)) { @@ -1644,7 +1633,6 @@ protected override void RemoveItem(string path, bool recurse) string strPathCheck = String.Empty; strPathCheck = host + WSManStringLiterals.DefaultPathSeparator; - if (path.Contains(strPathCheck + WSManStringLiterals.containerPlugin))//(path.Contains(@"\plugin")) { if (path.EndsWith(strPathCheck + WSManStringLiterals.containerPlugin, StringComparison.OrdinalIgnoreCase)) @@ -1766,7 +1754,6 @@ protected override void NewItem(string path, string itemTypeName, object newItem return; } - if (path.Length == 0 || !path.Contains(WSManStringLiterals.DefaultPathSeparator.ToString())) { NewItemCreateComputerConnection(path); @@ -1797,7 +1784,6 @@ protected override void NewItem(string path, string itemTypeName, object newItem Dictionary SessionObjCache = WSManHelper.GetSessionObjCache(); SessionObjCache.TryGetValue(host, out sessionobj); - string strPathChk = host + WSManStringLiterals.DefaultPathSeparator; if (path.Contains(strPathChk + WSManStringLiterals.containerPlugin))//(path.Contains(@"\plugin")) { @@ -2069,7 +2055,6 @@ private void NewItemPluginOrPluginChild(object sessionobj, string path, string h string NewItem = String.Empty; string[] Keys = null; - int pos = path.LastIndexOf(strPathChk + WSManStringLiterals.DefaultPathSeparator, StringComparison.OrdinalIgnoreCase) + strPathChk.Length + 1; int pindex = path.IndexOf(WSManStringLiterals.DefaultPathSeparator, pos); if (pindex != -1) @@ -2089,7 +2074,6 @@ private void NewItemPluginOrPluginChild(object sessionobj, string path, string h ArrayList ResourceArray = ProcessPluginResourceLevel(pxml, out SecurityArray); ArrayList InitParamArray = ProcessPluginInitParamLevel(pxml); - strPathChk = strPathChk + WSManStringLiterals.DefaultPathSeparator + pName + WSManStringLiterals.DefaultPathSeparator; if (path.Contains(strPathChk + WSManStringLiterals.containerResources)) { @@ -2581,7 +2565,7 @@ private void PutResourceValue(object sessionobj, string ResourceURI, Hashtable v nsmgr.AddNamespace("cfg", uri_schema); string xpath = SetXPathString(ResourceURI); XmlNodeList nodelist = inputxml.SelectNodes(xpath, nsmgr); - if (nodelist.Count == 1 && nodelist != null) + if (nodelist != null && nodelist.Count == 1) { XmlNode node = (XmlNode)nodelist.Item(0); if (node.HasChildNodes) @@ -3734,7 +3718,6 @@ private void RemoveListenerOrCertMapping(object sessionobj, string WsManUri, str } } - /// /// Used By ItemExists, HasChildItem,IsValidPath, IsItemContainer /// @@ -3763,7 +3746,6 @@ private bool CheckValidContainerOrPath(string path) ChildName = path; } - //Get the wsman host name to find the session object string host = GetHostName(path); @@ -4065,7 +4047,6 @@ private void GetChildItemsOrNames(string path, ProviderMethods methodname, bool throw new InvalidOperationException("InvalidPath"); } - //Checks the WinRM Service if (IsPathLocalMachine(host)) { @@ -4230,8 +4211,6 @@ private void GetChildItemsOrNames(string path, ProviderMethods methodname, bool obj.Properties.Add(new PSNoteProperty(p.Properties["ResourceDir"].Value.ToString(), WSManStringLiterals.ContainerChildValue)); WritePSObjectPropertiesAsWSManElementObjects(obj, path, key, null, WsManElementObjectTypes.WSManConfigContainerElement, recurse); - - //WriteItemObject(new WSManConfigContainerElement(p.Properties["ResourceDir"].Value.ToString(), WSManStringLiterals.ContainerChildValue, key), path + WSManStringLiterals.DefaultPathSeparator + p.Properties["ResourceDir"].Value.ToString(), true); break; case ProviderMethods.GetChildNames: @@ -4585,7 +4564,6 @@ private void GenerateObjectNameAndKeys(Hashtable InputAttributes, string Resourc keys = keysColumns.Split('|'); } - private void ProcessCertMappingObjects(XmlDocument xmlCerts, out Hashtable Certcache, out Hashtable Keyscache) { Hashtable lCache = new Hashtable(); @@ -4790,7 +4768,6 @@ private ArrayList ProcessPluginResourceLevel(XmlDocument xmldoc, out ArrayList a objResource.Properties.Add(new PSNoteProperty("SupportsOptions", false)); } - //Processing capabilities XmlDocument xmlCapabilities = new XmlDocument(); @@ -5365,7 +5342,6 @@ public Hashtable OptionSet } private Hashtable optionset; - /// /// The following is the definition of the input parameter "Authentication". /// This parameter takes a set of authentication methods the user can select @@ -5793,7 +5769,6 @@ public bool Enabled } - #endregion #region Listener Dynamic Parameters @@ -5975,7 +5950,6 @@ public SwitchParameter Concatenate private SwitchParameter _concatenate = false; } - #endregion SetItemDynamicParameters #endregion @@ -6124,7 +6098,6 @@ internal static class WSManStringLiterals /// internal const string containerCertMapping = "Service/certmapping"; - /// /// Possible Values in Plugin Top Level XML /// @@ -6358,11 +6331,7 @@ public string[] Keys private string[] _keys; } - - #endregion "WsMan Output Objects" - } - diff --git a/src/Microsoft.WSMan.Management/CredSSP.cs b/src/Microsoft.WSMan.Management/CredSSP.cs index 29b71c14f3c..5112eee6026 100644 --- a/src/Microsoft.WSMan.Management/CredSSP.cs +++ b/src/Microsoft.WSMan.Management/CredSSP.cs @@ -1,6 +1,6 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.IO; using System.Reflection; @@ -99,7 +99,6 @@ internal IWSManSession CreateWSManSession() /// access a second hop /// - [Cmdlet(VerbsLifecycle.Disable, "WSManCredSSP", HelpUri = "https://go.microsoft.com/fwlink/?LinkId=141438")] [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cred")] [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SSP")] @@ -1005,14 +1004,7 @@ protected override void BeginProcessing() #endregion IDisposable Members - - - - } - - - #endregion } diff --git a/src/Microsoft.WSMan.Management/CurrentConfigurations.cs b/src/Microsoft.WSMan.Management/CurrentConfigurations.cs index 242fd613330..aeb78f97bb4 100644 --- a/src/Microsoft.WSMan.Management/CurrentConfigurations.cs +++ b/src/Microsoft.WSMan.Management/CurrentConfigurations.cs @@ -1,19 +1,5 @@ -//------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -// -// -// Pankaj Sarda -// -// -// -// Class that queries the server and gets current configurations. -// Also provides a generic way to update the configurations. -// -// -// -//------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. namespace Microsoft.WSMan.Management { diff --git a/src/Microsoft.WSMan.Management/Interop.cs b/src/Microsoft.WSMan.Management/Interop.cs index 7a15b30cc96..4d526f01501 100644 --- a/src/Microsoft.WSMan.Management/Interop.cs +++ b/src/Microsoft.WSMan.Management/Interop.cs @@ -1,6 +1,6 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.IO; using System.Reflection; @@ -22,8 +22,6 @@ namespace Microsoft.WSMan.Management #region "public Api" - - #region WsManEnumFlags /// _WSManEnumFlags enumeration. @@ -60,9 +58,6 @@ public enum WSManEnumFlags #endregion WsManEnumFlags - - - #region WsManSessionFlags /// WSManSessionFlags enumeration. /// @@ -388,7 +383,6 @@ void SetProxy(int accessType, int ProxyAuthenticationUseDigest(); }; - #endregion IWSManConnectionOptions #region IWSManEnumerator @@ -498,7 +492,6 @@ public interface IWSManEx object CreateSession([MarshalAs(UnmanagedType.BStr)] string connection, int flags, [MarshalAs(UnmanagedType.IDispatch)] object connectionOptions); #endif - /// CreateConnectionOptions method of IWSManEx interface. /// An original IDL definition of CreateConnectionOptions method was the following: HRESULT CreateConnectionOptions ([out, retval] IDispatch** ReturnValue); // IDL: HRESULT CreateConnectionOptions ([out, retval] IDispatch** ReturnValue); @@ -511,7 +504,6 @@ public interface IWSManEx #endif object CreateConnectionOptions(); - /// /// /// @@ -540,12 +532,10 @@ string Error get; } - /// CreateResourceLocator method of IWSManEx interface. /// An original IDL definition of CreateResourceLocator method was the following: HRESULT CreateResourceLocator ([optional, defaultvalue("")] BSTR strResourceLocator, [out, retval] IDispatch** ReturnValue); // IDL: HRESULT CreateResourceLocator ([optional, defaultvalue("")] BSTR strResourceLocator, [out, retval] IDispatch** ReturnValue); - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "str")] [DispId(5)] #if CORECLR @@ -567,7 +557,6 @@ string Error /// An original IDL definition of SessionFlagCredUsernamePassword method was the following: HRESULT SessionFlagCredUsernamePassword ([out, retval] long* ReturnValue); // IDL: HRESULT SessionFlagCredUsernamePassword ([out, retval] long* ReturnValue); - [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Username")] [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cred")] [DispId(7)] @@ -717,7 +706,6 @@ string Error [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings")] - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sel")] [Guid("A7A1BA28-DE41-466A-AD0A-C4059EAD7428")] @@ -729,7 +717,6 @@ string Error [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)] #endif - public interface IWSManResourceLocator { #if CORECLR @@ -775,7 +762,6 @@ string ResourceUri // Add selector to resource locator // IDL: HRESULT AddSelector (BSTR resourceSelName, VARIANT selValue); - [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "resource")] [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "sel")] [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sel")] @@ -787,8 +773,6 @@ string ResourceUri // Clear all selectors // IDL: HRESULT ClearSelectors (void); - - [DispId(3)] void ClearSelectors(); @@ -810,7 +794,6 @@ string FragmentPath set; } - /// FragmentDialect property of IWSManResourceLocator interface. Gets the Fragment dialect /// An original IDL definition of FragmentDialect property was the following: BSTR FragmentDialect; // Gets the Fragment dialect @@ -837,7 +820,6 @@ string FragmentDialect [DispId(6)] void AddOption([MarshalAs(UnmanagedType.BStr)] string OptionName, object OptionValue, int mustComply); - /// MustUnderstandOptions property of IWSManResourceLocator interface. Sets the MustUnderstandOptions value /// An original IDL definition of MustUnderstandOptions property was the following: long MustUnderstandOptions; // Sets the MustUnderstandOptions value @@ -855,7 +837,6 @@ int MustUnderstandOptions set; } - /// ClearOptions method of IWSManResourceLocator interface. Clear all options /// An original IDL definition of ClearOptions method was the following: HRESULT ClearOptions (void); // Clear all options @@ -864,8 +845,6 @@ int MustUnderstandOptions [DispId(8)] void ClearOptions(); - - /// Error property of IWSManResourceLocator interface. /// An original IDL definition of Error property was the following: BSTR Error; // IDL: BSTR Error; @@ -882,8 +861,6 @@ string Error get; } - - } #endregion IWsManResourceLocator @@ -922,7 +899,6 @@ public interface IWSManSession /// An original IDL definition of Get method was the following: HRESULT Get (VARIANT resourceUri, [optional, defaultvalue(0)] long flags, [out, retval] BSTR* ReturnValue); // IDL: HRESULT Get (VARIANT resourceUri, [optional, defaultvalue(0)] long flags, [out, retval] BSTR* ReturnValue); - [SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get")] [DispId(1)] [return: MarshalAs(UnmanagedType.BStr)] @@ -965,7 +941,6 @@ public interface IWSManSession [DispId(5)] String Invoke([MarshalAs(UnmanagedType.BStr)] string actionURI, [In] object resourceUri, [MarshalAs(UnmanagedType.BStr)] string parameters, [In] int flags); - /// Enumerate method of IWSManSession interface. /// An original IDL definition of Enumerate method was the following: HRESULT Enumerate (VARIANT resourceUri, [optional, defaultvalue("")] BSTR filter, [optional, defaultvalue("")] BSTR dialect, [optional, defaultvalue(0)] long flags, [out, retval] IDispatch** ReturnValue); // IDL: HRESULT Enumerate (VARIANT resourceUri, [optional, defaultvalue("")] BSTR filter, [optional, defaultvalue("")] BSTR dialect, [optional, defaultvalue(0)] long flags, [out, retval] IDispatch** ReturnValue); @@ -1001,7 +976,6 @@ string Error get; } - /// BatchItems property of IWSManSession interface. /// An original IDL definition of BatchItems property was the following: long BatchItems; // IDL: long BatchItems; @@ -1018,7 +992,6 @@ int BatchItems set; } - /// Timeout property of IWSManSession interface. /// An original IDL definition of Timeout property was the following: long Timeout; // IDL: long Timeout; @@ -1068,7 +1041,6 @@ public interface IWSManResourceLocatorInternal #endregion IWSManResourceLocatorInternal - /// WSMan interface. [Guid("BCED617B-EC03-420b-8508-977DC7A686BD")] [ComImport] diff --git a/src/Microsoft.WSMan.Management/InvokeWSManAction.cs b/src/Microsoft.WSMan.Management/InvokeWSManAction.cs index 24e15016f1b..556131af998 100644 --- a/src/Microsoft.WSMan.Management/InvokeWSManAction.cs +++ b/src/Microsoft.WSMan.Management/InvokeWSManAction.cs @@ -1,6 +1,6 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.IO; using System.Reflection; @@ -14,8 +14,6 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; - - namespace Microsoft.WSMan.Management { /// @@ -103,6 +101,7 @@ public Uri ConnectionURI /// via this input file /// [Parameter] + [Alias("Path")] [ValidateNotNullOrEmpty] public String FilePath { @@ -206,7 +205,6 @@ public Hashtable ValueSet } private Hashtable valueset; - /// /// The following is the definition of the input parameter "ResourceURI". /// URI of the resource class/instance representation @@ -223,13 +221,11 @@ public Uri ResourceURI } private Uri resourceuri; - private WSManHelper helper; IWSManEx m_wsmanObject = (IWSManEx)new WSManClass(); IWSManSession m_session = null; string connectionStr = string.Empty; - /// /// BeginProcessing method. /// @@ -242,7 +238,6 @@ protected override void BeginProcessing() //create the connection string connectionStr = helper.CreateConnectionString(connectionuri, port, computername, applicationname); - } /// @@ -251,7 +246,6 @@ protected override void BeginProcessing() protected override void ProcessRecord() { - try { //create the resourcelocator object @@ -321,9 +315,5 @@ protected override void EndProcessing() } - - - - }//End Class } diff --git a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj index 1d4f4e581b6..dc066a3ca10 100644 --- a/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj +++ b/src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj @@ -8,7 +8,8 @@ - + + diff --git a/src/Microsoft.WSMan.Management/NewWSManSession.cs b/src/Microsoft.WSMan.Management/NewWSManSession.cs index 5d44cf29361..c927bbc88a7 100644 --- a/src/Microsoft.WSMan.Management/NewWSManSession.cs +++ b/src/Microsoft.WSMan.Management/NewWSManSession.cs @@ -1,6 +1,6 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.IO; using System.Reflection; @@ -15,8 +15,6 @@ using System.Diagnostics.CodeAnalysis; using System.Net; - - namespace Microsoft.WSMan.Management { /// @@ -28,7 +26,6 @@ namespace Microsoft.WSMan.Management /// Connect-WSMan /// - [Cmdlet(VerbsCommon.New, "WSManSessionOption", HelpUri = "https://go.microsoft.com/fwlink/?LinkId=141449")] public class NewWSManSessionOptionCommand : PSCmdlet { @@ -87,7 +84,6 @@ public PSCredential ProxyCredential } private PSCredential _proxycredential; - /// /// The following is the definition of the input parameter "SkipCACheck". /// When connecting over HTTPS, the client does not validate that the server @@ -211,10 +207,6 @@ public SwitchParameter UseUTF16 } private bool useutf16; - - - - /// /// BeginProcessing method. /// @@ -241,8 +233,6 @@ protected override void BeginProcessing() return; } - - //Creating the Session Object SessionOption objSessionOption = new SessionOption(); diff --git a/src/Microsoft.WSMan.Management/PingWSMan.cs b/src/Microsoft.WSMan.Management/PingWSMan.cs index 60ed743868f..66dd6800b28 100644 --- a/src/Microsoft.WSMan.Management/PingWSMan.cs +++ b/src/Microsoft.WSMan.Management/PingWSMan.cs @@ -1,6 +1,6 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.IO; using System.Reflection; @@ -14,7 +14,6 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; - namespace Microsoft.WSMan.Management { @@ -124,7 +123,6 @@ public String ApplicationName } private String applicationname = null; - /// /// ProcessRecord method. /// diff --git a/src/Microsoft.WSMan.Management/Set-QuickConfig.cs b/src/Microsoft.WSMan.Management/Set-QuickConfig.cs index 240a25765b7..c7378949be1 100644 --- a/src/Microsoft.WSMan.Management/Set-QuickConfig.cs +++ b/src/Microsoft.WSMan.Management/Set-QuickConfig.cs @@ -1,6 +1,6 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.IO; using System.Reflection; @@ -14,7 +14,6 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; - namespace Microsoft.WSMan.Management { #region Set-WsManQuickConfig @@ -91,11 +90,8 @@ protected override void BeginProcessing() QuickConfigRemoting(false); }//End BeginProcessing() - - #region private - private void QuickConfigRemoting(bool serviceonly) { IWSManSession m_SessionObj = null; @@ -112,7 +108,6 @@ private void QuickConfigRemoting(bool serviceonly) string xpathStatus = string.Empty; string xpathResult = string.Empty; - if (!usessl) { transport = "http"; @@ -134,7 +129,6 @@ private void QuickConfigRemoting(bool serviceonly) action = "Analyze"; } - string analysisOutputXml = m_SessionObj.Invoke(action, "winrm/config/service", analysisInputXml, 0); XmlDocument resultopxml = new XmlDocument(); resultopxml.LoadXml(analysisOutputXml); @@ -152,8 +146,6 @@ private void QuickConfigRemoting(bool serviceonly) xpathUpdate = "/cfg:Analyze_OUTPUT/cfg:EnableRemoting_INPUT"; } - - XmlNamespaceManager nsmgr = new XmlNamespaceManager(resultopxml.NameTable); nsmgr.AddNamespace("cfg", "http://schemas.microsoft.com/wbem/wsman/1/config/service"); string enabled = resultopxml.SelectSingleNode(xpathEnabled, nsmgr).InnerText; diff --git a/src/Microsoft.WSMan.Management/WSManConnections.cs b/src/Microsoft.WSMan.Management/WSManConnections.cs index 642b6a0c09d..b63d3d5d2e1 100644 --- a/src/Microsoft.WSMan.Management/WSManConnections.cs +++ b/src/Microsoft.WSMan.Management/WSManConnections.cs @@ -1,6 +1,6 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.IO; using System.Reflection; @@ -16,7 +16,6 @@ using System.Diagnostics.CodeAnalysis; using Dbg = System.Management.Automation; - namespace Microsoft.WSMan.Management { #region Base class for cmdlets taking credential, authentication, certificatethumbprint @@ -227,8 +226,6 @@ public SwitchParameter UseSSL } private SwitchParameter usessl; - - #endregion /// @@ -356,8 +353,6 @@ protected override void BeginProcessing() } }//End BeginProcessing() - - }//End Class #endregion Disconnect-WSMAN } diff --git a/src/Microsoft.WSMan.Management/WSManInstance.cs b/src/Microsoft.WSMan.Management/WSManInstance.cs index 99bc67cdf6f..4bbcfcba4b2 100644 --- a/src/Microsoft.WSMan.Management/WSManInstance.cs +++ b/src/Microsoft.WSMan.Management/WSManInstance.cs @@ -1,6 +1,6 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.IO; using System.Reflection; @@ -17,7 +17,6 @@ using Dbg = System.Management.Automation; using System.Globalization; - namespace Microsoft.WSMan.Management { #region Get-WSManInstance @@ -579,7 +578,6 @@ protected override void ProcessRecord() #endregion IDisposable Members - /// /// BeginProcessing method. /// @@ -589,7 +587,6 @@ protected override void EndProcessing() helper.CleanUp(); } - } #endregion @@ -677,6 +674,7 @@ public Uri Dialect /// via this input file /// [Parameter(ValueFromPipelineByPropertyName = true)] + [Alias("Path")] [ValidateNotNullOrEmpty] public string FilePath { @@ -685,7 +683,6 @@ public string FilePath } private string filepath; - /// /// The following is the definition of the input parameter "Fragment". /// Specifies a section inside the instance that is to be updated or retrieved @@ -816,8 +813,6 @@ public Hashtable ValueSet } private Hashtable valueset; - - #endregion private WSManHelper helper ; @@ -831,7 +826,6 @@ protected override void ProcessRecord() helper.WSManOp = "set"; IWSManSession m_session = null; - if (dialect != null) { if (dialect.ToString().Equals(helper.ALIAS_WQL, StringComparison.CurrentCultureIgnoreCase)) @@ -941,11 +935,8 @@ protected override void EndProcessing() } - - #endregion - #region Remove-WsManInstance /// @@ -1111,12 +1102,8 @@ public SwitchParameter UseSSL } private SwitchParameter usessl; - - - #endregion - /// /// ProcessRecord method. /// @@ -1200,10 +1187,8 @@ protected override void ProcessRecord() #endregion IDisposable Members - } - #endregion #region New-WsManInstance @@ -1274,6 +1259,7 @@ public Uri ConnectionURI /// [Parameter] [ValidateNotNullOrEmpty] + [Alias("Path")] public String FilePath { get { return filepath; } @@ -1418,7 +1404,6 @@ protected override void BeginProcessing() }//End BeginProcessing() - /// /// ProcessRecord method. /// diff --git a/src/Microsoft.WSMan.Management/WsManHelper.cs b/src/Microsoft.WSMan.Management/WsManHelper.cs index d33423ddf00..45e906510dc 100644 --- a/src/Microsoft.WSMan.Management/WsManHelper.cs +++ b/src/Microsoft.WSMan.Management/WsManHelper.cs @@ -1,6 +1,6 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.Collections.Generic; using System.Text; @@ -88,7 +88,6 @@ internal class WSManHelper private static ResourceManager _resourceMgr = new ResourceManager("Microsoft.WSMan.Management.resources.WsManResources", typeof(WSManHelper).GetTypeInfo().Assembly); - // // //Below class is just a static container which would release sessions in case this DLL is unloaded. @@ -109,7 +108,6 @@ internal class Sessions // // - internal static void ReleaseSessions() { lock (Sessions.SessionObjCache) @@ -200,7 +198,6 @@ static private string FormatResourceMsgFromResourcetextS( return result; } - /// /// add a session to dictionary /// @@ -495,20 +492,7 @@ internal string ProcessInput(IWSManEx wsman, string filepath, string operation, internal string GetXmlNs(string resUri) { - - string tmpNs = null; - - if (resUri.ToLowerInvariant().Contains(URI_IPMI) || (resUri.ToLowerInvariant().Contains(URI_WMI))) - tmpNs = StripParams(resUri); - else - { - //tmpNs = StripParams(resUri) + ".xsd"; - //This was reported by Intel as an interop issue. So now we are not appending a .xsd in the end. - tmpNs = StripParams(resUri); - } - - return (@"xmlns:p=""" + tmpNs + @""""); - + return (@"xmlns:p=""" + StripParams(resUri) + @""""); } internal XmlNode GetXmlNode(string xmlString, string xpathpattern, string xmlnamespace) @@ -581,7 +565,6 @@ internal IWSManResourceLocator InitializeResourceLocator(Hashtable optionset, Ha { m_resource = (IWSManResourceLocator)wsmanObj.CreateResourceLocator(resource); - if (optionset != null) { foreach (DictionaryEntry entry in optionset) @@ -778,7 +761,6 @@ internal IWSManSession CreateSessionObject(IWSManEx wsmanObject, AuthenticationM connObject.SetProxy((int)sessionoption.ProxyAccessType, (int)sessionoption.ProxyAuthentication, null, null); } - } if (sessionoption.SkipCACheck) { @@ -843,7 +825,6 @@ internal IWSManSession CreateSessionObject(IWSManEx wsmanObject, AuthenticationM internal void CleanUp() { - if (_sr != null) { _sr.Dispose(); @@ -1110,7 +1091,6 @@ internal static void LoadResourceData() throw (e); } - } /// @@ -1139,6 +1119,5 @@ internal static string GetResourceString(string Key) /// private static Dictionary ResourceValueCache = new Dictionary(); - } } diff --git a/src/Microsoft.WSMan.Management/WsManSnapin.cs b/src/Microsoft.WSMan.Management/WsManSnapin.cs index b9741220403..8f7ed601778 100644 --- a/src/Microsoft.WSMan.Management/WsManSnapin.cs +++ b/src/Microsoft.WSMan.Management/WsManSnapin.cs @@ -1,6 +1,6 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.Diagnostics; using System.Text; diff --git a/src/Microsoft.WSMan.Management/resources/WsManResources.txt b/src/Microsoft.WSMan.Management/resources/WsManResources.txt index 7599a12ece2..fd0bd37eb74 100644 --- a/src/Microsoft.WSMan.Management/resources/WsManResources.txt +++ b/src/Microsoft.WSMan.Management/resources/WsManResources.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2008 Microsoft Corporation +# Copyright (c) Microsoft Corporation. All rights reserved. # {0} = Delegate @@ -11,8 +11,8 @@ NoResourceMatch=This command cannot be used because the parameter does not match MultipleResourceMatch=This command cannot be used because the parameter matches multiple properties on the ResourceURI.Check the input parameters and run your command. NoAttributeMatch=This command cannot be used because the parameter matches a non-text property on the ResourceURI.Check the input parameters and run your command. WinrmNotConfigured=This command cannot be used because the configuration is corrupted. Run WinRM invoke Restore WinRM/config to restore the default configuration -DelegateFreshCred=The machine is configured to allow delegating fresh credentials to the following target(s): -NoDelegateFreshCred=The machine is not configured to allow delegating fresh credentials. +DelegateFreshCred=The machine is configured to allow delegating fresh credentials to the following target(s): +NoDelegateFreshCred=The machine is not configured to allow delegating fresh credentials. LocalHost=This command cannot be used to remove the computer 'localhost' because it will always be connected. Give some other connected computer and run your command. ConnectFailure=This command cannot be used from the current path. Move to root path of the provider using cd\\ and run your command again. DisconnectFailure=This command cannot be used from the current path. Move to root path of the provider using cd\\ and run your command again. diff --git a/src/Microsoft.WSMan.Runtime/WSManSessionOption.cs b/src/Microsoft.WSMan.Runtime/WSManSessionOption.cs index 9c187e9bc10..0477dcc7aee 100644 --- a/src/Microsoft.WSMan.Runtime/WSManSessionOption.cs +++ b/src/Microsoft.WSMan.Runtime/WSManSessionOption.cs @@ -1,6 +1,6 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + using System; using System.IO; using System.Xml; @@ -16,10 +16,6 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; - - - - [assembly: CLSCompliant(true)] namespace Microsoft.WSMan.Management { diff --git a/src/Modules/PSGalleryModules.csproj b/src/Modules/PSGalleryModules.csproj new file mode 100644 index 00000000000..6d0ed858cb8 --- /dev/null +++ b/src/Modules/PSGalleryModules.csproj @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/Modules/Shared/Microsoft.PowerShell.Host/Microsoft.PowerShell.Host.psd1 b/src/Modules/Shared/Microsoft.PowerShell.Host/Microsoft.PowerShell.Host.psd1 index 4d07a73f9c0..56bb9287184 100644 --- a/src/Modules/Shared/Microsoft.PowerShell.Host/Microsoft.PowerShell.Host.psd1 +++ b/src/Modules/Shared/Microsoft.PowerShell.Host/Microsoft.PowerShell.Host.psd1 @@ -1,8 +1,8 @@ @{ GUID="56D66100-99A0-4FFC-A12D-EEE9A6718AEF" -Author="Microsoft Corporation" +Author="PowerShell" CompanyName="Microsoft Corporation" -Copyright="(c) Microsoft Corporation. All rights reserved." +Copyright="Copyright (c) Microsoft Corporation. All rights reserved." ModuleVersion="3.0.0.0" PowerShellVersion="3.0" CLRVersion="4.0" @@ -10,5 +10,5 @@ AliasesToExport = @() FunctionsToExport = @() CmdletsToExport="Start-Transcript", "Stop-Transcript" NestedModules="Microsoft.PowerShell.ConsoleHost.dll" -HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=390784' +HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=855956' } diff --git a/src/Modules/Shared/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psm1 b/src/Modules/Shared/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psm1 index cd915abe7ae..c55839fd440 100644 --- a/src/Modules/Shared/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psm1 +++ b/src/Modules/Shared/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psm1 @@ -1,3 +1,5 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. ## Converts a SDDL string into an object-based representation of a security ## descriptor diff --git a/src/Modules/Shared/PSReadLine/PSReadLine.psd1 b/src/Modules/Shared/PSReadLine/PSReadLine.psd1 index 6af2eea6f73..a634495d19d 100644 --- a/src/Modules/Shared/PSReadLine/PSReadLine.psd1 +++ b/src/Modules/Shared/PSReadLine/PSReadLine.psd1 @@ -5,7 +5,7 @@ ModuleVersion = '1.2' GUID = '5714753b-2afd-4492-a5fd-01d9e2cff8b5' Author = 'Microsoft Corporation' CompanyName = 'Microsoft Corporation' -Copyright = '(c) Microsoft Corporation. All rights reserved.' +Copyright = 'Copyright (c) Microsoft Corporation. All rights reserved.' Description = 'Great command line editing in the PowerShell console host' PowerShellVersion = '3.0' DotNetFrameworkVersion = '4.0' @@ -13,5 +13,5 @@ CLRVersion = '4.0' FunctionsToExport = 'PSConsoleHostReadline' CmdletsToExport = 'Get-PSReadlineKeyHandler','Set-PSReadlineKeyHandler','Remove-PSReadlineKeyHandler', 'Get-PSReadlineOption','Set-PSReadlineOption' -HelpInfoURI = 'https://go.microsoft.com/fwlink/?LinkId=528806' +HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=855966' } diff --git a/src/Modules/Shared/Pester b/src/Modules/Shared/Pester deleted file mode 160000 index aa243108e7d..00000000000 --- a/src/Modules/Shared/Pester +++ /dev/null @@ -1 +0,0 @@ -Subproject commit aa243108e7da50a8cf82513b6dd649b653c70b0e diff --git a/src/Modules/Unix/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 b/src/Modules/Unix/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 index 90759a98e4b..ce0b1442968 100644 --- a/src/Modules/Unix/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 +++ b/src/Modules/Unix/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 @@ -1,13 +1,13 @@ @{ GUID="EEFCB906-B326-4E99-9F54-8B4BB6EF3C6D" -Author="Microsoft Corporation" +Author="PowerShell" CompanyName="Microsoft Corporation" -Copyright="(c) Microsoft Corporation. All rights reserved." +Copyright="Copyright (c) Microsoft Corporation. All rights reserved." ModuleVersion="3.1.0.0" PowerShellVersion="3.0" NestedModules="Microsoft.PowerShell.Commands.Management.dll" -HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=390785' -AliasesToExport = @("gtz") +HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=855958' +AliasesToExport = @("gtz") FunctionsToExport = @() CmdletsToExport=@("Add-Content", "Clear-Content", @@ -45,6 +45,7 @@ CmdletsToExport=@("Add-Content", "Wait-Process", "Debug-Process", "Start-Process", + "Test-Connection", "Remove-ItemProperty", "Rename-ItemProperty", "Resolve-Path", diff --git a/src/Modules/Unix/Microsoft.PowerShell.Security/Microsoft.PowerShell.Security.psd1 b/src/Modules/Unix/Microsoft.PowerShell.Security/Microsoft.PowerShell.Security.psd1 index a8ef3b89ffc..5afb77fe13c 100644 --- a/src/Modules/Unix/Microsoft.PowerShell.Security/Microsoft.PowerShell.Security.psd1 +++ b/src/Modules/Unix/Microsoft.PowerShell.Security/Microsoft.PowerShell.Security.psd1 @@ -1,13 +1,13 @@ @{ GUID="A94C8C7E-9810-47C0-B8AF-65089C13A35A" -Author="Microsoft Corporation" +Author="PowerShell" CompanyName="Microsoft Corporation" -Copyright="(c) Microsoft Corporation. All rights reserved." +Copyright="Copyright (c) Microsoft Corporation. All rights reserved." ModuleVersion="3.0.0.0" PowerShellVersion="3.0" AliasesToExport = @() FunctionsToExport = @() CmdletsToExport="Get-Credential", "Get-ExecutionPolicy", "Set-ExecutionPolicy", "ConvertFrom-SecureString", "ConvertTo-SecureString", "Get-PfxCertificate" NestedModules="Microsoft.PowerShell.Security.dll" -HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=390786' +HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=855959' } diff --git a/src/Modules/Unix/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 b/src/Modules/Unix/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 index fdc7173d35b..0785132ffd2 100644 --- a/src/Modules/Unix/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 +++ b/src/Modules/Unix/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 @@ -1,8 +1,8 @@ @{ GUID="1DA87E53-152B-403E-98DC-74D7B4D63D59" -Author="Microsoft Corporation" +Author="PowerShell" CompanyName="Microsoft Corporation" -Copyright="© Microsoft Corporation. All rights reserved." +Copyright="Copyright (c) Microsoft Corporation. All rights reserved." ModuleVersion="3.1.0.0" PowerShellVersion="3.0" CmdletsToExport= "Format-List", "Format-Custom", "Format-Table", "Format-Wide", @@ -22,9 +22,10 @@ CmdletsToExport= "Format-List", "Format-Custom", "Format-Table", "Format-Wide", "Get-PSBreakpoint", "Remove-PSBreakpoint", "Enable-PSBreakpoint", "Disable-PSBreakpoint", "Get-PSCallStack", "Send-MailMessage", "Get-TraceSource", "Set-TraceSource", "Trace-Command", "Get-FileHash", "Get-Runspace", "Debug-Runspace", "Enable-RunspaceDebug", "Disable-RunspaceDebug", - "Get-RunspaceDebug", "Wait-Debugger" , "Get-Uptime", "New-TemporaryFile", "Get-Verb", "Format-Hex" + "Get-RunspaceDebug", "Wait-Debugger" , "Get-Uptime", "New-TemporaryFile", "Get-Verb", "Format-Hex", + "Test-Json", "Remove-Alias" FunctionsToExport= "Import-PowerShellDataFile" AliasesToExport= "fhx" NestedModules="Microsoft.PowerShell.Commands.Utility.dll","Microsoft.PowerShell.Utility.psm1" -HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=390787' +HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=855960' } diff --git a/src/Modules/Windows-Core+Full/CimCmdlets/CimCmdlets.psd1 b/src/Modules/Windows-Core+Full/CimCmdlets/CimCmdlets.psd1 index 16c79204763..f43e7df4ab3 100644 --- a/src/Modules/Windows-Core+Full/CimCmdlets/CimCmdlets.psd1 +++ b/src/Modules/Windows-Core+Full/CimCmdlets/CimCmdlets.psd1 @@ -1,8 +1,8 @@ @{ GUID="{Fb6cc51d-c096-4b38-b78d-0fed6277096a}" -Author="Microsoft Corporation" +Author="PowerShell" CompanyName="Microsoft Corporation" -Copyright="© Microsoft Corporation. All rights reserved." +Copyright="Copyright (c) Microsoft Corporation. All rights reserved." ModuleVersion="1.0.0.0" PowerShellVersion="3.0" CLRVersion="4.0" @@ -14,5 +14,5 @@ CmdletsToExport= "Get-CimAssociatedInstance", "Get-CimClass", "Get-CimInstance", "Export-BinaryMiLog","Import-BinaryMiLog" AliasesToExport = "gcim","scim","ncim", "rcim","icim","gcai","rcie","ncms","rcms","gcms","ncso","gcls" FunctionsToExport = @() -HelpInfoUri="https://go.microsoft.com/fwlink/?linkid=390758" +HelpInfoUri="https://go.microsoft.com/fwlink/?linkid=855946" } diff --git a/src/Modules/Windows-Core+Full/Microsoft.PowerShell.Security/Microsoft.PowerShell.Security.psd1 b/src/Modules/Windows-Core+Full/Microsoft.PowerShell.Security/Microsoft.PowerShell.Security.psd1 index fc76cbdf76f..5ce8045b8b5 100644 --- a/src/Modules/Windows-Core+Full/Microsoft.PowerShell.Security/Microsoft.PowerShell.Security.psd1 +++ b/src/Modules/Windows-Core+Full/Microsoft.PowerShell.Security/Microsoft.PowerShell.Security.psd1 @@ -1,8 +1,8 @@ @{ GUID="A94C8C7E-9810-47C0-B8AF-65089C13A35A" -Author="Microsoft Corporation" +Author="PowerShell" CompanyName="Microsoft Corporation" -Copyright="(c) Microsoft Corporation. All rights reserved." +Copyright="Copyright (c) Microsoft Corporation. All rights reserved." ModuleVersion="3.0.0.0" PowerShellVersion="3.0" CLRVersion="4.0" @@ -10,5 +10,5 @@ AliasesToExport = @() FunctionsToExport = @() CmdletsToExport="Get-Acl", "Set-Acl", "Get-PfxCertificate", "Get-Credential", "Get-ExecutionPolicy", "Set-ExecutionPolicy", "Get-AuthenticodeSignature", "Set-AuthenticodeSignature", "ConvertFrom-SecureString", "ConvertTo-SecureString", "Get-CmsMessage", "Unprotect-CmsMessage", "Protect-CmsMessage" , "New-FileCatalog" , "Test-FileCatalog" NestedModules="Microsoft.PowerShell.Security.dll" -HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=390786' +HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=855959' } diff --git a/src/Modules/Windows-Core+Full/Microsoft.WSMan.Management/Microsoft.WSMan.Management.psd1 b/src/Modules/Windows-Core+Full/Microsoft.WSMan.Management/Microsoft.WSMan.Management.psd1 index 722b3d0d3a8..5049c15af56 100644 --- a/src/Modules/Windows-Core+Full/Microsoft.WSMan.Management/Microsoft.WSMan.Management.psd1 +++ b/src/Modules/Windows-Core+Full/Microsoft.WSMan.Management/Microsoft.WSMan.Management.psd1 @@ -1,8 +1,8 @@ @{ GUID="766204A6-330E-4263-A7AB-46C87AFC366C" -Author="Microsoft Corporation" +Author="PowerShell" CompanyName="Microsoft Corporation" -Copyright="(c) Microsoft Corporation. All rights reserved." +Copyright="Copyright (c) Microsoft Corporation. All rights reserved." ModuleVersion="3.0.0.0" PowerShellVersion="3.0" CLRVersion="4.0" @@ -11,5 +11,5 @@ FunctionsToExport = @() CmdletsToExport="Disable-WSManCredSSP", "Enable-WSManCredSSP", "Get-WSManCredSSP", "Set-WSManQuickConfig", "Test-WSMan", "Invoke-WSManAction", "Connect-WSMan", "Disconnect-WSMan", "Get-WSManInstance", "Set-WSManInstance", "Remove-WSManInstance", "New-WSManInstance", "New-WSManSessionOption" NestedModules="Microsoft.WSMan.Management.dll" FormatsToProcess="WSMan.format.ps1xml" -HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=390788' +HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=855961' } diff --git a/src/Modules/Windows-Core+Full/Microsoft.WSMan.Management/WSMan.format.ps1xml b/src/Modules/Windows-Core+Full/Microsoft.WSMan.Management/WSMan.format.ps1xml index c770f0e9769..246a7a307dc 100644 --- a/src/Modules/Windows-Core+Full/Microsoft.WSMan.Management/WSMan.format.ps1xml +++ b/src/Modules/Windows-Core+Full/Microsoft.WSMan.Management/WSMan.format.ps1xml @@ -5,7 +5,7 @@ PowerShell engine. Do not edit or change the contents of this file directly. Please see the Windows PowerShell documentation or type Get-Help Update-FormatData for more information. -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. THIS SAMPLE CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO diff --git a/src/Modules/Windows-Core+Full/PSDiagnostics/PSDiagnostics.psd1 b/src/Modules/Windows-Core+Full/PSDiagnostics/PSDiagnostics.psd1 index 44b9e292940..fe88525544e 100644 --- a/src/Modules/Windows-Core+Full/PSDiagnostics/PSDiagnostics.psd1 +++ b/src/Modules/Windows-Core+Full/PSDiagnostics/PSDiagnostics.psd1 @@ -1,8 +1,8 @@ @{ GUID="c61d6278-02a3-4618-ae37-a524d40a7f44 " - Author="Microsoft Corporation" + Author="PowerShell" CompanyName="Microsoft Corporation" - Copyright="© Microsoft Corporation. All rights reserved." + Copyright="Copyright (c) Microsoft Corporation. All rights reserved." ModuleVersion="1.0.0.0" PowerShellVersion="2.0" CLRVersion="2.0.50727" diff --git a/src/Modules/Windows-Core+Full/PSDiagnostics/PSDiagnostics.psm1 b/src/Modules/Windows-Core+Full/PSDiagnostics/PSDiagnostics.psm1 index 524f2ccb73e..d0b184bf44c 100644 --- a/src/Modules/Windows-Core+Full/PSDiagnostics/PSDiagnostics.psm1 +++ b/src/Modules/Windows-Core+Full/PSDiagnostics/PSDiagnostics.psm1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + <# Windows PowerShell Diagnostics Module This module contains a set of wrapper scripts that @@ -434,7 +437,6 @@ namespace Microsoft.PowerShell.Diagnostics } "@ - if ($psedition -eq 'Core') { # Currently we only support these cmdlets as logman.exe is not working on Nano/Lot system. diff --git a/src/Modules/Windows-Core/Microsoft.PowerShell.Diagnostics/GetEvent.types.ps1xml b/src/Modules/Windows-Core/Microsoft.PowerShell.Diagnostics/GetEvent.types.ps1xml index 29a42edfab1..150f184c164 100644 --- a/src/Modules/Windows-Core/Microsoft.PowerShell.Diagnostics/GetEvent.types.ps1xml +++ b/src/Modules/Windows-Core/Microsoft.PowerShell.Diagnostics/GetEvent.types.ps1xml @@ -5,7 +5,7 @@ PowerShell engine. Do not edit or change the contents of this file directly. Please see the Windows PowerShell documentation or type Get-Help Update-TypeData for more information. -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. THIS SAMPLE CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO diff --git a/src/Modules/Windows-Core/Microsoft.PowerShell.Diagnostics/Microsoft.PowerShell.Diagnostics.psd1 b/src/Modules/Windows-Core/Microsoft.PowerShell.Diagnostics/Microsoft.PowerShell.Diagnostics.psd1 index 8dc0d9cada6..1eaafbce6ab 100644 --- a/src/Modules/Windows-Core/Microsoft.PowerShell.Diagnostics/Microsoft.PowerShell.Diagnostics.psd1 +++ b/src/Modules/Windows-Core/Microsoft.PowerShell.Diagnostics/Microsoft.PowerShell.Diagnostics.psd1 @@ -1,13 +1,13 @@ @{ GUID="CA046F10-CA64-4740-8FF9-2565DBA61A4F" -Author="Microsoft Corporation" +Author="PowerShell" CompanyName="Microsoft Corporation" -Copyright="© Microsoft Corporation. All rights reserved." +Copyright="Copyright (c) Microsoft Corporation. All rights reserved." ModuleVersion="3.0.0.0" PowerShellVersion="3.0" CmdletsToExport="Get-WinEvent", "New-WinEvent" # Counter CmdLets Disabled #4272: "Get-Counter", "Import-Counter", "Export-Counter" NestedModules="Microsoft.PowerShell.Commands.Diagnostics.dll" TypesToProcess="GetEvent.types.ps1xml" FormatsToProcess="Event.format.ps1xml", "Diagnostics.format.ps1xml" -HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=390783' +HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=855954' } diff --git a/src/Modules/Windows-Core/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 b/src/Modules/Windows-Core/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 index f2fadbe07ce..78d776ca45c 100644 --- a/src/Modules/Windows-Core/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 +++ b/src/Modules/Windows-Core/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 @@ -1,13 +1,13 @@ @{ GUID="EEFCB906-B326-4E99-9F54-8B4BB6EF3C6D" -Author="Microsoft Corporation" +Author="PowerShell" CompanyName="Microsoft Corporation" -Copyright="(c) Microsoft Corporation. All rights reserved." +Copyright="Copyright (c) Microsoft Corporation. All rights reserved." ModuleVersion="3.1.0.0" PowerShellVersion="3.0" NestedModules="Microsoft.PowerShell.Commands.Management.dll" -HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=390785' -AliasesToExport = @("gin", "gtz", "stz") +HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=855958' +AliasesToExport = @("gin", "gtz", "stz") FunctionsToExport = @() CmdletsToExport=@("Add-Content", "Clear-Content", @@ -40,6 +40,7 @@ CmdletsToExport=@("Add-Content", "New-ItemProperty", "Split-Path", "Test-Path", + "Test-Connection", "Get-Process", "Stop-Process", "Wait-Process", @@ -59,7 +60,6 @@ CmdletsToExport=@("Add-Content", "Remove-Service", "Set-Content", "Set-ItemProperty", - "Test-Connection", "Restart-Computer", "Stop-Computer", "Rename-Computer", diff --git a/src/Modules/Windows-Core/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 b/src/Modules/Windows-Core/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 index 7c7b3d302c8..50f785f87b1 100644 --- a/src/Modules/Windows-Core/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 +++ b/src/Modules/Windows-Core/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 @@ -1,8 +1,8 @@ @{ GUID="1DA87E53-152B-403E-98DC-74D7B4D63D59" -Author="Microsoft Corporation" +Author="PowerShell" CompanyName="Microsoft Corporation" -Copyright="© Microsoft Corporation. All rights reserved." +Copyright="Copyright (c) Microsoft Corporation. All rights reserved." ModuleVersion="3.1.0.0" PowerShellVersion="3.0" CmdletsToExport= "Format-List", "Format-Custom", "Format-Table", "Format-Wide", @@ -22,9 +22,10 @@ CmdletsToExport= "Format-List", "Format-Custom", "Format-Table", "Format-Wide", "Get-PSBreakpoint", "Remove-PSBreakpoint", "New-TemporaryFile", "Enable-PSBreakpoint", "Disable-PSBreakpoint", "Get-PSCallStack", "Send-MailMessage", "Get-TraceSource", "Set-TraceSource", "Trace-Command", "Get-FileHash", "Unblock-File", "Get-Runspace", "Debug-Runspace", "Enable-RunspaceDebug", "Disable-RunspaceDebug", - "Get-RunspaceDebug", "Wait-Debugger" , "Get-Uptime", "Get-Verb", "Format-Hex" + "Get-RunspaceDebug", "Wait-Debugger" , "Get-Uptime", "Get-Verb", "Format-Hex", + "Test-Json", "Remove-Alias" FunctionsToExport= "ConvertFrom-SddlString" AliasesToExport= "fhx" NestedModules="Microsoft.PowerShell.Commands.Utility.dll","Microsoft.PowerShell.Utility.psm1" -HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=390787' +HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=855960' } diff --git a/src/Modules/Windows-Full/Microsoft.PowerShell.Diagnostics/GetEvent.types.ps1xml b/src/Modules/Windows-Full/Microsoft.PowerShell.Diagnostics/GetEvent.types.ps1xml index d9dcc2034bb..c52b8e6c2c2 100644 --- a/src/Modules/Windows-Full/Microsoft.PowerShell.Diagnostics/GetEvent.types.ps1xml +++ b/src/Modules/Windows-Full/Microsoft.PowerShell.Diagnostics/GetEvent.types.ps1xml @@ -5,7 +5,7 @@ PowerShell engine. Do not edit or change the contents of this file directly. Please see the Windows PowerShell documentation or type Get-Help Update-TypeData for more information. -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. THIS SAMPLE CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO diff --git a/src/Modules/Windows-Full/Microsoft.PowerShell.Diagnostics/Microsoft.PowerShell.Diagnostics.psd1 b/src/Modules/Windows-Full/Microsoft.PowerShell.Diagnostics/Microsoft.PowerShell.Diagnostics.psd1 index ca82ca6e9dc..6db471f5247 100644 --- a/src/Modules/Windows-Full/Microsoft.PowerShell.Diagnostics/Microsoft.PowerShell.Diagnostics.psd1 +++ b/src/Modules/Windows-Full/Microsoft.PowerShell.Diagnostics/Microsoft.PowerShell.Diagnostics.psd1 @@ -1,8 +1,8 @@ @{ GUID="CA046F10-CA64-4740-8FF9-2565DBA61A4F" -Author="Microsoft Corporation" +Author="PowerShell" CompanyName="Microsoft Corporation" -Copyright="(c) Microsoft Corporation. All rights reserved." +Copyright="Copyright (c) Microsoft Corporation. All rights reserved." ModuleVersion="3.0.0.0" PowerShellVersion="3.0" CLRVersion="4.0" @@ -11,6 +11,6 @@ FunctionsToExport = @() CmdletsToExport="Get-WinEvent", "Get-Counter", "Import-Counter", "Export-Counter", "New-WinEvent" NestedModules="Microsoft.PowerShell.Commands.Diagnostics.dll" TypesToProcess="GetEvent.types.ps1xml" -FormatsToProcess="Event.format.ps1xml","Diagnostics.format.ps1xml" -HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=390783' +FormatsToProcess="Event.format.ps1xml","Diagnostics.format.ps1xml" +HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=855954' } diff --git a/src/Modules/Windows-Full/Microsoft.PowerShell.LocalAccounts/Microsoft.PowerShell.LocalAccounts.psd1 b/src/Modules/Windows-Full/Microsoft.PowerShell.LocalAccounts/Microsoft.PowerShell.LocalAccounts.psd1 index ee3091ecc55..dd879947383 100644 --- a/src/Modules/Windows-Full/Microsoft.PowerShell.LocalAccounts/Microsoft.PowerShell.LocalAccounts.psd1 +++ b/src/Modules/Windows-Full/Microsoft.PowerShell.LocalAccounts/Microsoft.PowerShell.LocalAccounts.psd1 @@ -2,9 +2,9 @@ RootModule = 'Microsoft.Powershell.LocalAccounts' ModuleVersion = '1.0.0.0' GUID = '8e362604-2c0b-448f-a414-a6a690a644e2' -Author = 'Microsoft Corporation' +Author = 'PowerShell' CompanyName = 'Microsoft Corporation' -Copyright = '© Microsoft Corporation. All rights reserved.' +Copyright = 'Copyright (c) Microsoft Corporation. All rights reserved.' Description = 'Provides cmdlets to work with local users and local groups' PowerShellVersion = '3.0' CLRVersion = '4.0' diff --git a/src/Modules/Windows-Full/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 b/src/Modules/Windows-Full/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 index 81e941c6d71..e7a43cf4aea 100644 --- a/src/Modules/Windows-Full/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 +++ b/src/Modules/Windows-Full/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 @@ -1,13 +1,13 @@ @{ GUID="EEFCB906-B326-4E99-9F54-8B4BB6EF3C6D" -Author="Microsoft Corporation" +Author="PowerShell" CompanyName="Microsoft Corporation" -Copyright="(c) Microsoft Corporation. All rights reserved." +Copyright="Copyright (c) Microsoft Corporation. All rights reserved." ModuleVersion="3.1.0.0" PowerShellVersion="3.0" CLRVersion="4.0" NestedModules="Microsoft.PowerShell.Commands.Management.dll" -HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=390785' +HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=855958' AliasesToExport = @("gcb", "scb", "gin", "gtz", "stz") FunctionsToExport = @() CmdletsToExport=@("Add-Content", diff --git a/src/Modules/Windows-Full/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataAdapter.ps1 b/src/Modules/Windows-Full/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataAdapter.ps1 index 0c0921821d9..967268f8bbf 100644 --- a/src/Modules/Windows-Full/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataAdapter.ps1 +++ b/src/Modules/Windows-Full/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataAdapter.ps1 @@ -1,5 +1,7 @@ -Import-LocalizedData LocalizedData -FileName Microsoft.PowerShell.ODataUtilsStrings.psd1 +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. +Import-LocalizedData LocalizedData -FileName Microsoft.PowerShell.ODataUtilsStrings.psd1 # Add .NET classes used by the module Add-Type -TypeDefinition $global:BaseClassDefinitions @@ -813,7 +815,6 @@ function GenerateGetProxyCmdlet } } - # Add Query Parameters (i.e., Top, Skip, OrderBy, Filter) to the generated Get-* cmdlets. $queryParameters = @{ diff --git a/src/Modules/Windows-Full/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtils.psd1 b/src/Modules/Windows-Full/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtils.psd1 index 515040f7941..b4ad19bd6f5 100644 --- a/src/Modules/Windows-Full/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtils.psd1 +++ b/src/Modules/Windows-Full/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtils.psd1 @@ -16,13 +16,13 @@ ModuleVersion = '1.0' GUID = 'fa1606d1-94cb-4264-bfb6-def714420084' # Author of this module -Author = 'Microsoft Corporation' +Author = 'PowerShell' # Company or vendor of this module CompanyName = 'Microsoft Corporation' # Copyright statement for this module -Copyright = '(c) 2014 Microsoft. All rights reserved.' +Copyright = 'Copyright (c) Microsoft Corporation. All rights reserved.' # Description of the functionality provided by this module # Description = '' diff --git a/src/Modules/Windows-Full/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtils.psm1 b/src/Modules/Windows-Full/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtils.psm1 index 9d5e5254726..2909c7f731b 100644 --- a/src/Modules/Windows-Full/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtils.psm1 +++ b/src/Modules/Windows-Full/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtils.psm1 @@ -1,5 +1,7 @@ -Import-LocalizedData LocalizedData -FileName Microsoft.PowerShell.ODataUtilsStrings.psd1 +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. +Import-LocalizedData LocalizedData -FileName Microsoft.PowerShell.ODataUtilsStrings.psd1 # This module doesn't support Arm because of Add-Type cmdlet $ProcessorArchitecture = (Get-WmiObject -query "Select Architecture from Win32_Processor").Architecture diff --git a/src/Modules/Windows-Full/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtilsHelper.ps1 b/src/Modules/Windows-Full/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtilsHelper.ps1 index 473d39909e2..d332635db6a 100644 --- a/src/Modules/Windows-Full/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtilsHelper.ps1 +++ b/src/Modules/Windows-Full/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtilsHelper.ps1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + # Base class definitions used by the actual Adapter modules $global:BaseClassDefinitions = @" using System; diff --git a/src/Modules/Windows-Full/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataV4Adapter.ps1 b/src/Modules/Windows-Full/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataV4Adapter.ps1 index 9ecd112b2e8..b19636df0f1 100644 --- a/src/Modules/Windows-Full/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataV4Adapter.ps1 +++ b/src/Modules/Windows-Full/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataV4Adapter.ps1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + Import-LocalizedData LocalizedData -FileName Microsoft.PowerShell.ODataUtilsStrings.psd1 # Add .NET classes used by the module @@ -384,7 +387,6 @@ function ParseTypeDefinitions if($null -eq $SchemaXML) { throw ($LocalizedData.ArguementNullError -f "SchemaXML", "ParseTypeDefinitions") } - foreach ($typeDefinition in $SchemaXML.TypeDefinition) { $newType = [ODataUtils.EntityTypeV4] @{ @@ -779,7 +781,6 @@ function VerifyMetadata $validEntitySets = @() $sessionCommands = Get-Command -All - foreach ($metadata in $metadataSet) { foreach ($entitySet in $metadata.EntitySets) @@ -1653,7 +1654,6 @@ function SaveCDXMLInstanceCmdlets } $xmlWriter.WriteAttributeString('DefaultCmdletParameterSet', $defaultCmdletParameterSet) - $xmlWriter.WriteStartElement('QueryableProperties') $position = 0 @@ -1758,7 +1758,6 @@ function SaveCDXMLInstanceCmdlets $xmlWriter.WriteEndElement() } - $xmlWriter.WriteEndElement() } @@ -2665,4 +2664,4 @@ namespace $($dotNetNamespace) Write-Verbose ($LocalizedData.VerboseSavedTypeDefinationModule -f $typeDefinationFileName, $OutputModule) return $complexTypeMapping -} \ No newline at end of file +} diff --git a/src/Modules/Windows-Full/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 b/src/Modules/Windows-Full/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 index 86eccf288f3..b8bd33f155d 100644 --- a/src/Modules/Windows-Full/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 +++ b/src/Modules/Windows-Full/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 @@ -1,8 +1,8 @@ @{ GUID="1DA87E53-152B-403E-98DC-74D7B4D63D59" -Author="Microsoft Corporation" +Author="PowerShell" CompanyName="Microsoft Corporation" -Copyright="© Microsoft Corporation. All rights reserved." +Copyright="Copyright (c) Microsoft Corporation. All rights reserved." ModuleVersion="3.1.0.0" PowerShellVersion="3.0" CLRVersion="4.0" @@ -28,5 +28,5 @@ CmdletsToExport= "Format-List", "Format-Custom", "Format-Table", "Format-Wide", FunctionsToExport= "ConvertFrom-SddlString" AliasesToExport= "CFS", "fhx" NestedModules="Microsoft.PowerShell.Commands.Utility.dll","Microsoft.PowerShell.Utility.psm1" -HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=390787' +HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=855960' } diff --git a/src/Modules/Windows-Full/PSScheduledJob/PSScheduledJob.psd1 b/src/Modules/Windows-Full/PSScheduledJob/PSScheduledJob.psd1 index 3b7d84099de..d2831607ee4 100644 --- a/src/Modules/Windows-Full/PSScheduledJob/PSScheduledJob.psd1 +++ b/src/Modules/Windows-Full/PSScheduledJob/PSScheduledJob.psd1 @@ -6,11 +6,11 @@ ModuleVersion = '1.1.0.0' GUID = '50cdb55f-5ab7-489f-9e94-4ec21ff51e59' -Author = 'Microsoft Corporation' +Author = 'PowerShell' CompanyName = 'Microsoft Corporation' -Copyright = '(c) Microsoft Corporation. All rights reserved.' +Copyright = 'Copyright (c) Microsoft Corporation. All rights reserved.' PowerShellVersion = '3.0' @@ -20,8 +20,8 @@ TypesToProcess = 'PSScheduledJob.types.ps1xml' FormatsToProcess="PSScheduledJob.Format.ps1xml" -CmdletsToExport = 'New-JobTrigger', 'Add-JobTrigger', 'Remove-JobTrigger', - 'Get-JobTrigger', 'Set-JobTrigger', 'Enable-JobTrigger', +CmdletsToExport = 'New-JobTrigger', 'Add-JobTrigger', 'Remove-JobTrigger', + 'Get-JobTrigger', 'Set-JobTrigger', 'Enable-JobTrigger', 'Disable-JobTrigger', 'New-ScheduledJobOption', 'Get-ScheduledJobOption', 'Set-ScheduledJobOption', 'Register-ScheduledJob', 'Get-ScheduledJob', 'Set-ScheduledJob', 'Unregister-ScheduledJob', 'Enable-ScheduledJob', diff --git a/src/Modules/Windows-Full/PSScheduledJob/PSScheduledJob.types.ps1xml b/src/Modules/Windows-Full/PSScheduledJob/PSScheduledJob.types.ps1xml index 699af0c99d3..f8822f2c9d6 100644 --- a/src/Modules/Windows-Full/PSScheduledJob/PSScheduledJob.types.ps1xml +++ b/src/Modules/Windows-Full/PSScheduledJob/PSScheduledJob.types.ps1xml @@ -5,7 +5,7 @@ PowerShell engine. Do not edit or change the contents of this file directly. Please see the Windows PowerShell documentation or type Get-Help Update-TypeData for more information. -Copyright (c) Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation. All rights reserved. THIS SAMPLE CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO diff --git a/src/PowerShell.Core.Instrumentation/CMakeLists.txt b/src/PowerShell.Core.Instrumentation/CMakeLists.txt new file mode 100644 index 00000000000..bfa5218b86c --- /dev/null +++ b/src/PowerShell.Core.Instrumentation/CMakeLists.txt @@ -0,0 +1,75 @@ +cmake_minimum_required(VERSION 3.5) +# +# Builds PowerShell.Core.Instrumentation.dll resource-only DLL containing ETW event resources +# + +# The fully qualified path to the event manifest +SET(EVENTS_MANIFEST "${CMAKE_CURRENT_SOURCE_DIR}/PowerShell.Core.Instrumentation.man") + +# User mode manifest resource-only dll +function(add_manifest_binary) + + add_definitions(-D_DLL=1) + add_library(${ARGV}) + + # NOTE: EVENTS_MANIFEST must be the fully qualified path to the manifest + SET(MC_MANIFEST_FULLNAME ${EVENTS_MANIFEST}) + + # get the ETW manifest's filename without the directory or extension + get_filename_component(MC_MANIFEST_BASENAME ${EVENTS_MANIFEST} NAME_WE) + + SET(MC_COMMAND "mc.exe") + SET(GeneratedManifestFiles) + + # The target directory for generated managed files + SET (MC_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}") + + # include the generated directory in the include path + include_directories("${MC_GENERATED_DIR}") + + SET (MC_GENERATED_FILES + ${MC_GENERATED_DIR}/${MC_MANIFEST_BASENAME}.rc + ${MC_GENERATED_DIR}/${MC_MANIFEST_BASENAME}TEMP.BIN + ${MC_GENERATED_DIR}/${MC_MANIFEST_BASENAME}_MSG00001.BIN + ) + + SET(MC_COMMAND "mc.exe -h ${MC_GENERATED_DIR} -r ${MC_GENERATED_DIR} ${MC_MANIFEST_FULLNAME}") + + add_custom_command( + COMMENT "Generating native event manifest files for ${EVENTS_MANIFEST}" + OUTPUT ${MC_GENERATED_FILES} + DEPENDS ${MC_MANIFEST_FULLNAME} + COMMAND cmd.exe /c ${MC_COMMAND} + WORKING_DIRECTORY ${MC_GENERATED_DIR} + VERBATIM + ) + + list (APPEND GeneratedManifestFiles ${MC_GENERATED_DIR}/${MC_MANIFEST_BASENAME}.rc) + + set_source_files_properties(${GeneratedManifestFiles} PROPERTIES GENERATED TRUE) + add_custom_target(GeneratedManifestFiles DEPENDS ${GeneratedManifestFiles}) + + # for a resource only dll, cmake can report an error + # if there is no linker language set. + # CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly. + # Missing variable is: CMAKE_RC_CREATE_SHARED_LIBRARY + get_property(isSet TARGET ${ARGV0} PROPERTY LINKER_LANGUAGE SET) + if (NOT ${isSet}) + set_target_properties(${ARGV0} PROPERTIES LINKER_LANGUAGE "CXX") + endif() + + set_target_properties(${ARGV0} PROPERTIES LINK_FLAGS "/NODEFAULTLIB /NOENTRY") + + if (BUILD_ONECORE) + set_target_properties(${ARGV0} PROPERTIES COMPILE_DEFINITIONS "CORECLR") + endif (BUILD_ONECORE) + + # ensure the target is dependent on the generated files. + add_dependencies(${ARGV0} GeneratedManifestFiles) + +endfunction() + +file(GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/version.rc) + +add_manifest_binary(PowerShell.Core.Instrumentation SHARED ${SOURCES}) + diff --git a/src/PowerShell.Core.Instrumentation/PowerShell.Core.Instrumentation.man b/src/PowerShell.Core.Instrumentation/PowerShell.Core.Instrumentation.man new file mode 100644 index 00000000000..350323f519c --- /dev/null +++ b/src/PowerShell.Core.Instrumentation/PowerShell.Core.Instrumentation.man @@ -0,0 +1,5635 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + 15728640 + + + + + + true + + 1048985600 + + + + 64 + + + + + + true + + 1048985600 + + + + 64 + + + + + + true + + 1048985600 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +