├── source ├── Examples │ └── README.md ├── DSCResources │ └── MSFT_xCredSSP │ │ ├── en-US │ │ └── MSFT_xCredSSP.strings.psd1 │ │ ├── MSFT_xCredSSP.schema.mof │ │ └── MSFT_xCredSSP.psm1 ├── xCredSSP.psm1 ├── en-US │ └── about_xCredSSP.help.txt ├── WikiSource │ └── Home.md └── xCredSSP.psd1 ├── Resolve-Dependency.psd1 ├── CODE_OF_CONDUCT.md ├── .markdownlint.json ├── .gitignore ├── .github ├── ISSUE_TEMPLATE │ ├── General.md │ ├── config.yml │ ├── Resource_proposal.yml │ └── Problem_with_resource.yml ├── stale.yml └── PULL_REQUEST_TEMPLATE.md ├── CONTRIBUTING.md ├── .gitattributes ├── codecov.yml ├── GitVersion.yml ├── RequiredModules.psd1 ├── LICENSE ├── CHANGELOG.md ├── SECURITY.md ├── .vscode ├── settings.json ├── analyzersettings.psd1 └── tasks.json ├── README.md ├── azure-pipelines.yml ├── tests └── Unit │ └── MSFT_xCredSSP.tests.ps1 └── Resolve-Dependency.ps1 /source/Examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | Current there are no examples for the resources. 4 | -------------------------------------------------------------------------------- /Resolve-Dependency.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | Gallery = 'PSGallery' 3 | AllowPrerelease = $false 4 | WithYAML = $true 5 | } 6 | -------------------------------------------------------------------------------- /source/DSCResources/MSFT_xCredSSP/en-US/MSFT_xCredSSP.strings.psd1: -------------------------------------------------------------------------------- 1 | # Localized resources for xCredSSP 2 | 3 | ConvertFrom-StringData @' 4 | '@ 5 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | This project has adopted the [DSC Community Code of Conduct](https://dsccommunity.org/code_of_conduct). 4 | -------------------------------------------------------------------------------- /source/xCredSSP.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | This file is intentionally left empty. It is must be left here for the module 3 | manifest to refer to. It is recreated during the build process. 4 | #> 5 | -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "default": true, 3 | "MD029": { 4 | "style": "one" 5 | }, 6 | "MD013": true, 7 | "MD024": false, 8 | "MD034": false, 9 | "no-hard-tabs": true 10 | } 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | output/ 2 | 3 | **.bak 4 | *.local.* 5 | !**/README.md 6 | .kitchen/ 7 | 8 | *.nupkg 9 | *.suo 10 | *.user 11 | *.coverage 12 | .vs 13 | .psproj 14 | .sln 15 | markdownissues.txt 16 | node_modules 17 | package-lock.json 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/General.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: General question or documentation update 3 | about: If you have a general question or documentation update suggestion around the resource module. 4 | --- 5 | 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: "Virtual PowerShell User Group #DSC channel" 4 | url: https://dsccommunity.org/community/contact/ 5 | about: "To talk to the community and maintainers of DSC Community, please visit the #DSC channel." 6 | 7 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Please check out common DSC Community [contributing guidelines](https://dsccommunity.org/guidelines/contributing). 4 | 5 | ## Running the Tests 6 | 7 | If want to know how to run this module's tests you can look at the [Testing Guidelines](https://dsccommunity.org/guidelines/testing-guidelines/#running-tests) 8 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Needed for publishing of examples, build worker defaults to core.autocrlf=input. 2 | * text eol=autocrlf 3 | 4 | *.mof text eol=crlf 5 | *.sh text eol=lf 6 | *.svg eol=lf 7 | 8 | # Ensure any exe files are treated as binary 9 | *.exe binary 10 | *.jpg binary 11 | *.xl* binary 12 | *.pfx binary 13 | *.png binary 14 | *.dll binary 15 | *.so binary 16 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | require_ci_to_pass: no 3 | branch: main 4 | 5 | comment: 6 | layout: "reach, diff, flags, files" 7 | behavior: default 8 | 9 | coverage: 10 | range: 50..80 11 | round: down 12 | precision: 0 13 | 14 | status: 15 | project: 16 | default: 17 | target: 70 18 | patch: 19 | default: 20 | target: auto 21 | threshold: 5 22 | 23 | fixes: 24 | - '^\d+\.\d+\.\d+::source' # move path "X.Y.Z" => "source" 25 | -------------------------------------------------------------------------------- /source/DSCResources/MSFT_xCredSSP/MSFT_xCredSSP.schema.mof: -------------------------------------------------------------------------------- 1 | [ClassVersion("1.0.0.0"), FriendlyName("xCredSSP")] 2 | class MSFT_xCredSSP : OMI_BaseResource 3 | { 4 | [Key, Description("Specifies the CredSSP role.\nServer \nClient \n"), ValueMap{"Server","Client"}, Values{"Server","Client"}] String Role; 5 | [Write, Description("An enumerated value that describes if the role is expected to be enabled on the machine.\nPresent {default} \nAbsent \n"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; 6 | [Write, Description("Specifies the array of computers that CredSSP client can delegate to.")] String DelegateComputers[]; 7 | [Write, Description("Specifies if a reboot should be supressed. Default is False")] Boolean SuppressReboot; 8 | }; 9 | 10 | -------------------------------------------------------------------------------- /GitVersion.yml: -------------------------------------------------------------------------------- 1 | mode: ContinuousDelivery 2 | next-version: 0.0.1 3 | major-version-bump-message: '(breaking\schange|breaking|major)\b' 4 | minor-version-bump-message: '(adds?|features?|minor)\b' 5 | patch-version-bump-message: '\s?(fix|patch)' 6 | no-bump-message: '\+semver:\s?(none|skip)' 7 | assembly-informational-format: '{NuGetVersionV2}+Sha.{Sha}.Date.{CommitDate}' 8 | branches: 9 | master: 10 | tag: preview 11 | regex: ^main$ 12 | pull-request: 13 | tag: PR 14 | feature: 15 | tag: useBranchName 16 | increment: Minor 17 | regex: f(eature(s)?)?[\/-] 18 | source-branches: ['master'] 19 | hotfix: 20 | tag: fix 21 | increment: Patch 22 | regex: (hot)?fix(es)?[\/-] 23 | source-branches: ['master'] 24 | 25 | ignore: 26 | sha: [] 27 | merge-message-formats: {} 28 | -------------------------------------------------------------------------------- /source/en-US/about_xCredSSP.help.txt: -------------------------------------------------------------------------------- 1 | TOPIC 2 | about_xCredSSP 3 | 4 | SHORT DESCRIPTION 5 | This module contains DSC resources for configuration of the WSMan Credential Security Support Provider (CredSSP). 6 | 7 | LONG DESCRIPTION 8 | This module contains DSC resources for configuration of the WSMan Credential Security Support Provider (CredSSP). 9 | 10 | EXAMPLES 11 | PS C:\> Get-DscResource -Module xCredSSP 12 | 13 | NOTE: 14 | Thank you to all those who contributed to this module, by writing code, sharing opinions, and provided feedback. 15 | 16 | TROUBLESHOOTING NOTE: 17 | Go to the Github repository for read about issues, submit a new issue, and read 18 | about new releases. https://github.com/dsccommunity/xCredSSP 19 | 20 | SEE ALSO 21 | - https://github.com/dsccommunity/xCredSSP 22 | 23 | KEYWORDS 24 | DSC, DscResource, WSMan, CredSSP 25 | -------------------------------------------------------------------------------- /RequiredModules.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | PSDependOptions = @{ 3 | AddToPath = $true 4 | Target = 'output\RequiredModules' 5 | Parameters = @{ 6 | Repository = 'PSGallery' 7 | } 8 | } 9 | 10 | InvokeBuild = 'latest' 11 | PSScriptAnalyzer = 'latest' 12 | Pester = '4.10.1' 13 | Plaster = 'latest' 14 | ModuleBuilder = 'latest' 15 | ChangelogManagement = 'latest' 16 | Sampler = 'latest' 17 | 'Sampler.GitHubTasks' = 'latest' 18 | MarkdownLinkCheck = 'latest' 19 | 'DscResource.Common' = 'latest' 20 | 'DscResource.Test' = 'latest' 21 | 'DscResource.AnalyzerRules' = 'latest' 22 | xDscResourceDesigner = 'latest' 23 | 'DscResource.DocGenerator' = 'latest' 24 | } 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) DSC Community contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-stale - https://github.com/probot/stale 2 | 3 | limitPerRun: 30 4 | 5 | pulls: 6 | daysUntilStale: 14 7 | daysUntilClose: false 8 | exemptProjects: true 9 | exemptMilestones: true 10 | staleLabel: abandoned 11 | exemptLabels: 12 | - needs review 13 | - on hold 14 | - waiting for CLA pass 15 | 16 | markComment: > 17 | Labeling this pull request (PR) as abandoned since it has gone 14 days or more 18 | since the last update. An abandoned PR can be continued by another contributor. 19 | The abandoned label will be removed if work on this PR is taken up again. 20 | 21 | issues: 22 | daysUntilStale: 30 23 | daysUntilClose: 40 24 | exemptProjects: true 25 | exemptMilestones: true 26 | staleLabel: stale 27 | exemptLabels: 28 | - bug 29 | - enhancement 30 | - tests 31 | - documentation 32 | - resource proposal 33 | - on hold 34 | 35 | markComment: > 36 | This issue has been automatically marked as stale because 37 | it has not had activity from the community in the last 30 days. It will be 38 | closed if no further activity occurs within 10 days. If the issue is labelled 39 | with any of the work labels (e.g bug, enhancement, documentation, or tests) 40 | then the issue will not auto-close. 41 | 42 | closeComment: > 43 | This issue has been automatically closed because it is has not had activity 44 | from the community in the last 40 days. 45 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog for xCredSSP 2 | 3 | The format is based on and uses the types of changes according to [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 4 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 5 | 6 | ## [Unreleased] 7 | 8 | - xCredSSP 9 | - Renamed default branch to `main`. 10 | 11 | ## [1.4.0] - 2022-10-23 12 | 13 | - Updated pipeline for continuos delivery. 14 | - Fixed issue where the Set method did not correct DelegateComputers, when 15 | two machines were accidentally added as one string instead of an array. 16 | 17 | ## [1.3.0] - 2017-05-31 18 | 19 | - Added a fix to enable credSSP with a fresh server installation 20 | 21 | ## [1.2.0] - 2017-03-24 22 | 23 | - Converted appveyor.yml to install Pester from PSGallery instead of from Chocolatey. 24 | - Implemented a GPO check to prevent an endless reboot loop when CredSSP is 25 | configured via a GPO 26 | - Fixed issue with Test always returning false with other regional settings 27 | then english 28 | - Added check to test if Role=Server and DelegateComputers parameter is specified 29 | - Added parameter to supress a reboot, default value is false (reboot server 30 | when required) 31 | 32 | ## [1.1.0] - 2016-03-31 33 | 34 | - Made sure DSC reboots if credSS is enabled 35 | 36 | ## [1.0.1] - 2014-10-24 37 | 38 | - Updated with minor bug fixes. 39 | 40 | ## [1.0.0] - 2014-09-27 41 | 42 | - Initial release with the following resources: 43 | - xCredSSP 44 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | ## Security 2 | 3 | The DSC Community takes the security of our modules seriously, which includes all source code repositories managed through our GitHub organization. 4 | 5 | If you believe you have found a security vulnerability in any DSC Community owned repository, please report it to us as described below. 6 | 7 | ## Reporting Security Issues 8 | 9 | **Please do not report security vulnerabilities through public GitHub issues.** 10 | 11 | Instead, please report them to one or several members of the DSC Community organization. 12 | The easiest way to do so is to send us a direct message via twitter or slack. 13 | 14 | You should receive a response within 48 hours. If for some reason you do not, please follow up to other member of the community. 15 | 16 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 17 | 18 | * Type of issue 19 | * Full paths of source file(s) related to the manifestation of the issue 20 | * The location of the affected source code (tag/branch/commit or direct URL) 21 | * Any special configuration required to reproduce the issue 22 | * Step-by-step instructions to reproduce the issue 23 | * Proof-of-concept or exploit code (if possible) 24 | * Impact of the issue, including how an attacker might exploit the issue 25 | 26 | This information will help us triage your report more quickly. 27 | 28 | ## Preferred Languages 29 | 30 | We prefer all communications to be in English. 31 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "powershell.codeFormatting.openBraceOnSameLine": false, 3 | "powershell.codeFormatting.newLineAfterOpenBrace": true, 4 | "powershell.codeFormatting.newLineAfterCloseBrace": true, 5 | "powershell.codeFormatting.whitespaceBeforeOpenBrace": true, 6 | "powershell.codeFormatting.whitespaceBeforeOpenParen": true, 7 | "powershell.codeFormatting.whitespaceAroundOperator": true, 8 | "powershell.codeFormatting.whitespaceAfterSeparator": true, 9 | "powershell.codeFormatting.ignoreOneLineBlock": false, 10 | "powershell.codeFormatting.pipelineIndentationStyle": "IncreaseIndentationForFirstPipeline", 11 | "powershell.codeFormatting.preset": "Custom", 12 | "powershell.codeFormatting.alignPropertyValuePairs": true, 13 | "powershell.developer.bundledModulesPath": "${cwd}/output/RequiredModules", 14 | "powershell.scriptAnalysis.settingsPath": ".vscode\\analyzersettings.psd1", 15 | "powershell.scriptAnalysis.enable": true, 16 | "files.trimTrailingWhitespace": true, 17 | "files.trimFinalNewlines": true, 18 | "files.insertFinalNewline": true, 19 | "files.associations": { 20 | "*.ps1xml": "xml" 21 | }, 22 | "cSpell.words": [ 23 | "COMPANYNAME", 24 | "ICONURI", 25 | "LICENSEURI", 26 | "PROJECTURI", 27 | "RELEASENOTES", 28 | "buildhelpers", 29 | "endregion", 30 | "gitversion", 31 | "icontains", 32 | "keepachangelog", 33 | "notin", 34 | "pscmdlet", 35 | "steppable" 36 | ], 37 | "[markdown]": { 38 | "files.trimTrailingWhitespace": false, 39 | "files.encoding": "utf8" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /.vscode/analyzersettings.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | CustomRulePath = '.\output\RequiredModules\DscResource.AnalyzerRules' 3 | IncludeDefaultRules = $true 4 | IncludeRules = @( 5 | # DSC Resource Kit style guideline rules. 6 | 'PSAvoidDefaultValueForMandatoryParameter', 7 | 'PSAvoidDefaultValueSwitchParameter', 8 | 'PSAvoidInvokingEmptyMembers', 9 | 'PSAvoidNullOrEmptyHelpMessageAttribute', 10 | 'PSAvoidUsingCmdletAliases', 11 | 'PSAvoidUsingComputerNameHardcoded', 12 | 'PSAvoidUsingDeprecatedManifestFields', 13 | 'PSAvoidUsingEmptyCatchBlock', 14 | 'PSAvoidUsingInvokeExpression', 15 | 'PSAvoidUsingPositionalParameters', 16 | 'PSAvoidShouldContinueWithoutForce', 17 | 'PSAvoidUsingWMICmdlet', 18 | 'PSAvoidUsingWriteHost', 19 | 'PSDSCReturnCorrectTypesForDSCFunctions', 20 | 'PSDSCStandardDSCFunctionsInResource', 21 | 'PSDSCUseIdenticalMandatoryParametersForDSC', 22 | 'PSDSCUseIdenticalParametersForDSC', 23 | 'PSMisleadingBacktick', 24 | 'PSMissingModuleManifestField', 25 | 'PSPossibleIncorrectComparisonWithNull', 26 | 'PSProvideCommentHelp', 27 | 'PSReservedCmdletChar', 28 | 'PSReservedParams', 29 | 'PSUseApprovedVerbs', 30 | 'PSUseCmdletCorrectly', 31 | 'PSUseOutputTypeCorrectly', 32 | 'PSAvoidGlobalVars', 33 | 'PSAvoidUsingConvertToSecureStringWithPlainText', 34 | 'PSAvoidUsingPlainTextForPassword', 35 | 'PSAvoidUsingUsernameAndPasswordParams', 36 | 'PSDSCUseVerboseMessageInDSCResource', 37 | 'PSShouldProcess', 38 | 'PSUseDeclaredVarsMoreThanAssignments', 39 | 'PSUsePSCredentialType', 40 | 41 | 'Measure-*' 42 | ) 43 | 44 | } 45 | -------------------------------------------------------------------------------- /source/WikiSource/Home.md: -------------------------------------------------------------------------------- 1 | # Welcome to the xCredSSP wiki 2 | 3 | *xCredSSP v#.#.#* 4 | 5 | Here you will find all the information you need to make use of the xCredSSP 6 | DSC resources in the latest release. This includes details of the resources 7 | that are available, current capabilities, known issues, and information to 8 | help plan a DSC based implementation of xCredSSP. 9 | 10 | Please leave comments, feature requests, and bug reports for this module in 11 | the [issues section](https://github.com/dsccommunity/xCredSSP/issues) 12 | for this repository. 13 | 14 | ## Deprecated resources 15 | 16 | The documentation, examples, unit test, and integration tests have been removed 17 | for these deprecated resources. These resources will be removed 18 | in a future release. 19 | 20 | ### xCredSSP 21 | 22 | - No deprecated resource at this time 23 | 24 | ## Getting started 25 | 26 | To get started either: 27 | 28 | - Install from the PowerShell Gallery using PowerShellGet by running the 29 | following command: 30 | 31 | ```powershell 32 | Install-Module -Name xCredSSP -Repository PSGallery 33 | ``` 34 | 35 | - Download xCredSSP from the [PowerShell Gallery](https://www.powershellgallery.com/packages/xCredSSP) 36 | and then unzip it to one of your PowerShell modules folders (such as 37 | `$env:ProgramFiles\WindowsPowerShell\Modules`). 38 | 39 | To confirm installation, run the below command and ensure you see the xCredSSP 40 | DSC resources available: 41 | 42 | ```powershell 43 | Get-DscResource -Module xCredSSP 44 | ``` 45 | 46 | ## Prerequisites 47 | 48 | The minimum Windows Management Framework (PowerShell) version required is 4.0 49 | or higher. 50 | 51 | ## Change log 52 | 53 | A full list of changes in each version can be found in the [change log](https://github.com/dsccommunity/xCredSSP/blob/dev/CHANGELOG.md). 54 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Resource_proposal.yml: -------------------------------------------------------------------------------- 1 | name: New resource proposal 2 | description: If you have a new resource proposal that you think should be added to this resource module. 3 | title: "NewResourceName: New resource proposal" 4 | labels: [] 5 | assignees: [] 6 | body: 7 | - type: markdown 8 | attributes: 9 | value: | 10 | Please replace `NewResourceName` in the issue title (above) with your proposed resource name. 11 | 12 | Thank you for contributing and making this resource module better! 13 | - type: textarea 14 | id: description 15 | attributes: 16 | label: Resource proposal 17 | description: Provide information how this resource will/should work and how it will help users. 18 | validations: 19 | required: true 20 | - type: textarea 21 | id: proposedProperties 22 | attributes: 23 | label: Proposed properties 24 | description: | 25 | List all the proposed properties that the resource should have (key, required, write, and/or read). For each property provide a detailed description, the data type, if a default value should be used, and if the property is limited to a set of values. 26 | value: | 27 | Property | Type qualifier | Data type | Description | Default value | Allowed values 28 | --- | --- | --- | --- | --- | --- 29 | PropertyName | Key | String | Detailed description | None | None 30 | validations: 31 | required: true 32 | - type: textarea 33 | id: considerations 34 | attributes: 35 | label: Special considerations or limitations 36 | description: | 37 | Provide any considerations or limitations you can think of that a contributor should take in account when coding the proposed resource, and or what limitations a user will encounter or should consider when using the proposed resource. 38 | validations: 39 | required: true 40 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 12 | 13 | #### Pull Request (PR) description 14 | 15 | 19 | 20 | #### This Pull Request (PR) fixes the following issues 21 | 22 | 30 | 31 | #### Task list 32 | 33 | 40 | 41 | - [ ] Added an entry to the change log under the Unreleased section of the file CHANGELOG.md. 42 | Entry should say what was changed and how that affects users (if applicable), and 43 | reference the issue being resolved (if applicable). 44 | - [ ] Resource documentation added/updated in README.md. 45 | - [ ] Resource parameter descriptions added/updated in README.md, schema.mof and comment-based 46 | help. 47 | - [ ] Comment-based help added/updated. 48 | - [ ] Localization strings added/updated in all localization files as appropriate. 49 | - [ ] Examples appropriately added/updated. 50 | - [ ] Unit tests added/updated. See [DSC Community Testing Guidelines](https://dsccommunity.org/guidelines/testing-guidelines). 51 | - [ ] Integration tests added/updated (where possible). See [DSC Community Testing Guidelines](https://dsccommunity.org/guidelines/testing-guidelines). 52 | - [ ] New/changed code adheres to [DSC Community Style Guidelines](https://dsccommunity.org/styleguidelines). 53 | -------------------------------------------------------------------------------- /source/xCredSSP.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | # Version number of this module. 3 | ModuleVersion = '0.0.1' 4 | 5 | # ID used to uniquely identify this module 6 | GUID = '38e1ad0f-9b30-490a-a2b6-cc77765af4ec' 7 | 8 | # Author of this module 9 | Author = 'DSC Community' 10 | 11 | # Company or vendor of this module 12 | CompanyName = 'DSC Community' 13 | 14 | # Copyright statement for this module 15 | Copyright = 'Copyright the DSC Community contributors. All rights reserved.' 16 | 17 | # Description of the functionality provided by this module 18 | Description = 'This module contains DSC resources for configuration of the WSMan Credential Security Support Provider (CredSSP).' 19 | 20 | # Minimum version of the PowerShell engine required by this module 21 | PowerShellVersion = '4.0' 22 | 23 | # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. 24 | CLRVersion = '4.0' 25 | 26 | # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. 27 | FunctionsToExport = @() 28 | 29 | # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. 30 | CmdletsToExport = @() 31 | 32 | # Variables to export from this module 33 | VariablesToExport = @() 34 | 35 | # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. 36 | AliasesToExport = @() 37 | 38 | # DSC resources to export from this module 39 | DscResourcesToExport = @() 40 | 41 | # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. 42 | PrivateData = @{ 43 | PSData = @{ 44 | # Set to a prerelease string value if the release should be a prerelease. 45 | Prerelease = '' 46 | 47 | # Tags applied to this module. These help with module discovery in online galleries. 48 | Tags = @('DesiredStateConfiguration', 'DSC', 'DSCResourceKit', 'DSCResource') 49 | 50 | # A URL to the license for this module. 51 | LicenseUri = 'https://github.com/dsccommunity/xCredSSP/blob/main/LICENSE' 52 | 53 | # A URL to the main website for this project. 54 | ProjectUri = 'https://github.com/dsccommunity/xCredSSP' 55 | 56 | # A URL to an icon representing this module. 57 | IconUri = 'https://dsccommunity.org/images/DSC_Logo_300p.png' 58 | 59 | # ReleaseNotes of this module 60 | ReleaseNotes = '' 61 | } # End of PSData hashtable 62 | } # End of PrivateData hashtable 63 | } 64 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Problem_with_resource.yml: -------------------------------------------------------------------------------- 1 | name: Problem with a resource 2 | description: If you have a problem, bug, or enhancement with a resource in this resource module. 3 | labels: [] 4 | assignees: [] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Please prefix the issue title (above) with the resource name, e.g. 'ResourceName: Short description of my issue'! 10 | 11 | Your feedback and support is greatly appreciated, thanks for contributing! 12 | - type: textarea 13 | id: description 14 | attributes: 15 | label: Problem description 16 | description: Details of the scenario you tried and the problem that is occurring. 17 | validations: 18 | required: true 19 | - type: textarea 20 | id: logs 21 | attributes: 22 | label: Verbose logs 23 | description: | 24 | Verbose logs showing the problem. **NOTE! Sensitive information should be obfuscated.** _Will be automatically formatted as plain text._ 25 | placeholder: | 26 | Paste verbose logs here 27 | render: text 28 | validations: 29 | required: true 30 | - type: textarea 31 | id: configuration 32 | attributes: 33 | label: DSC configuration 34 | description: | 35 | The DSC configuration that is used to reproduce the issue (as detailed as possible). **NOTE! Sensitive information should be obfuscated.** _Will be automatically formatted as PowerShell code._ 36 | placeholder: | 37 | Paste DSC configuration here 38 | render: powershell 39 | validations: 40 | required: true 41 | - type: textarea 42 | id: suggestedSolution 43 | attributes: 44 | label: Suggested solution 45 | description: Do you have any suggestions how to solve the issue? 46 | validations: 47 | required: true 48 | - type: textarea 49 | id: targetNodeOS 50 | attributes: 51 | label: Operating system the target node is running 52 | description: | 53 | Please provide as much as possible about the target node, for example edition, version, build, and language. _Will be automatically formatted as plain text._ 54 | 55 | On OS with WMF 5.1 the following command can help get this information: `Get-ComputerInfo -Property @('OsName','OsOperatingSystemSKU','OSArchitecture','WindowsVersion','WindowsBuildLabEx','OsLanguage','OsMuiLanguages')` 56 | placeholder: | 57 | Add operating system information here 58 | render: text 59 | validations: 60 | required: true 61 | - type: textarea 62 | id: targetNodePS 63 | attributes: 64 | label: PowerShell version and build the target node is running 65 | description: | 66 | Please provide the version and build of PowerShell the target node is running. _Will be automatically formatted as plain text._ 67 | 68 | To help with this information, please run this command: `$PSVersionTable` 69 | placeholder: | 70 | Add PowerShell information here 71 | render: text 72 | validations: 73 | required: true 74 | - type: textarea 75 | id: moduleVersion 76 | attributes: 77 | label: xCredSSP version 78 | description: | 79 | Please provide the version of the xCredSSP module that was used. _Will be automatically formatted as plain text._ 80 | 81 | To help with this information, please run this command: `Get-Module -Name 'xCredSSP' -ListAvailable | ft Name,Version,Path` 82 | placeholder: | 83 | Add module information here 84 | render: text 85 | validations: 86 | required: true 87 | 88 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # xCredSSP 2 | 3 | This module contains DSC resources for the management and 4 | configuration of Credential Security Support Provider (CredSSP). 5 | 6 | [![Build Status](https://dev.azure.com/dsccommunity/xCredSSP/_apis/build/status/dsccommunity.xCredSSP?branchName=main)](https://dev.azure.com/dsccommunity/xCredSSP/_build/latest?definitionId=52&branchName=main) 7 | ![Azure DevOps coverage (branch)](https://img.shields.io/azure-devops/coverage/dsccommunity/xCredSSP/52/main) 8 | [![codecov](https://codecov.io/gh/dsccommunity/xCredSSP/branch/main/graph/badge.svg)](https://codecov.io/gh/dsccommunity/xCredSSP) 9 | [![Azure DevOps tests](https://img.shields.io/azure-devops/tests/dsccommunity/xCredSSP/52/main)](https://dsccommunity.visualstudio.com/xCredSSP/_test/analytics?definitionId=52&contextType=build) 10 | [![PowerShell Gallery (with prereleases)](https://img.shields.io/powershellgallery/vpre/xCredSSP?label=xCredSSP%20Preview)](https://www.powershellgallery.com/packages/xCredSSP/) 11 | [![PowerShell Gallery](https://img.shields.io/powershellgallery/v/xCredSSP?label=xCredSSP)](https://www.powershellgallery.com/packages/xCredSSP/) 12 | 13 | ## Code of Conduct 14 | 15 | This project has adopted this [Code of Conduct](CODE_OF_CONDUCT.md). 16 | 17 | ## Releases 18 | 19 | For each merge to the branch `main` a preview release will be 20 | deployed to [PowerShell Gallery](https://www.powershellgallery.com/). 21 | Periodically a release version tag will be pushed which will deploy a 22 | full release to [PowerShell Gallery](https://www.powershellgallery.com/). 23 | 24 | ## Contributing 25 | 26 | Please check out common DSC Community [contributing guidelines](https://dsccommunity.org/guidelines/contributing). 27 | 28 | ## Change log 29 | 30 | A full list of changes in each version can be found in the [change log](CHANGELOG.md). 31 | 32 | ## Documentation 33 | 34 | The documentation can be found in the [xCredSSP Wiki](https://github.com/dsccommunity/xCredSSP/wiki). 35 | The DSC resources schema files is used to automatically update the 36 | documentation on each PR merge. 37 | 38 | ## Requirements 39 | 40 | This module requires the latest version of PowerShell (v4.0, which ships in 41 | Windows 8.1 or Windows Server 2012R2). To easily use PowerShell 4.0 on older 42 | operating systems, [install WMF 4.0](http://www.microsoft.com/en-us/download/details.aspx?id=40855). 43 | Please read the installation instructions that are present on both the download 44 | page and the release notes for WMF 4.0. 45 | 46 | ### Examples 47 | 48 | You can review the [Examples](/source/Examples) directory in the xCredSSP module 49 | for some general use scenarios for all of the resources that are in the module. 50 | 51 | The resource examples are also available in the [xCredSSP Wiki](https://github.com/dsccommunity/xCredSSP/wiki). 52 | 53 | ## Resources 54 | 55 | ### xCredSSP 56 | 57 | This resource enables or disables Credential Security Support Provider (CredSSP) 58 | authentication on a client or on a server computer, and which server or servers 59 | the client credentials can be delegated to. 60 | 61 | #### Parameters 62 | 63 | - **Ensure:** Specifies whether the domain trust is present or absent 64 | - **Role**: REQUIRED parameter representing the CredSSP role, and is either 65 | "Server" or "Client" 66 | - **DelegateComputers**: Array of servers to be delegated to, REQUIRED when 67 | Role is set to "Client". 68 | - **SuppressReboot**: Specifies whether a necessary reboot has to be suppressed 69 | or not. 70 | 71 | ## Examples 72 | 73 | ### xCredSSP 74 | 75 | Enable CredSSP for both server and client roles, and delegate to Server1 and Server2. 76 | 77 | ```powershell 78 | Configuration EnableCredSSP 79 | { 80 | Import-DscResource -Module xCredSSP 81 | Node localhost 82 | { 83 | xCredSSP Server 84 | { 85 | Ensure = "Present" 86 | Role = "Server" 87 | } 88 | xCredSSP Client 89 | { 90 | Ensure = "Present" 91 | Role = "Client" 92 | DelegateComputers = "Server1","Server2" 93 | } 94 | } 95 | } 96 | ``` 97 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "_runner": "terminal", 4 | "windows": { 5 | "options": { 6 | "shell": { 7 | "executable": "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", 8 | "args": [ 9 | "-NoProfile", 10 | "-ExecutionPolicy", 11 | "Bypass", 12 | "-Command" 13 | ] 14 | } 15 | } 16 | }, 17 | "linux": { 18 | "options": { 19 | "shell": { 20 | "executable": "/usr/bin/pwsh", 21 | "args": [ 22 | "-NoProfile", 23 | "-Command" 24 | ] 25 | } 26 | } 27 | }, 28 | "osx": { 29 | "options": { 30 | "shell": { 31 | "executable": "/usr/local/bin/pwsh", 32 | "args": [ 33 | "-NoProfile", 34 | "-Command" 35 | ] 36 | } 37 | } 38 | }, 39 | "tasks": [ 40 | { 41 | "label": "build", 42 | "type": "shell", 43 | "command": "&${cwd}/build.ps1", 44 | "args": [], 45 | "presentation": { 46 | "echo": true, 47 | "reveal": "always", 48 | "focus": true, 49 | "panel": "new", 50 | "clear": false 51 | }, 52 | "runOptions": { 53 | "runOn": "default" 54 | }, 55 | "problemMatcher": [ 56 | { 57 | "owner": "powershell", 58 | "fileLocation": [ 59 | "absolute" 60 | ], 61 | "severity": "error", 62 | "pattern": [ 63 | { 64 | "regexp": "^\\s*(\\[-\\]\\s*.*?)(\\d+)ms\\s*$", 65 | "message": 1 66 | }, 67 | { 68 | "regexp": "(.*)", 69 | "code": 1 70 | }, 71 | { 72 | "regexp": "" 73 | }, 74 | { 75 | "regexp": "^.*,\\s*(.*):\\s*line\\s*(\\d+).*", 76 | "file": 1, 77 | "line": 2 78 | } 79 | ] 80 | } 81 | ] 82 | }, 83 | { 84 | "label": "test", 85 | "type": "shell", 86 | "command": "&${cwd}/build.ps1", 87 | "args": ["-AutoRestore","-Tasks","test"], 88 | "presentation": { 89 | "echo": true, 90 | "reveal": "always", 91 | "focus": true, 92 | "panel": "dedicated", 93 | "showReuseMessage": true, 94 | "clear": false 95 | }, 96 | "problemMatcher": [ 97 | { 98 | "owner": "powershell", 99 | "fileLocation": [ 100 | "absolute" 101 | ], 102 | "severity": "error", 103 | "pattern": [ 104 | { 105 | "regexp": "^\\s*(\\[-\\]\\s*.*?)(\\d+)ms\\s*$", 106 | "message": 1 107 | }, 108 | { 109 | "regexp": "(.*)", 110 | "code": 1 111 | }, 112 | { 113 | "regexp": "" 114 | }, 115 | { 116 | "regexp": "^.*,\\s*(.*):\\s*line\\s*(\\d+).*", 117 | "file": 1, 118 | "line": 2 119 | } 120 | ] 121 | } 122 | ] 123 | } 124 | ] 125 | } 126 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | trigger: 2 | branches: 3 | include: 4 | - main 5 | paths: 6 | include: 7 | - source/* 8 | tags: 9 | include: 10 | - "v*" 11 | exclude: 12 | - "*-*" 13 | 14 | variables: 15 | buildFolderName: output 16 | buildArtifactName: output 17 | testResultFolderName: testResults 18 | testArtifactName: testResults 19 | sourceFolderName: source 20 | defaultBranch: main 21 | 22 | stages: 23 | - stage: Build 24 | jobs: 25 | - job: Package_Module 26 | displayName: 'Package Module' 27 | pool: 28 | vmImage: 'ubuntu-latest' 29 | steps: 30 | - pwsh: | 31 | dotnet tool install --global GitVersion.Tool 32 | $gitVersionObject = dotnet-gitversion | ConvertFrom-Json 33 | $gitVersionObject.PSObject.Properties.ForEach{ 34 | Write-Host -Object "Setting Task Variable '$($_.Name)' with value '$($_.Value)'." 35 | Write-Host -Object "##vso[task.setvariable variable=$($_.Name);]$($_.Value)" 36 | } 37 | Write-Host -Object "##vso[build.updatebuildnumber]$($gitVersionObject.FullSemVer)" 38 | displayName: Calculate ModuleVersion (GitVersion) 39 | - task: PowerShell@2 40 | name: package 41 | displayName: 'Build & Package Module' 42 | inputs: 43 | filePath: './build.ps1' 44 | arguments: '-ResolveDependency -tasks pack' 45 | pwsh: true 46 | env: 47 | ModuleVersion: $(NuGetVersionV2) 48 | - task: PublishPipelineArtifact@1 49 | displayName: 'Publish Build Artifact' 50 | inputs: 51 | targetPath: '$(buildFolderName)/' 52 | artifact: $(buildArtifactName) 53 | publishLocation: 'pipeline' 54 | parallel: true 55 | 56 | - stage: Test 57 | dependsOn: Build 58 | jobs: 59 | - job: Test_HQRM 60 | displayName: 'HQRM' 61 | pool: 62 | vmImage: 'windows-latest' 63 | timeoutInMinutes: 0 64 | steps: 65 | - task: DownloadPipelineArtifact@2 66 | displayName: 'Download Build Artifact' 67 | inputs: 68 | buildType: 'current' 69 | artifactName: $(buildArtifactName) 70 | targetPath: '$(Build.SourcesDirectory)/$(buildFolderName)' 71 | - task: PowerShell@2 72 | name: test 73 | displayName: 'Run HQRM Test' 74 | inputs: 75 | filePath: './build.ps1' 76 | arguments: '-Tasks hqrmtest' 77 | pwsh: false 78 | - task: PublishTestResults@2 79 | displayName: 'Publish Test Results' 80 | condition: succeededOrFailed() 81 | inputs: 82 | testResultsFormat: 'NUnit' 83 | testResultsFiles: 'output/testResults/NUnit*.xml' 84 | testRunTitle: 'HQRM' 85 | 86 | - job: Test_Unit 87 | displayName: 'Unit' 88 | pool: 89 | vmImage: 'windows-latest' 90 | timeoutInMinutes: 0 91 | steps: 92 | - task: DownloadPipelineArtifact@2 93 | displayName: 'Download Build Artifact' 94 | inputs: 95 | buildType: 'current' 96 | artifactName: $(buildArtifactName) 97 | targetPath: '$(Build.SourcesDirectory)/$(buildFolderName)' 98 | - task: PowerShell@2 99 | name: test 100 | displayName: 'Run Unit Test' 101 | inputs: 102 | filePath: './build.ps1' 103 | arguments: "-Tasks test -PesterScript 'tests/Unit'" 104 | pwsh: true 105 | - task: PublishTestResults@2 106 | displayName: 'Publish Test Results' 107 | condition: succeededOrFailed() 108 | inputs: 109 | testResultsFormat: 'NUnit' 110 | testResultsFiles: '$(buildFolderName)/$(testResultFolderName)/NUnit*.xml' 111 | testRunTitle: 'Unit' 112 | - task: PublishPipelineArtifact@1 113 | displayName: 'Publish Test Artifact' 114 | inputs: 115 | targetPath: '$(buildFolderName)/$(testResultFolderName)/' 116 | artifactName: $(testArtifactName) 117 | parallel: true 118 | 119 | - job: Test_Integration 120 | displayName: 'Integration' 121 | pool: 122 | vmImage: 'windows-latest' 123 | timeoutInMinutes: 0 124 | steps: 125 | - task: DownloadPipelineArtifact@2 126 | displayName: 'Download Build Artifact' 127 | inputs: 128 | buildType: 'current' 129 | artifactName: $(buildArtifactName) 130 | targetPath: '$(Build.SourcesDirectory)/$(buildFolderName)' 131 | - task: PowerShell@2 132 | name: configureWinRM 133 | displayName: 'Configure WinRM' 134 | inputs: 135 | targetType: 'inline' 136 | script: 'winrm quickconfig -quiet' 137 | pwsh: false 138 | - task: PowerShell@2 139 | name: test 140 | displayName: 'Run Integration Test' 141 | inputs: 142 | filePath: './build.ps1' 143 | arguments: "-Tasks test -CodeCoverageThreshold 0 -PesterScript 'tests/Integration'" 144 | pwsh: false 145 | - task: PublishTestResults@2 146 | displayName: 'Publish Test Results' 147 | condition: succeededOrFailed() 148 | inputs: 149 | testResultsFormat: 'NUnit' 150 | testResultsFiles: '$(buildFolderName)/$(testResultFolderName)/NUnit*.xml' 151 | testRunTitle: 'Integration' 152 | 153 | - job: Code_Coverage 154 | displayName: 'Publish Code Coverage' 155 | dependsOn: Test_Unit 156 | pool: 157 | vmImage: 'ubuntu-latest' 158 | timeoutInMinutes: 0 159 | steps: 160 | - task: DownloadPipelineArtifact@2 161 | displayName: 'Download Build Artifact' 162 | inputs: 163 | buildType: 'current' 164 | artifactName: $(buildArtifactName) 165 | targetPath: '$(Build.SourcesDirectory)/$(buildFolderName)' 166 | - task: DownloadPipelineArtifact@2 167 | displayName: 'Download Test Artifact' 168 | inputs: 169 | buildType: 'current' 170 | artifactName: $(testArtifactName) 171 | targetPath: '$(Build.SourcesDirectory)/$(buildFolderName)/$(testResultFolderName)' 172 | - task: PublishCodeCoverageResults@1 173 | displayName: 'Publish Code Coverage to Azure DevOps' 174 | inputs: 175 | codeCoverageTool: 'JaCoCo' 176 | summaryFileLocation: '$(Build.SourcesDirectory)/$(buildFolderName)/$(testResultFolderName)/JaCoCo_coverage.xml' 177 | pathToSources: '$(Build.SourcesDirectory)/$(sourceFolderName)/' 178 | - script: | 179 | bash <(curl -s https://codecov.io/bash) -f "./$(buildFolderName)/$(testResultFolderName)/JaCoCo_coverage.xml" 180 | displayName: 'Publish Code Coverage to Codecov.io' 181 | 182 | - stage: Deploy 183 | dependsOn: Test 184 | condition: | 185 | and( 186 | succeeded(), 187 | or( 188 | eq(variables['Build.SourceBranch'], 'refs/heads/main'), 189 | startsWith(variables['Build.SourceBranch'], 'refs/tags/') 190 | ), 191 | contains(variables['System.TeamFoundationCollectionUri'], 'dsccommunity') 192 | ) 193 | jobs: 194 | - job: Deploy_Module 195 | displayName: 'Deploy Module' 196 | pool: 197 | vmImage: 'ubuntu-latest' 198 | steps: 199 | - task: DownloadPipelineArtifact@2 200 | displayName: 'Download Pipeline Artifact' 201 | inputs: 202 | buildType: 'current' 203 | artifactName: $(buildArtifactName) 204 | targetPath: '$(Build.SourcesDirectory)/$(buildArtifactName)' 205 | - task: PowerShell@2 206 | name: publishRelease 207 | displayName: 'Publish Release' 208 | inputs: 209 | filePath: './build.ps1' 210 | arguments: '-tasks publish' 211 | pwsh: true 212 | env: 213 | GitHubToken: $(GitHubToken) 214 | GalleryApiToken: $(GalleryApiToken) 215 | ReleaseBranch: $(defaultBranch) 216 | MainGitBranch: $(defaultBranch) 217 | - task: PowerShell@2 218 | name: sendChangelogPR 219 | displayName: 'Send Changelog PR' 220 | inputs: 221 | filePath: './build.ps1' 222 | arguments: '-tasks Create_ChangeLog_GitHub_PR' 223 | pwsh: true 224 | env: 225 | GitHubToken: $(GitHubToken) 226 | ReleaseBranch: $(defaultBranch) 227 | MainGitBranch: $(defaultBranch) 228 | -------------------------------------------------------------------------------- /source/DSCResources/MSFT_xCredSSP/MSFT_xCredSSP.psm1: -------------------------------------------------------------------------------- 1 | function Get-TargetResource 2 | { 3 | [CmdletBinding()] 4 | [OutputType([System.Collections.Hashtable])] 5 | param 6 | ( 7 | [Parameter(Mandatory = $true)] 8 | [ValidateSet("Server","Client")] 9 | [System.String] 10 | $Role 11 | ) 12 | 13 | #Check if GPO policy has been set 14 | switch ($Role) 15 | { 16 | "Server" 17 | { 18 | $RegKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" 19 | } 20 | "Client" 21 | { 22 | $RegKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" 23 | } 24 | } 25 | $RegValueName = "AllowCredSSP" 26 | 27 | if (Test-RegistryValue -Path $RegKey -Name $RegValueName) 28 | { 29 | Write-Verbose -Message "CredSSP is configured via Group Policies" 30 | } 31 | else 32 | { 33 | # Check regular values 34 | switch ($Role) 35 | { 36 | "Server" 37 | { 38 | $RegKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WSMAN\Service" 39 | } 40 | "Client" 41 | { 42 | $RegKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WSMAN\Client" 43 | } 44 | } 45 | $RegValueName = "auth_credssp" 46 | } 47 | 48 | if (Test-RegistryValue -Path $RegKey -Name $RegValueName) 49 | { 50 | $Setting = (Get-ItemProperty -Path $RegKey -Name $RegValueName).$RegValueName 51 | } 52 | else 53 | { 54 | $Setting = 0 55 | } 56 | 57 | switch ($Role) 58 | { 59 | "Server" 60 | { 61 | switch ($Setting) 62 | { 63 | 1 64 | { 65 | $returnValue = @{ 66 | Ensure = "Present"; 67 | Role = "Server" 68 | } 69 | } 70 | 0 71 | { 72 | $returnValue = @{ 73 | Ensure = "Absent"; 74 | Role = "Server" 75 | } 76 | } 77 | } 78 | } 79 | "Client" 80 | { 81 | switch ($Setting) 82 | { 83 | 1 84 | { 85 | $key = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation\AllowFreshCredentials" 86 | 87 | $DelegateComputers = @() 88 | 89 | 90 | Get-Item -Path $key -ErrorAction SilentlyContinue | 91 | Select-Object -ExpandProperty Property | 92 | ForEach-Object { 93 | $DelegateComputer = ((Get-ItemProperty -Path $key -Name $_).$_).Split("/")[1] 94 | $DelegateComputers += $DelegateComputer 95 | } 96 | $DelegateComputers = $DelegateComputers | Sort-Object -Unique 97 | 98 | $returnValue = @{ 99 | Ensure = "Present"; 100 | Role = "Client"; 101 | DelegateComputers = @($DelegateComputers) 102 | } 103 | } 104 | 0 105 | { 106 | $returnValue = @{ 107 | Ensure = "Absent"; 108 | Role = "Client" 109 | } 110 | } 111 | } 112 | } 113 | } 114 | 115 | return $returnValue 116 | } 117 | 118 | 119 | function Set-TargetResource 120 | { 121 | [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSDSCUseVerboseMessageInDSCResource', '', Justification = 'Suppressed until localized messages are added to the function')] 122 | [CmdletBinding()] 123 | param 124 | ( 125 | [Parameter()] 126 | [ValidateSet("Present","Absent")] 127 | [System.String] 128 | $Ensure = "Present", 129 | 130 | [Parameter(Mandatory = $true)] 131 | [ValidateSet("Server","Client")] 132 | [System.String] 133 | $Role, 134 | 135 | [Parameter()] 136 | [System.String[]] 137 | $DelegateComputers, 138 | 139 | [Parameter()] 140 | [System.Boolean] 141 | $SuppressReboot = $false 142 | ) 143 | 144 | if ($Role -eq "Server" -and ($DelegateComputers)) 145 | { 146 | throw ("Cannot use the Role=Server parameter together with " + ` 147 | "the DelegateComputers parameter") 148 | } 149 | 150 | #Check if policy has been set 151 | switch ($Role) 152 | { 153 | "Server" 154 | { 155 | $RegKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" 156 | } 157 | "Client" 158 | { 159 | $RegKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" 160 | } 161 | } 162 | $RegValueName = "AllowCredSSP" 163 | 164 | if (Test-RegistryValue -Path $RegKey -Name $RegValueName) 165 | { 166 | throw "Cannot configure CredSSP. CredSSP is configured via Group Policies" 167 | } 168 | 169 | switch ($Role) 170 | { 171 | "Server" 172 | { 173 | switch ($Ensure) 174 | { 175 | "Present" 176 | { 177 | Enable-WSManCredSSP -Role Server -Force | Out-Null 178 | if ($SuppressReboot -eq $false) 179 | { 180 | $global:DSCMachineStatus = 1 181 | } 182 | } 183 | "Absent" 184 | { 185 | Disable-WSManCredSSP -Role Server | Out-Null 186 | } 187 | } 188 | } 189 | "Client" 190 | { 191 | switch ($Ensure) 192 | { 193 | "Present" 194 | { 195 | if ($DelegateComputers) 196 | { 197 | $key = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation\AllowFreshCredentials" 198 | 199 | if (!(test-path $key)) 200 | { 201 | New-Item $key -Force | out-null 202 | } 203 | 204 | $CurrentDelegateComputers = @() 205 | 206 | Get-Item -Path $key | 207 | Select-Object -ExpandProperty Property | 208 | ForEach-Object { 209 | $CurrentDelegateComputer = ((Get-ItemProperty -Path $key -Name $_).$_).Split("/")[1] 210 | $CurrentDelegateComputers += $CurrentDelegateComputer 211 | } 212 | $CurrentDelegateComputers = $CurrentDelegateComputers | Sort-Object -Unique 213 | 214 | foreach ($DelegateComputer in $DelegateComputers) 215 | { 216 | if (($null -eq $CurrentDelegateComputers) -or ($CurrentDelegateComputers -notcontains $DelegateComputer)) 217 | { 218 | Enable-WSManCredSSP -Role Client -DelegateComputer $DelegateComputer -Force | Out-Null 219 | if ($SuppressReboot -eq $false) 220 | { 221 | $global:DSCMachineStatus = 1 222 | } 223 | } 224 | } 225 | } 226 | else 227 | { 228 | throw "DelegateComputers is required!" 229 | } 230 | } 231 | "Absent" 232 | { 233 | Disable-WSManCredSSP -Role Client | Out-Null 234 | } 235 | } 236 | } 237 | } 238 | } 239 | 240 | 241 | function Test-TargetResource 242 | { 243 | [CmdletBinding()] 244 | [OutputType([System.Boolean])] 245 | param 246 | ( 247 | [Parameter()] 248 | [ValidateSet("Present","Absent")] 249 | [System.String] 250 | $Ensure = "Present", 251 | 252 | [Parameter(Mandatory = $true)] 253 | [ValidateSet("Server","Client")] 254 | [System.String] 255 | $Role, 256 | 257 | [Parameter()] 258 | [System.String[]] 259 | $DelegateComputers, 260 | 261 | [Parameter()] 262 | [System.Boolean] 263 | $SuppressReboot = $false 264 | ) 265 | 266 | if ($Role -eq "Server" -and $PSBoundParameters.ContainsKey("DelegateComputers")) 267 | { 268 | Write-Verbose -Message ("Cannot use the Role=Server parameter together with " + ` 269 | "the DelegateComputers parameter") 270 | } 271 | 272 | $CredSSP = Get-TargetResource -Role $Role 273 | 274 | switch ($Role) 275 | { 276 | "Server" 277 | { 278 | return ($CredSSP.Ensure -eq $Ensure) 279 | } 280 | "Client" 281 | { 282 | switch ($Ensure) 283 | { 284 | "Present" 285 | { 286 | $CorrectDelegateComputers = $true 287 | if ($DelegateComputers) 288 | { 289 | foreach ($DelegateComputer in $DelegateComputers) 290 | { 291 | if (!($CredSSP.DelegateComputers | Where-Object {$_ -eq $DelegateComputer})) 292 | { 293 | $CorrectDelegateComputers = $false 294 | } 295 | } 296 | } 297 | $result = (($CredSSP.Ensure -eq $Ensure) -and $CorrectDelegateComputers) 298 | } 299 | "Absent" 300 | { 301 | $result = ($CredSSP.Ensure -eq $Ensure) 302 | } 303 | } 304 | } 305 | } 306 | 307 | return $result 308 | } 309 | 310 | 311 | Export-ModuleMember -Function *-TargetResource 312 | 313 | 314 | function Test-RegistryValue 315 | { 316 | param ( 317 | [Parameter(Mandatory = $true)] 318 | [String]$Path 319 | , 320 | [Parameter(Mandatory = $true)] 321 | [String]$Name 322 | ) 323 | 324 | if ($null -eq $Path) 325 | { 326 | return $false 327 | } 328 | 329 | $itemProperties = Get-ItemProperty -Path $Path -ErrorAction SilentlyContinue 330 | return ($null -ne $itemProperties -and $null -ne $itemProperties.$Name) 331 | } 332 | -------------------------------------------------------------------------------- /tests/Unit/MSFT_xCredSSP.tests.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Unit tests for MSFT_xCredSSP 4 | .DESCRIPTION 5 | Unit tests for MSFT_xCredSSP 6 | 7 | .NOTES 8 | Code in HEADER and FOOTER regions are standard and may be moved into DSCResource.Tools in 9 | Future and therefore should not be altered if possible. 10 | #> 11 | 12 | 13 | $script:dscModuleName = 'xCredSSP' # Example xNetworking 14 | $script:dscResourceName = 'MSFT_xCredSSP' # Example MSFT_xFirewall 15 | 16 | function Invoke-TestSetup 17 | { 18 | try 19 | { 20 | Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' 21 | } 22 | catch [System.IO.FileNotFoundException] 23 | { 24 | throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' 25 | } 26 | 27 | $script:testEnvironment = Initialize-TestEnvironment ` 28 | -DSCModuleName $script:dscModuleName ` 29 | -DSCResourceName $script:dscResourceName ` 30 | -ResourceType 'Mof' ` 31 | -TestType 'Unit' 32 | } 33 | 34 | function Invoke-TestCleanup 35 | { 36 | Restore-TestEnvironment -TestEnvironment $script:testEnvironment 37 | } 38 | 39 | Invoke-TestSetup 40 | 41 | try 42 | { 43 | InModuleScope $script:dscResourceName { 44 | Describe "$($script:dscModuleName)\Get-TargetResource" { 45 | # TODO: Complete Tests... 46 | } 47 | 48 | Describe "$($script:dscModuleName)\Test-TargetResource" { 49 | Context "Enable Server Role with invalid delegate Computer parameter" { 50 | BeforeAll { 51 | $global:DSCMachineStatus = $null 52 | } 53 | AfterAll { 54 | $global:DSCMachineStatus = $null 55 | } 56 | 57 | mock Enable-WSManCredSSP -MockWith {} -Verifiable 58 | mock Disable-WSManCredSSP -MockWith {} 59 | 60 | it 'should throw' { 61 | Test-TargetResource -Ensure 'Present' -Role Server -DelegateComputer 'foo' | Should Be $false 62 | } 63 | } 64 | 65 | Context "Server Role not configured" { 66 | BeforeAll { 67 | $global:DSCMachineStatus = $null 68 | } 69 | AfterAll { 70 | $global:DSCMachineStatus = $null 71 | } 72 | 73 | mock Get-ItemProperty -MockWith { 74 | return @{ auth_credssp = 0 } 75 | } 76 | it 'should not return anything' { 77 | Test-TargetResource -Ensure 'Present' -Role Server | should be $false 78 | } 79 | } 80 | 81 | Context "Client Role not configured" { 82 | BeforeAll { 83 | $global:DSCMachineStatus = $null 84 | } 85 | AfterAll { 86 | $global:DSCMachineStatus = $null 87 | } 88 | 89 | Mock Get-WSManCredSSP -MockWith {@([string]::Empty,[string]::Empty)} 90 | mock Get-ItemProperty -MockWith { 91 | return @{ 92 | 1 = "wsman/testserver.domain.com" 93 | 2 = "wsman/testserver2.domain.com" 94 | } 95 | } 96 | mock Get-Item -MockWith { 97 | $client1 = New-Object -typename PSObject| 98 | Add-Member NoteProperty "Name" 1 -PassThru | 99 | Add-Member NoteProperty "Property" 1 -PassThru 100 | 101 | $client2 = New-Object -typename PSObject| 102 | Add-Member NoteProperty "Name" 2 -PassThru | 103 | Add-Member NoteProperty "Property" 2 -PassThru 104 | 105 | return @($client1, $client2) 106 | } 107 | 108 | it 'should not return anything' { 109 | Test-TargetResource -Ensure 'Present' -Role Client -DelegateComputer 'foo' | should be $false 110 | } 111 | } 112 | # TODO: Complete Tests... 113 | } 114 | 115 | Describe "$($script:dscModuleName)\Set-TargetResource" { 116 | Context "Enable Server Role with invalid delegate Computer parameter" { 117 | BeforeAll { 118 | $global:DSCMachineStatus = $null 119 | } 120 | AfterAll { 121 | $global:DSCMachineStatus = $null 122 | } 123 | 124 | mock Enable-WSManCredSSP -MockWith {} -Verifiable 125 | mock Disable-WSManCredSSP -MockWith {} 126 | 127 | it 'should throw' { 128 | { Set-TargetResource -Ensure 'Present' -Role Server -DelegateComputer 'foo' } | should throw 129 | } 130 | it 'should have not called enable' { 131 | Assert-MockCalled -CommandName Enable-WSManCredSSP -Times 0 -Scope 'Context' 132 | } 133 | it 'should have not called disable' { 134 | Assert-MockCalled -CommandName Disable-WSManCredSSP -Times 0 -Scope 'Context' 135 | } 136 | it 'Should not have triggered a reboot' { 137 | $global:DSCMachineStatus | should be $null 138 | } 139 | } 140 | 141 | Context "Enable Server Role when it has been configured using GPO" { 142 | BeforeAll { 143 | $global:DSCMachineStatus = $null 144 | } 145 | AfterAll { 146 | $global:DSCMachineStatus = $null 147 | } 148 | 149 | mock Enable-WSManCredSSP -MockWith {} -Verifiable 150 | mock Disable-WSManCredSSP -MockWith {} 151 | mock Get-ItemProperty -MockWith { 152 | return @{ AllowCredSSP = 1 } 153 | } -ParameterFilter { $Path -eq "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" } 154 | 155 | it 'should throw' { 156 | { Set-TargetResource -Ensure 'Present' -Role Server }| should throw 157 | } 158 | it 'should have not called enable' { 159 | Assert-MockCalled -CommandName Enable-WSManCredSSP -Times 0 -Scope 'Context' 160 | } 161 | it 'should have not called disable' { 162 | Assert-MockCalled -CommandName Disable-WSManCredSSP -Times 0 -Scope 'Context' 163 | } 164 | it 'Should not have triggered a reboot' { 165 | $global:DSCMachineStatus | should be $null 166 | } 167 | } 168 | 169 | Context "Enable Client Role when it has been configured using GPO" { 170 | BeforeAll { 171 | $global:DSCMachineStatus = $null 172 | } 173 | AfterAll { 174 | $global:DSCMachineStatus = $null 175 | } 176 | 177 | mock Enable-WSManCredSSP -MockWith {} -Verifiable 178 | mock Disable-WSManCredSSP -MockWith {} 179 | mock Get-ItemProperty -MockWith { 180 | return @{ AllowCredSSP = 1 } 181 | } -ParameterFilter { $Path -eq "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client" } 182 | 183 | it 'should throw' { 184 | {Set-TargetResource -Ensure 'Present' -Role Client -DelegateComputers 'foo'}| should throw 185 | } 186 | it 'should have not called enable' { 187 | Assert-MockCalled -CommandName Enable-WSManCredSSP -Times 0 -Scope 'Context' 188 | } 189 | it 'should have not called disable' { 190 | Assert-MockCalled -CommandName Disable-WSManCredSSP -Times 0 -Scope 'Context' 191 | } 192 | it 'Should not have triggered a reboot' { 193 | $global:DSCMachineStatus | should be $null 194 | } 195 | } 196 | 197 | Context "Enable Server Role" { 198 | BeforeAll { 199 | $global:DSCMachineStatus = $null 200 | } 201 | AfterAll { 202 | $global:DSCMachineStatus = $null 203 | } 204 | 205 | mock Enable-WSManCredSSP -MockWith {} -Verifiable 206 | mock Disable-WSManCredSSP -MockWith {} 207 | mock Get-ItemProperty -MockWith { 208 | return @{ auth_credssp = 1 } 209 | } 210 | it 'should not return anything' { 211 | Set-TargetResource -Ensure 'Present' -Role Server | should be $null 212 | } 213 | it 'should have called enable'{ 214 | Assert-MockCalled -CommandName Enable-WSManCredSSP -Times 1 -ParameterFilter {$Role -eq 'Server' -and $Force -eq $true} 215 | } 216 | it 'should have not called disable' { 217 | Assert-MockCalled -CommandName Disable-WSManCredSSP -Times 0 218 | } 219 | it 'Should have triggered a reboot'{ 220 | $global:DSCMachineStatus | should be 1 221 | } 222 | } 223 | 224 | Context "Enable Client Role" { 225 | BeforeAll { 226 | Mock -CommandName New-Item -ParameterFilter { 227 | $Path -eq 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation\AllowFreshCredentials' 228 | } 229 | 230 | $global:DSCMachineStatus = $null 231 | } 232 | AfterAll { 233 | $global:DSCMachineStatus = $null 234 | } 235 | 236 | Mock Get-WSManCredSSP -MockWith {@([string]::Empty,[string]::Empty)} 237 | mock Enable-WSManCredSSP -MockWith {} -Verifiable 238 | mock Disable-WSManCredSSP -MockWith {} 239 | mock Get-ItemProperty -MockWith { 240 | return @{ 241 | 1 = "wsman/testserver.domain.com" 242 | 2 = "wsman/testserver2.domain.com" 243 | } 244 | } 245 | mock Get-Item -MockWith { 246 | $client1 = New-Object -typename PSObject| 247 | Add-Member NoteProperty "Name" 1 -PassThru | 248 | Add-Member NoteProperty "Property" 1 -PassThru 249 | 250 | $client2 = New-Object -typename PSObject| 251 | Add-Member NoteProperty "Name" 2 -PassThru | 252 | Add-Member NoteProperty "Property" 2 -PassThru 253 | 254 | return @($client1, $client2) 255 | } 256 | 257 | it 'should not return anything' { 258 | Set-TargetResource -Ensure 'Present' -Role Client -DelegateComputer 'foo' | should be $null 259 | } 260 | it 'should have called enable'{ 261 | Assert-MockCalled -CommandName Enable-WSManCredSSP -Times 1 -ParameterFilter {$Role -eq 'Client' -and $Force -eq $true -and $DelegateComputer -eq 'foo'} 262 | } 263 | it 'should have not called disable' { 264 | Assert-MockCalled -CommandName Disable-WSManCredSSP -Times 0 265 | } 266 | it 'Should have triggered a reboot'{ 267 | $global:DSCMachineStatus | should be 1 268 | } 269 | } 270 | Context "Enable Client Role with invalid delegate Computer parameter" { 271 | BeforeAll { 272 | $global:DSCMachineStatus = $null 273 | } 274 | AfterAll { 275 | $global:DSCMachineStatus = $null 276 | } 277 | 278 | Mock Get-WSManCredSSP -MockWith {@([string]::Empty,[string]::Empty)} 279 | mock Enable-WSManCredSSP -MockWith {} -Verifiable 280 | mock Disable-WSManCredSSP -MockWith {} 281 | mock Get-ItemProperty -MockWith { 282 | return @{ auth_credssp = 1 } 283 | } 284 | mock Get-Item -MockWith { 285 | return @( 286 | @{ 287 | Name = 1 288 | Property = "wsman/foo" 289 | }, 290 | @{ 291 | Name = 1 292 | Property = "wsman/testserver.domain.com" 293 | } 294 | ) 295 | } 296 | 297 | it 'should throw' { 298 | { Set-TargetResource -Ensure 'Present' -Role Client } | should throw 'DelegateComputers is required!' 299 | } 300 | it 'should have not called get' { 301 | Assert-MockCalled -CommandName Get-WSManCredSSP -Times 0 -Scope 'Context' 302 | } 303 | it 'should have called enable' { 304 | Assert-MockCalled -CommandName Enable-WSManCredSSP -Times 0 -Scope 'Context' 305 | } 306 | it 'should have not called disable' { 307 | Assert-MockCalled -CommandName Disable-WSManCredSSP -Times 0 -Scope 'Context' 308 | } 309 | it 'Should have triggered a reboot'{ 310 | $global:DSCMachineStatus | should be $null 311 | } 312 | } 313 | } 314 | 315 | # TODO: Pester Tests for any Helper Cmdlets 316 | } 317 | } 318 | finally 319 | { 320 | Invoke-TestCleanup 321 | } 322 | -------------------------------------------------------------------------------- /Resolve-Dependency.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .DESCRIPTION 3 | Bootstrap script for PSDepend. 4 | 5 | .PARAMETER DependencyFile 6 | Specifies the configuration file for the this script. The default value is 7 | 'RequiredModules.psd1' relative to this script's path. 8 | 9 | .PARAMETER PSDependTarget 10 | Path for PSDepend to be bootstrapped and save other dependencies. 11 | Can also be CurrentUser or AllUsers if you wish to install the modules in 12 | such scope. The default value is 'output/RequiredModules' relative to 13 | this script's path. 14 | 15 | .PARAMETER Proxy 16 | Specifies the URI to use for Proxy when attempting to bootstrap 17 | PackageProvider and PowerShellGet. 18 | 19 | .PARAMETER ProxyCredential 20 | Specifies the credential to contact the Proxy when provided. 21 | 22 | .PARAMETER Scope 23 | Specifies the scope to bootstrap the PackageProvider and PSGet if not available. 24 | THe default value is 'CurrentUser'. 25 | 26 | .PARAMETER Gallery 27 | Specifies the gallery to use when bootstrapping PackageProvider, PSGet and 28 | when calling PSDepend (can be overridden in Dependency files). The default 29 | value is 'PSGallery'. 30 | 31 | .PARAMETER GalleryCredential 32 | Specifies the credentials to use with the Gallery specified above. 33 | 34 | .PARAMETER AllowOldPowerShellGetModule 35 | Allow you to use a locally installed version of PowerShellGet older than 36 | 1.6.0 (not recommended). Default it will install the latest PowerShellGet 37 | if an older version than 2.0 is detected. 38 | 39 | .PARAMETER MinimumPSDependVersion 40 | Allow you to specify a minimum version fo PSDepend, if you're after specific 41 | features. 42 | 43 | .PARAMETER AllowPrerelease 44 | Not yet written. 45 | 46 | .PARAMETER WithYAML 47 | Not yet written. 48 | 49 | .NOTES 50 | Load defaults for parameters values from Resolve-Dependency.psd1 if not 51 | provided as parameter. 52 | #> 53 | [CmdletBinding()] 54 | param 55 | ( 56 | [Parameter()] 57 | [System.String] 58 | $DependencyFile = 'RequiredModules.psd1', 59 | 60 | [Parameter()] 61 | [System.String] 62 | $PSDependTarget = (Join-Path -Path $PSScriptRoot -ChildPath 'output/RequiredModules'), 63 | 64 | [Parameter()] 65 | [System.Uri] 66 | $Proxy, 67 | 68 | [Parameter()] 69 | [System.Management.Automation.PSCredential] 70 | $ProxyCredential, 71 | 72 | [Parameter()] 73 | [ValidateSet('CurrentUser', 'AllUsers')] 74 | [System.String] 75 | $Scope = 'CurrentUser', 76 | 77 | [Parameter()] 78 | [System.String] 79 | $Gallery = 'PSGallery', 80 | 81 | [Parameter()] 82 | [System.Management.Automation.PSCredential] 83 | $GalleryCredential, 84 | 85 | [Parameter()] 86 | [System.Management.Automation.SwitchParameter] 87 | $AllowOldPowerShellGetModule, 88 | 89 | [Parameter()] 90 | [System.String] 91 | $MinimumPSDependVersion, 92 | 93 | [Parameter()] 94 | [System.Management.Automation.SwitchParameter] 95 | $AllowPrerelease, 96 | 97 | [Parameter()] 98 | [System.Management.Automation.SwitchParameter] 99 | $WithYAML, 100 | 101 | [Parameter()] 102 | [System.Collections.Hashtable] 103 | $RegisterGallery 104 | ) 105 | 106 | try 107 | { 108 | if ($PSVersionTable.PSVersion.Major -le 5) 109 | { 110 | if (-not (Get-Command -Name 'Import-PowerShellDataFile' -ErrorAction 'SilentlyContinue')) 111 | { 112 | Import-Module -Name Microsoft.PowerShell.Utility -RequiredVersion '3.1.0.0' 113 | } 114 | 115 | <# 116 | Making sure the imported PackageManagement module is not from PS7 module 117 | path. The VSCode PS extension is changing the $env:PSModulePath and 118 | prioritize the PS7 path. This is an issue with PowerShellGet because 119 | it loads an old version if available (or fail to load latest). 120 | #> 121 | Get-Module -ListAvailable PackageManagement | 122 | Where-Object -Property 'ModuleBase' -NotMatch 'powershell.7' | 123 | Select-Object -First 1 | 124 | Import-Module -Force 125 | } 126 | 127 | Write-Verbose -Message 'Importing Bootstrap default parameters from ''$PSScriptRoot/Resolve-Dependency.psd1''.' 128 | 129 | $resolveDependencyConfigPath = Join-Path -Path $PSScriptRoot -ChildPath '.\Resolve-Dependency.psd1' -Resolve -ErrorAction 'Stop' 130 | 131 | $resolveDependencyDefaults = Import-PowerShellDataFile -Path $resolveDependencyConfigPath 132 | 133 | $parameterToDefault = $MyInvocation.MyCommand.ParameterSets.Where{ $_.Name -eq $PSCmdlet.ParameterSetName }.Parameters.Keys 134 | 135 | if ($parameterToDefault.Count -eq 0) 136 | { 137 | $parameterToDefault = $MyInvocation.MyCommand.Parameters.Keys 138 | } 139 | 140 | # Set the parameters available in the Parameter Set, or it's not possible to choose yet, so all parameters are an option. 141 | foreach ($parameterName in $parameterToDefault) 142 | { 143 | if (-not $PSBoundParameters.Keys.Contains($parameterName) -and $resolveDependencyDefaults.ContainsKey($parameterName)) 144 | { 145 | Write-Verbose -Message "Setting parameter '$parameterName' to value '$($resolveDependencyDefaults[$parameterName])'." 146 | 147 | try 148 | { 149 | $variableValue = $resolveDependencyDefaults[$parameterName] 150 | 151 | if ($variableValue -is [System.String]) 152 | { 153 | $variableValue = $ExecutionContext.InvokeCommand.ExpandString($variableValue) 154 | } 155 | 156 | $PSBoundParameters.Add($parameterName, $variableValue) 157 | 158 | Set-Variable -Name $parameterName -value $variableValue -Force -ErrorAction 'SilentlyContinue' 159 | } 160 | catch 161 | { 162 | Write-Verbose -Message "Error adding default for $parameterName : $($_.Exception.Message)." 163 | } 164 | } 165 | } 166 | } 167 | catch 168 | { 169 | Write-Warning -Message "Error attempting to import Bootstrap's default parameters from '$resolveDependencyConfigPath': $($_.Exception.Message)." 170 | } 171 | 172 | Write-Progress -Activity 'Bootstrap:' -PercentComplete 0 -CurrentOperation 'NuGet Bootstrap' 173 | 174 | # TODO: This should handle the parameter $AllowOldPowerShellGetModule. 175 | $powerShellGetModule = Import-Module -Name 'PowerShellGet' -MinimumVersion '2.0' -ErrorAction 'SilentlyContinue' -PassThru 176 | 177 | # Install the package provider if it is not available. 178 | $nuGetProvider = Get-PackageProvider -Name 'NuGet' -ListAvailable | Select-Object -First 1 179 | 180 | if (-not $powerShellGetModule -and -not $nuGetProvider) 181 | { 182 | $providerBootstrapParameters = @{ 183 | Name = 'nuget' 184 | Force = $true 185 | ForceBootstrap = $true 186 | ErrorAction = 'Stop' 187 | } 188 | 189 | switch ($PSBoundParameters.Keys) 190 | { 191 | 'Proxy' 192 | { 193 | $providerBootstrapParameters.Add('Proxy', $Proxy) 194 | } 195 | 196 | 'ProxyCredential' 197 | { 198 | $providerBootstrapParameters.Add('ProxyCredential', $ProxyCredential) 199 | } 200 | 201 | 'Scope' 202 | { 203 | $providerBootstrapParameters.Add('Scope', $Scope) 204 | } 205 | } 206 | 207 | if ($AllowPrerelease) 208 | { 209 | $providerBootstrapParameters.Add('AllowPrerelease', $true) 210 | } 211 | 212 | Write-Information -MessageData 'Bootstrap: Installing NuGet Package Provider from the web (Make sure Microsoft addresses/ranges are allowed).' 213 | 214 | # TODO: This does not handle a private Gallery yet. 215 | $null = Install-PackageProvider @providerBootstrapParams 216 | 217 | $nuGetProvider = Get-PackageProvider -Name 'NuGet' -ListAvailable | Select-Object -First 1 218 | 219 | $nuGetProviderVersion = $nuGetProvider.Version.ToString() 220 | 221 | Write-Information -MessageData "Bootstrap: Importing NuGet Package Provider version $nuGetProviderVersion to current session." 222 | 223 | $Null = Import-PackageProvider -Name 'NuGet' -RequiredVersion $nuGetProviderVersion -Force 224 | } 225 | 226 | if ($RegisterGallery) 227 | { 228 | if ($RegisterGallery.ContainsKey('Name') -and -not [System.String]::IsNullOrEmpty($RegisterGallery.Name)) 229 | { 230 | $Gallery = $RegisterGallery.Name 231 | } 232 | else 233 | { 234 | $RegisterGallery.Name = $Gallery 235 | } 236 | 237 | Write-Progress -Activity 'Bootstrap:' -PercentComplete 7 -CurrentOperation "Verifying private package repository '$Gallery'" -Completed 238 | 239 | $previousRegisteredRepository = Get-PSRepository -Name $Gallery -ErrorAction 'SilentlyContinue' 240 | 241 | if ($previousRegisteredRepository.SourceLocation -ne $RegisterGallery.SourceLocation) 242 | { 243 | if ($previousRegisteredRepository) 244 | { 245 | Write-Progress -Activity 'Bootstrap:' -PercentComplete 9 -CurrentOperation "Re-registrering private package repository '$Gallery'" -Completed 246 | 247 | Unregister-PSRepository -Name $Gallery 248 | 249 | $unregisteredPreviousRepository = $true 250 | } 251 | else 252 | { 253 | Write-Progress -Activity 'Bootstrap:' -PercentComplete 9 -CurrentOperation "Registering private package repository '$Gallery'" -Completed 254 | } 255 | 256 | Register-PSRepository @RegisterGallery 257 | } 258 | } 259 | 260 | Write-Progress -Activity 'Bootstrap:' -PercentComplete 10 -CurrentOperation "Ensuring Gallery $Gallery is trusted" 261 | 262 | # Fail if the given PSGallery is not registered. 263 | $previousGalleryInstallationPolicy = (Get-PSRepository -Name $Gallery -ErrorAction 'Stop').InstallationPolicy 264 | 265 | if ($previousGalleryInstallationPolicy -ne 'Trusted') 266 | { 267 | # Only change policy if the repository is not trusted 268 | Set-PSRepository -Name $Gallery -InstallationPolicy 'Trusted' -ErrorAction 'Ignore' 269 | } 270 | 271 | try 272 | { 273 | Write-Progress -Activity 'Bootstrap:' -PercentComplete 25 -CurrentOperation 'Checking PowerShellGet' 274 | 275 | # Ensure the module is loaded and retrieve the version you have. 276 | $powerShellGetVersion = (Import-Module -Name 'PowerShellGet' -PassThru -ErrorAction 'SilentlyContinue').Version 277 | 278 | Write-Verbose -Message "Bootstrap: The PowerShellGet version is $powerShellGetVersion" 279 | 280 | # Versions below 2.0 are considered old, unreliable & not recommended 281 | if (-not $powerShellGetVersion -or ($powerShellGetVersion -lt [System.Version] '2.0' -and -not $AllowOldPowerShellGetModule)) 282 | { 283 | Write-Progress -Activity 'Bootstrap:' -PercentComplete 40 -CurrentOperation 'Installing newer version of PowerShellGet' 284 | 285 | $installPowerShellGetParameters = @{ 286 | Name = 'PowerShellGet' 287 | Force = $True 288 | SkipPublisherCheck = $true 289 | AllowClobber = $true 290 | Scope = $Scope 291 | Repository = $Gallery 292 | } 293 | 294 | switch ($PSBoundParameters.Keys) 295 | { 296 | 'Proxy' 297 | { 298 | $installPowerShellGetParameters.Add('Proxy', $Proxy) 299 | } 300 | 301 | 'ProxyCredential' 302 | { 303 | $installPowerShellGetParameters.Add('ProxyCredential', $ProxyCredential) 304 | } 305 | 306 | 'GalleryCredential' 307 | { 308 | $installPowerShellGetParameters.Add('Credential', $GalleryCredential) 309 | } 310 | } 311 | 312 | Write-Progress -Activity 'Bootstrap:' -PercentComplete 60 -CurrentOperation 'Installing newer version of PowerShellGet' 313 | 314 | Install-Module @installPowerShellGetParameters 315 | 316 | Remove-Module -Name 'PowerShellGet' -Force -ErrorAction 'SilentlyContinue' 317 | Remove-Module -Name 'PackageManagement' -Force 318 | 319 | $powerShellGetModule = Import-Module PowerShellGet -Force -PassThru 320 | 321 | $powerShellGetVersion = $powerShellGetModule.Version.ToString() 322 | 323 | Write-Information -MessageData "Bootstrap: PowerShellGet version loaded is $powerShellGetVersion" 324 | } 325 | 326 | # Try to import the PSDepend module from the available modules. 327 | $getModuleParameters = @{ 328 | Name = 'PSDepend' 329 | ListAvailable = $true 330 | } 331 | 332 | $psDependModule = Get-Module @getModuleParameters 333 | 334 | if ($PSBoundParameters.ContainsKey('MinimumPSDependVersion')) 335 | { 336 | try 337 | { 338 | $psDependModule = $psDependModule | Where-Object -FilterScript { $_.Version -ge $MinimumPSDependVersion } 339 | } 340 | catch 341 | { 342 | throw ('There was a problem finding the minimum version of PSDepend. Error: {0}' -f $_) 343 | } 344 | } 345 | 346 | if (-not $psDependModule) 347 | { 348 | # PSDepend module not found, installing or saving it. 349 | if ($PSDependTarget -in 'CurrentUser', 'AllUsers') 350 | { 351 | Write-Debug -Message "PSDepend module not found. Attempting to install from Gallery '$Gallery'." 352 | 353 | Write-Warning -Message "Installing PSDepend in $PSDependTarget Scope." 354 | 355 | $installPSDependParameters = @{ 356 | Name = 'PSDepend' 357 | Repository = $Gallery 358 | Force = $true 359 | Scope = $PSDependTarget 360 | SkipPublisherCheck = $true 361 | AllowClobber = $true 362 | } 363 | 364 | if ($MinimumPSDependVersion) 365 | { 366 | $installPSDependParameters.Add('MinimumVersion', $MinimumPSDependVersion) 367 | } 368 | 369 | Write-Progress -Activity 'Bootstrap:' -PercentComplete 75 -CurrentOperation "Installing PSDepend from $Gallery" 370 | 371 | Install-Module @installPSDependParameters 372 | } 373 | else 374 | { 375 | Write-Debug -Message "PSDepend module not found. Attempting to Save from Gallery $Gallery to $PSDependTarget" 376 | 377 | $saveModuleParameters = @{ 378 | Name = 'PSDepend' 379 | Repository = $Gallery 380 | Path = $PSDependTarget 381 | Force = $true 382 | } 383 | 384 | if ($MinimumPSDependVersion) 385 | { 386 | $saveModuleParameters.add('MinimumVersion', $MinimumPSDependVersion) 387 | } 388 | 389 | Write-Progress -Activity 'Bootstrap:' -PercentComplete 75 -CurrentOperation "Saving & Importing PSDepend from $Gallery to $Scope" 390 | 391 | Save-Module @saveModuleParameters 392 | } 393 | } 394 | 395 | Write-Progress -Activity 'Bootstrap:' -PercentComplete 80 -CurrentOperation 'Loading PSDepend' 396 | 397 | $importModulePSDependParameters = @{ 398 | Name = 'PSDepend' 399 | ErrorAction = 'Stop' 400 | Force = $true 401 | } 402 | 403 | if ($PSBoundParameters.ContainsKey('MinimumPSDependVersion')) 404 | { 405 | $importModulePSDependParameters.Add('MinimumVersion', $MinimumPSDependVersion) 406 | } 407 | 408 | # We should have successfully bootstrapped PSDepend. Fail if not available. 409 | $null = Import-Module @importModulePSDependParameters 410 | 411 | if ($WithYAML) 412 | { 413 | Write-Progress -Activity 'Bootstrap:' -PercentComplete 82 -CurrentOperation 'Verifying PowerShell module PowerShell-Yaml' 414 | 415 | if (-not (Get-Module -ListAvailable -Name 'PowerShell-Yaml')) 416 | { 417 | Write-Progress -Activity 'Bootstrap:' -PercentComplete 85 -CurrentOperation 'Installing PowerShell module PowerShell-Yaml' 418 | 419 | Write-Verbose -Message "PowerShell-Yaml module not found. Attempting to Save from Gallery '$Gallery' to '$PSDependTarget'." 420 | 421 | $SaveModuleParam = @{ 422 | Name = 'PowerShell-Yaml' 423 | Repository = $Gallery 424 | Path = $PSDependTarget 425 | Force = $true 426 | } 427 | 428 | Save-Module @SaveModuleParam 429 | } 430 | else 431 | { 432 | Write-Verbose "PowerShell-Yaml is already available" 433 | } 434 | } 435 | 436 | Write-Progress -Activity 'Bootstrap:' -PercentComplete 90 -CurrentOperation 'Invoke PSDepend' 437 | 438 | Write-Progress -Activity "PSDepend:" -PercentComplete 0 -CurrentOperation "Restoring Build Dependencies" 439 | 440 | if (Test-Path -Path $DependencyFile) 441 | { 442 | $psDependParameters = @{ 443 | Force = $true 444 | Path = $DependencyFile 445 | } 446 | 447 | # TODO: Handle when the Dependency file is in YAML, and -WithYAML is specified. 448 | Invoke-PSDepend @psDependParameters 449 | } 450 | 451 | Write-Progress -Activity "PSDepend:" -PercentComplete 100 -CurrentOperation "Dependencies restored" -Completed 452 | 453 | Write-Progress -Activity 'Bootstrap:' -PercentComplete 100 -CurrentOperation "Bootstrap complete" -Completed 454 | } 455 | finally 456 | { 457 | if ($RegisterGallery) 458 | { 459 | Write-Verbose -Message "Removing private package repository '$Gallery'." 460 | Unregister-PSRepository -Name $Gallery 461 | } 462 | 463 | if ($unregisteredPreviousRepository) 464 | { 465 | Write-Verbose -Message "Reverting private package repository '$Gallery' to previous location URI:s." 466 | 467 | $registerPSRepositoryParameters = @{ 468 | Name = $previousRegisteredRepository.Name 469 | InstallationPolicy = $previousRegisteredRepository.InstallationPolicy 470 | } 471 | 472 | if ($previousRegisteredRepository.SourceLocation) 473 | { 474 | $registerPSRepositoryParameters.SourceLocation = $previousRegisteredRepository.SourceLocation 475 | } 476 | 477 | if ($previousRegisteredRepository.PublishLocation) 478 | { 479 | $registerPSRepositoryParameters.PublishLocation = $previousRegisteredRepository.PublishLocation 480 | } 481 | 482 | if ($previousRegisteredRepository.ScriptSourceLocation) 483 | { 484 | $registerPSRepositoryParameters.ScriptSourceLocation = $previousRegisteredRepository.ScriptSourceLocation 485 | } 486 | 487 | if ($previousRegisteredRepository.ScriptPublishLocation) 488 | { 489 | $registerPSRepositoryParameters.ScriptPublishLocation = $previousRegisteredRepository.ScriptPublishLocation 490 | } 491 | 492 | Register-PSRepository @registerPSRepositoryParameters 493 | } 494 | 495 | # Only try to revert installation policy if the repository exist 496 | if ((Get-PSRepository -Name $Gallery -ErrorAction 'SilentlyContinue')) 497 | { 498 | if ($previousGalleryInstallationPolicy -and $previousGalleryInstallationPolicy -ne 'Trusted') 499 | { 500 | # Reverting the Installation Policy for the given gallery if it was not already trusted 501 | Set-PSRepository -Name $Gallery -InstallationPolicy $previousGalleryInstallationPolicy 502 | } 503 | } 504 | 505 | Write-Verbose -Message "Project Bootstrapped, returning to Invoke-Build" 506 | } 507 | --------------------------------------------------------------------------------