Compare commits

..

28 Commits

Author SHA1 Message Date
unknown f48ffbcc11 Updated dobuild.ps1 2021-05-24 15:42:34 -07:00
unknown be08036a24 Bring in latest subsystem updates 2021-05-24 15:18:08 -07:00
unknown 53b693ab8e Fixed inherited properties 2021-05-24 14:41:18 -07:00
unknown 76f41549ad Fix NullReferenceException in DSC ClearCache() 2021-05-24 14:37:19 -07:00
Andrew a5787f0cb3 SubSystem work 1 2021-03-24 17:06:17 -07:00
Andrew 231356d2ba Changed namespace Internal.Json -> Internal.CrossPlatform 2021-01-28 13:54:32 -08:00
anmenaga 4a1c8e75e0 Class-based resource only support 2020-12-07 20:20:32 -08:00
anmenaga 67ee71793e Updated error reporting for class resources 2020-11-22 13:57:27 -08:00
anmenaga 86b0561f52 Fixed Get-DscResource shows the embedded class for class based resources 2020-11-20 22:35:22 -08:00
anmenaga a74f5ee8de Fixing Verbose message reporting from Class-based resources 2020-11-20 20:05:06 -08:00
anmenaga aa4652ce28 Added fix for PSModulePath resetting in Invoke-DscClassBasedResource 2020-10-01 15:55:28 -07:00
anmenaga 9ddb7e2305 Fix bug when same class-based module is in several module paths 2020-10-01 14:25:26 -07:00
anmenaga aa49a839e3 Disable cleaning caches in the end of Get-DscResource 2020-09-17 13:22:05 -07:00
anmenaga 82aa860cb1 remove hang related to composite resources 2020-09-16 12:51:52 -07:00
anmenaga 8b8e454b4e Merge branch 'master' into JsonWork 2020-09-14 17:39:17 -07:00
anmenaga 56e5460ef9 Make DSC_HOME env var cross platform 2020-09-01 23:08:18 -07:00
anmenaga eed19c33ed Updated namespace of SMA APIs 2020-09-01 10:54:50 -07:00
anmenaga c7f5c83843 Fixed typo in GetResourceFromKeyword 2020-08-24 03:15:30 -07:00
anmenaga 00be7c8e9d simplified schema 2020-08-23 23:41:40 -07:00
anmenaga 0f59c3cdba Fixed convertion cmdlet after namespace change 2020-08-21 15:12:51 -07:00
anmenaga d3b5218d0d Removed Internal from SMA APIs namespace 2020-08-20 17:32:06 -07:00
anmenaga 7f2d6ebf2e Started using Microsoft.PowerShell.DesiredStateConfiguration.Internal.Json namespace 2020-08-13 18:32:55 -07:00
anmenaga 5db42b0120 Bumped module version to 3.0.0 as was discussed offline 2020-08-13 18:20:54 -07:00
anmenaga bd0affdb4d Adding ConvertTo-DscJsonSchema cmdlet to DSC module 2020-08-11 21:19:02 -07:00
anmenaga 0b4412362b Set module Minimum PowerShellVersion to be 7.1 2020-08-11 16:44:31 -07:00
anmenaga 553a19715a Feedback 1 2020-08-11 16:40:20 -07:00
Andrew 94ca4dda32 Bumped module version to 2.0.6 2020-08-06 13:34:02 -07:00
Andrew 7cba5c16d5 adding BaseRegistration json files and ExportedCommands functionality 2020-08-05 16:41:28 -07:00
29 changed files with 955 additions and 1253 deletions
-77
View File
@@ -1,77 +0,0 @@
name: Bug report 🐛
description: Report errors or unexpected behavior 🤔
labels:
- bug
- Needs-Triage
body:
- type: markdown
attributes:
value: >-
This repository is **ONLY** for issues related to DSC in the published
PSDesiredStateConfiguration module.
- type: checkboxes
attributes:
label: Prerequisites
options:
- label: Write a descriptive title.
required: true
- label: Make sure you are able to repro it on the [latest released version](https://www.powershellgallery.com/packages/PSDesiredStateConfiguration)
required: true
- label: Search the existing issues.
required: true
- type: textarea
attributes:
label: Steps to reproduce
description: >
List of steps, sample code, failing test or link to a project that reproduces the behavior.
Make sure you place a stack trace inside a code (```) block to avoid linking unrelated issues.
placeholder: >
I am experiencing a problem with X.
I think Y should be happening but Z is actually happening.
validations:
required: true
- type: textarea
attributes:
label: Expected behavior
render: console
placeholder: |
PS> 2 + 2
4
validations:
required: true
- type: textarea
attributes:
label: Actual behavior
render: console
placeholder: |
PS> 2 + 2
5
validations:
required: true
- type: textarea
attributes:
label: Error details
description: Paste verbatim output from `Get-Error` if PowerShell returns an error.
render: console
placeholder: PS> Get-Error
- type: textarea
attributes:
label: Environment data
description: Paste verbatim output from `$PSVersionTable` below.
render: PowerShell
placeholder: PS> $PSVersionTable
validations:
required: true
- type: input
validations:
required: true
attributes:
label: Version
description: Specify the version of Crescendo you are using.
- type: textarea
attributes:
label: Visuals
description: >
Please upload images or animations that can be used to reproduce issues in the area below.
Try the [Steps Recorder](https://support.microsoft.com/en-us/windows/record-steps-to-reproduce-a-problem-46582a9b-620f-2e36-00c9-04e25d784e47)
on Windows or [Screenshot](https://support.apple.com/en-us/HT208721) on macOS.
@@ -1,23 +0,0 @@
name: Feature Request / Idea 🚀
description: Suggest a new feature or improvement (this does not mean you have to implement it)
labels:
- enhancement
- Needs-Triage
body:
- type: textarea
attributes:
label: Summary of the new feature / enhancement
description: >
A clear and concise description of what the problem is that the new feature would solve. Try
formulating it in user story style (if applicable).
placeholder: >
'As a user I want X so that Y...' with X being the being the action and Y being the value of
the action.
validations:
required: true
- type: textarea
attributes:
label: Proposed technical implementation details (optional)
placeholder: >
A clear and concise description of what you want to happen. Consider providing an example
experience with expected result.
-17
View File
@@ -1,17 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: PowerShell Issues
url: https://github.com/PowerShell/PowerShell/issues/new
about: PowerShell issues or suggestions.
- name: Windows PowerShell Issues
url: https://support.microsoft.com/windows/send-feedback-to-microsoft-with-the-feedback-hub-app-f59187f8-8739-22d6-ba93-f66612949332
about: Windows PowerShell issues or suggestions.
- name: Support
url: https://github.com/PowerShell/PowerShell/blob/master/.github/SUPPORT.md
about: PowerShell Support Questions/Help
- name: Documentation Issue
url: https://github.com/MicrosoftDocs/PowerShell-Docs-DSC/issues/new/choose
about: Please open issues on documentation for DSC here.
- name: Azure Policy Feedback
about: File feedback for Azure Policy's machine configuration feature
url: https://feedback.azure.com/d365community/forum/675ae472-f324-ec11-b6e6-000d3a4f0da0
+42 -115
View File
@@ -9,143 +9,70 @@ pr:
branches: branches:
include: include:
- master - master
- feature-*
resources: paths:
repositories: exclude:
- repository: ComplianceRepo - /.dependabot/*
type: github - /.poshchan/*
endpoint: ComplianceGHRepo - /.github/**/*
name: PowerShell/compliance - /.vscode/**/*
- /.vsts-ci/misc-analysis.yml
- /tools/**/*
- .editorconfig
- .gitattributes
- .gitignore
- /docs/**/*
- /CHANGELOG.md
- /CONTRIBUTING.md
- /README.md
- /LICENSE.txt
- /CODE_OF_CONDUCT.md
stages: stages:
- stage: Build - stage: Build
displayName: Build PSDesiredStateConfiguration module displayName: Build PowerShell Package
pool:
vmImage: windows-latest
jobs: jobs:
- job: BuildPkg - job: BuildPkg
displayName: Build Package displayName: Build Package
steps:
- powershell: |
$powerShellPath = Join-Path -Path $env:AGENT_TEMPDIRECTORY -ChildPath 'powershell'
Invoke-WebRequest -Uri https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.ps1 -outfile ./install-powershell.ps1
./install-powershell.ps1 -Destination $powerShellPath
$vstsCommandString = "vso[task.setvariable variable=PATH]$powerShellPath;$env:PATH"
Write-Host "sending " + $vstsCommandString
Write-Host "##$vstsCommandString"
displayName: Install PowerShell Core
- task: NuGetToolInstaller@1
displayName: 'Install NuGet 5.9.1'
inputs:
checkLatest: false
version: 5.9.1
- task: UseDotNet@2
displayName: 'Install .NET Core SDK'
inputs:
packageType: sdk
useGlobalJson: true
includePreviewVersions: true
workingDirectory: '$(Build.SourcesDirectory)'
- pwsh: |
Get-ChildItem -Path env:
displayName: Capture environment for build
condition: succeededOrFailed()
- pwsh: |
$modulePath = Join-Path -Path $env:AGENT_TEMPDIRECTORY -ChildPath 'TempModules'
if (Test-Path -Path $modulePath) {
Write-Verbose -Verbose "Deleting existing temp module path: $modulePath"
Remove-Item -Path $modulePath -Recurse -Force -ErrorAction Ignore
}
if (! (Test-Path -Path $modulePath)) {
Write-Verbose -Verbose "Creating new temp module path: $modulePath"
$null = New-Item -Path $modulePath -ItemType Directory
}
displayName: Create temporary module path
- pwsh: |
$modulePath = Join-Path -Path $env:AGENT_TEMPDIRECTORY -ChildPath 'TempModules'
Write-Verbose -Verbose "Install PowerShellGet V3 to temp module path"
Save-Module -Name PowerShellGet -Path $modulePath -MinimumVersion 3.0.0-beta10 -AllowPrerelease -Force
Write-Verbose -Verbose "Install PlatyPS to temp module path"
Save-Module -Name "platyPS" -Path $modulePath -Force
Write-Verbose -Verbose "Install PSScriptAnalyzer to temp module path"
Save-Module -Name "PSScriptAnalyzer" -Path $modulePath -RequiredVersion 1.18.0 -Force
Write-Verbose -Verbose "Install Pester 4.X to temp module path"
Save-Module -Name "Pester" -MaximumVersion 4.99 -Path $modulePath -Force
Write-Verbose -Verbose "Install PSPackageProject to temp module path"
Save-Module -Name PSPackageProject -Path $modulePath -Force
displayName: Install PSPackageProject and dependencies
- pwsh: |
$modulePath = Join-Path -Path $env:AGENT_TEMPDIRECTORY -ChildPath 'TempModules'
$env:PSModulePath = $modulePath + [System.IO.Path]::PathSeparator + $env:PSModulePath
$modPath = Join-Path -Path $modulePath -ChildPath PSPackageProject
Write-Verbose -Verbose "Importing PSPackageProject from: $modPath"
Import-Module -Name $modPath -Force
#
$(Build.SourcesDirectory)/build.ps1 -Build -Clean
$outBinPath = "$(Build.SourcesDirectory)\out\PSDesiredStateConfiguration"
$vstsCommandString = "vso[task.setvariable variable=outBinPath]${outBinPath}"
Write-Host "sending " + $vstsCommandString
Write-Host "##$vstsCommandString"
displayName: Execute build
- publish: "$(outBinPath)"
artifact: Build
displayName: Publish build
- stage: Compliance
displayName: Compliance
dependsOn: Build
jobs:
- job: Compliance_Job
pool: pool:
vmImage: windows-latest vmImage: windows-2019
steps: steps:
- checkout: self - template: templates/ci-build.yml
- checkout: ComplianceRepo
- download: current
artifact: Build
- pwsh: | - pwsh: |
Get-ChildItem -Path "$(Pipeline.Workspace)\Build" -Recurse Write-Verbose "BUILD_OUTPUT_PATH- $env:BUILD_OUTPUT_PATH" -Verbose
displayName: Capture downloaded artifacts Write-Verbose "SIGNED_OUTPUT_PATH- $env:SIGNED_OUTPUT_PATH" -Verbose
- template: ci-compliance.yml@ComplianceRepo Copy-Item $env:BUILD_OUTPUT_PATH $env:SIGNED_OUTPUT_PATH -Recurse -Force
parameters: displayName: Build Signing Placeholder
# component-governance - pwsh: |
sourceScanPath: '$(Pipeline.Workspace)\Build' $(Build.SourcesDirectory)/build.ps1 -Publish -Signed
# credscan displayName: Publish
suppressionsFile: '' timeoutInMinutes: 10
# TermCheck
optionsRulesDBPath: ''
optionsFTPath: ''
# tsa-upload
codeBaseName: 'PSDesiredStateConfiguration_20210423'
# selections
APIScan: false # set to false when not using Windows APIs.
- stage: Test - stage: Test
displayName: Test Package displayName: Test Package
dependsOn: Build
jobs: jobs:
- template: templates/ci-test.yml - template: templates/ci-test.yml
parameters: parameters:
jobName: TestPkgWin jobName: TestPkgWin
displayName: PowerShell Core on Windows displayName: PowerShell Core on Windows
imageName: windows-latest imageName: windows-2019
# Not supported on Windows PowerShell per PSD1
# - template: test.yml
# parameters:
# jobName: TestPkgWinPS
# displayName: Windows PowerShell on Windows
# imageName: windows-2019
# powershellExecutable: powershell
- template: templates/ci-test.yml - template: templates/ci-test.yml
parameters: parameters:
jobName: TestPkgUbuntu jobName: TestPkgUbuntu16
displayName: PowerShell Core on Ubuntu displayName: PowerShell Core on Ubuntu 16.04
imageName: ubuntu-latest imageName: ubuntu-16.04
- template: templates/ci-test.yml - template: templates/ci-test.yml
parameters: parameters:
jobName: TestPkgWinMacOS jobName: TestPkgWinMacOS
displayName: PowerShell Core on macOS displayName: PowerShell Core on macOS
imageName: macOS-latest imageName: macOS-10.14
+125 -188
View File
@@ -1,213 +1,150 @@
name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr) name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)
trigger: none trigger:
batch: true
resources: branches:
repositories: include:
- repository: ComplianceRepo - master
type: github paths:
endpoint: ComplianceGHRepo exclude:
name: PowerShell/compliance - /.dependabot/*
- /.poshchan/*
variables: - /.github/**/*
- name: PackageName - /.vscode/**/*
value: 'PSDesiredStateConfiguration' - /.vsts-ci/misc-analysis.yml
- name: PackageVersion - /tools/**/*
value: '3.0.0' - .editorconfig
- .gitattributes
- .gitignore
- /docs/**/*
- /CHANGELOG.md
- /CONTRIBUTING.md
- /README.md
- /LICENSE.txt
- /CODE_OF_CONDUCT.md
stages: stages:
- stage: Build - stage: Build
displayName: Build PSDesiredStateConfiguration module displayName: Build PowerShell Package
pool:
name: 1ES
demands:
- ImageOverride -equals PSMMS2019-Secure
jobs: jobs:
- job: BuildPkg - job: BuildPkg
displayName: Build Package displayName: Build Package
variables: pool:
- group: ESRP name: 'Package ES CodeHub Lab E'
steps: steps:
- powershell: | - powershell: |
$powerShellPath = Join-Path -Path $env:AGENT_TEMPDIRECTORY -ChildPath 'powershell' $powerShellPath = Join-Path -Path $env:AGENT_TEMPDIRECTORY -ChildPath 'powershell'
Invoke-WebRequest -Uri https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.ps1 -outfile ./install-powershell.ps1 Invoke-WebRequest -Uri https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.ps1 -outfile ./install-powershell.ps1
./install-powershell.ps1 -Preview -Destination $powerShellPath ./install-powershell.ps1 -Destination $powerShellPath
$vstsCommandString = "vso[task.setvariable variable=PATH]$powerShellPath;$env:PATH" $vstsCommandString = "vso[task.setvariable variable=PATH]$powerShellPath;$env:PATH"
Write-Host "sending " + $vstsCommandString Write-Host "sending " + $vstsCommandString
Write-Host "##$vstsCommandString" Write-Host "##$vstsCommandString"
displayName: Install PowerShell Core displayName: Install PowerShell Core
- task: NuGetToolInstaller@1 - task: PkgESSetupBuild@10
displayName: 'Install NuGet' displayName: 'Package ES - Setup Build'
inputs: inputs:
checkLatest: false productName: PSDesiredStateConfiguration
version: 5.9.1
- task: UseDotNet@2 - template: templates/shouldsign.yml
displayName: 'Install .NET Core SDK'
inputs:
packageType: sdk
useGlobalJson: true
includePreviewVersions: true
workingDirectory: '$(Build.SourcesDirectory)'
- pwsh: | - powershell: |
Get-ChildItem -Path env: Get-ChildItem -Path env:
displayName: Capture environment for build displayName: Capture environment
condition: succeededOrFailed() condition: succeededOrFailed()
- pwsh: | - template: templates/ci-build.yml
$modulePath = Join-Path -Path $env:AGENT_TEMPDIRECTORY -ChildPath 'TempModules'
if (Test-Path -Path $modulePath) { - powershell: |
Write-Verbose -Verbose "Deleting existing temp module path: $modulePath" Write-Verbose "BUILD_OUTPUT_PATH- $env:BUILD_OUTPUT_PATH" -Verbose
Remove-Item -Path $modulePath -Recurse -Force -ErrorAction Ignore Write-Verbose "SIGNED_OUTPUT_PATH- $env:SIGNED_OUTPUT_PATH" -Verbose
} Copy-Item $env:BUILD_OUTPUT_PATH $env:SIGNED_OUTPUT_PATH -Recurse -Force
if (! (Test-Path -Path $modulePath)) { displayName: Copy unsigned files first
Write-Verbose -Verbose "Creating new temp module path: $modulePath"
$null = New-Item -Path $modulePath -ItemType Directory - task: PkgESCodeSign@10
} displayName: 'CodeSign tools/releaseBuild/signing.xml'
displayName: Create temporary module path env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
inputs:
signConfigXml: tools/releaseBuild/signing.xml
inPathRoot: '$(BUILD_OUTPUT_PATH)'
outPathRoot: '$(SIGNED_OUTPUT_PATH)'
condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true'))
- task: PowerShell@1
displayName: 'Create catalog file'
inputs:
scriptType: inlineScript
inlineScript: |
$signedDir = "$env:SIGNED_OUTPUT_PATH\PSDesiredStateConfiguration"
New-FileCatalog -CatalogFilePath "$env:SIGNED_OUTPUT_PATH\PSDesiredStateConfiguration\PSDesiredStateConfiguration.cat" -Path "$signedDir"
- task: PkgESCodeSign@10
displayName: 'CodeSign tools/releaseBuild/FileCatalogSigning.xml'
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
inputs:
signConfigXml: tools/releaseBuild/FileCatalogSigning.xml
inPathRoot: '$(SIGNED_OUTPUT_PATH)'
outPathRoot: '$(SIGNED_OUTPUT_PATH)'
condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true'))
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
displayName: 'Component Detection'
- task: AntiMalware@3
inputs:
InputType: 'Basic'
ScanType: 'CustomScan'
FileDirPath: '$(SIGNED_OUTPUT_PATH)'
EnableServices: false
SupportLogOnError: false
TreatSignatureUpdateFailureAs: 'Warning'
SignatureFreshness: 'UpToDate'
TreatStaleSignatureAs: 'Error'
- task: PoliCheck@1
condition: succeededOrFailed()
inputs:
targetType: F
optionsFC: 0
optionsXS: 0
optionsPE: '1|2|3|4'
optionsHMENABLE: 0
optionsFTPATH: '$(Build.SourcesDirectory)\tools\terms\FileTypeSet.xml'
- task: CredScan@2
condition: succeededOrFailed()
# Publish results as artifacts
- task: PublishSecurityAnalysisLogs@3
condition: succeededOrFailed()
inputs:
ArtifactName: 'CodeAnalysisLogs'
ArtifactType: 'Container'
# Publish to TSA server
# - task: TSAUpload@1
# condition: succeededOrFailed()
# continueOnError: true
# inputs:
# tsaVersion: 'TsaV2'
# codebase: 'Existing'
# tsaEnvironment: 'PROD'
# codeBaseName: 'PSDesiredStateConfiguration_20190828'
# uploadAPIScan: false
# uploadBinSkim: false
# uploadCredScan: true
# uploadFortifySCA: false
# uploadFxCop: false
# uploadModernCop: false
# uploadPoliCheck: true
# uploadPREfast: false
# uploadRoslyn: false
# uploadTSLint: false
# uploadAsync: true
- pwsh: | - pwsh: |
$modulePath = Join-Path -Path $env:AGENT_TEMPDIRECTORY -ChildPath 'TempModules' $(Build.SourcesDirectory)/build.ps1 -Publish -Signed
Write-Verbose -Verbose "Install PowerShellGet V3 to temp module path" displayName: Publish
Save-Module -Name PowerShellGet -Path $modulePath -MinimumVersion 3.0.0-beta10 -AllowPrerelease -Force timeoutInMinutes: 10
Write-Verbose -Verbose "Install PlatyPS to temp module path"
Save-Module -Name "platyPS" -Path $modulePath -Force
Write-Verbose -Verbose "Install PSScriptAnalyzer to temp module path"
Save-Module -Name "PSScriptAnalyzer" -Path $modulePath -RequiredVersion 1.18.0 -Force
Write-Verbose -Verbose "Install Pester 4.X to temp module path"
Save-Module -Name "Pester" -MaximumVersion 4.99 -Path $modulePath -Force
Write-Verbose -Verbose "Install PSPackageProject to temp module path"
Save-Module -Name PSPackageProject -Path $modulePath -Force
displayName: Install PSPackageProject and dependencies
- pwsh: |
$modulePath = Join-Path -Path $env:AGENT_TEMPDIRECTORY -ChildPath 'TempModules'
$env:PSModulePath = $modulePath + [System.IO.Path]::PathSeparator + $env:PSModulePath
$modPath = Join-Path -Path $modulePath -ChildPath PSPackageProject
Write-Verbose -Verbose "Importing PSPackageProject from: $modPath"
Import-Module -Name $modPath -Force
#
$(Build.SourcesDirectory)/build.ps1 -Build -Clean
displayName: Execute build
- pwsh: |
$signSrcPath = "$(Build.SourcesDirectory)\out\PSDesiredStateConfiguration"
# Set signing src path variable
$vstsCommandString = "vso[task.setvariable variable=signSrcPath]${signSrcPath}"
Write-Host "sending " + $vstsCommandString
Write-Host "##$vstsCommandString"
$signOutPath = "$(Build.SourcesDirectory)\signed\PSDesiredStateConfiguration"
$null = New-Item -ItemType Directory -Path $signOutPath
# Set signing out path variable
$vstsCommandString = "vso[task.setvariable variable=signOutPath]${signOutPath}"
Write-Host "sending " + $vstsCommandString
Write-Host "##$vstsCommandString"
# Set path variable for guardian codesign validation
$vstsCommandString = "vso[task.setvariable variable=GDN_CODESIGN_TARGETDIRECTORY]${signOutPath}"
Write-Host "sending " + $vstsCommandString
Write-Host "##$vstsCommandString"
displayName: Setup variables for signing
- template: EsrpSign.yml@ComplianceRepo
parameters:
# the folder which contains the binaries to sign
buildOutputPath: $(signSrcPath)
# the location to put the signed output
signOutputPath: $(signOutPath)
# the certificate ID to use
certificateId: "CP-230012"
# the file pattern to use, comma separated
pattern: '*.psm1,*.psd1,Microsoft.PowerShell.DscSubsystem.dll'
- template: Sbom.yml@ComplianceRepo
parameters:
BuildDropPath: "$(Build.SourcesDirectory)/signed/PSDesiredStateConfiguration/PSDesiredStateConfiguration"
Build_Repository_Uri: 'https://github.com/PowerShell/PSDesiredStateConfiguration'
PackageName: $(PackageName)
PackageVersion: $(PackageVersion)
- pwsh: |
$repoName = [guid]::newGuid().ToString("N")
$packageRoot = "$(Build.SourcesDirectory)\signed\PSDesiredStateConfiguration"
Register-PSRepository -Name $repoName -SourceLocation $packageRoot -InstallationPolicy Trusted
Publish-Module -Path $packageRoot -Repository $repoName
Unregister-PSRepository -Name $repoName
Get-ChildItem -Recurse -Path $packageRoot | Write-Verbose -Verbose
$nupkgPath = (Get-ChildItem -Recurse -Path $packageRoot -Filter "PSDesiredStateConfiguration*.nupkg" | select -First 1).FullName
Write-Host "##vso[artifact.upload containerfolder=nupkg;artifactname=nupkg]$nupkgPath"
displayName: Package and publish nupkg
name: ProduceNupkg
- publish: "$(signSrcPath)"
artifact: Build
displayName: Publish build
- publish: "$(signOutPath)"
artifact: SignedBuild
displayName: Publish signed build
- stage: Compliance
displayName: Compliance
dependsOn: Build
jobs:
- job: Compliance_Job
pool:
name: 1ES
demands:
- ImageOverride -equals MMS2019
steps:
- checkout: self
- checkout: ComplianceRepo
- download: current
artifact: SignedBuild
- pwsh: |
Get-ChildItem -Path "$(Pipeline.Workspace)\SignedBuild" -Recurse
displayName: Capture downloaded artifacts
- template: script-module-compliance.yml@ComplianceRepo
parameters:
# component-governance
sourceScanPath: '$(Pipeline.Workspace)\SignedBuild'
# credscan
suppressionsFile: ''
# TermCheck
optionsRulesDBPath: ''
optionsFTPath: ''
# tsa-upload
codeBaseName: 'PSDesiredStateConfiguration_20210423'
# selections
APIScan: false # set to false when not using Windows APIs.
- stage: Deploy
displayName: Publish to PowerShell gallery
dependsOn:
- Build
- Compliance
jobs:
- deployment: DeployPowerShellGallery
displayName: Deploy nupkg to PowerShell Gallery
pool:
name: 1ES
demands:
- ImageOverride -equals MMS2019
environment: 'PSDesiredStateConfiguration-ReleaseApproval'
strategy:
runOnce:
deploy:
steps:
- download: current
artifact: 'nupkg'
- task: NuGetToolInstaller@1
displayName: 'Install NuGet'
inputs:
checkLatest: false
version: 5.9.1
- task: NuGetCommand@2
displayName: 'NuGet push'
inputs:
command: push
packagesToPush: '$(Pipeline.Workspace)\nupkg\PSDesiredStateConfiguration.*.nupkg'
nuGetFeedType: external
publishFeedCredentials: 'PowerShellGallery'
+19
View File
@@ -0,0 +1,19 @@
name: PR-$(System.PullRequest.PullRequestNumber)-$(Date:yyyyMMdd)$(Rev:.rr)
trigger:
# Batch merge builds together while a merge build is running
batch: true
branches:
include:
- master
pr:
branches:
include:
- master
resources:
- repo: self
clean: true
jobs:
- template: templates/credscan.yml
+16
View File
@@ -0,0 +1,16 @@
steps:
- pwsh: |
Install-Module -Name "platyPS","Pester" -Force
displayName: Install dependencies
timeoutInMinutes: 10
- pwsh: |
Install-Module -Name "PSScriptAnalyzer" -RequiredVersion 1.18.0 -Force
displayName: Install PSScriptAnalyzer
timeoutInMinutes: 10
- pwsh: |
Install-Module -Name PSPackageProject -Force
displayName: Install PSPackageProject module
timeoutInMinutes: 10
- pwsh: |
$(Build.SourcesDirectory)/build.ps1 -Build
displayName: Build
+104 -56
View File
@@ -10,65 +10,113 @@ jobs:
vmImage: ${{ parameters.imageName }} vmImage: ${{ parameters.imageName }}
displayName: ${{ parameters.displayName }} displayName: ${{ parameters.displayName }}
steps: steps:
- powershell: | - ${{ parameters.powershellExecutable }}: |
$powerShellPath = Join-Path -Path $env:AGENT_TEMPDIRECTORY -ChildPath 'powershell' if($IsMacOs)
{
brew install powershell/tap/powershell-preview
sudo ln -s -f /usr/local/opt/powershell-preview/libexec/pwsh /usr/local/bin/pwsh
}
elseif($IsLinux)
{
sudo apt-get update
sudo apt-get install powershell-preview
sudo ln -s /opt/microsoft/powershell/7-preview/pwsh /usr/local/bin/pwsh
}
elseif($IsWindows)
{
Invoke-WebRequest -Uri https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.ps1 -outfile ./install-powershell.ps1 Invoke-WebRequest -Uri https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.ps1 -outfile ./install-powershell.ps1
./install-powershell.ps1 -Preview -Destination $powerShellPath ./install-powershell.ps1 -AddToPath -Preview -Destination C:\powershell-preview
$newPath = $powerShellPath + [System.IO.Path]::PathSeparator + $env:PATH $vstsCommandString = "vso[task.setvariable variable=PATH]C:\powershell-preview;$env:PATH"
$vstsCommandString = "vso[task.setvariable variable=PATH]$newPath"
Write-Host "sending " + $vstsCommandString Write-Host "sending " + $vstsCommandString
Write-Host "##$vstsCommandString" Write-Host "##$vstsCommandString"
displayName: Install PowerShell Core }
displayName: Setup PowerShell preview
- pwsh: | - ${{ parameters.powershellExecutable }}: |
$modulePath = Join-Path -Path $env:AGENT_TEMPDIRECTORY -ChildPath 'TempModules' $PSVersionTable
if (Test-Path -Path $modulePath) { $vstsCommandString = "vso[task.setvariable variable=PSHOME]$pshome"
Write-Verbose -Verbose "Deleting existing temp module path: $modulePath" Write-Host "sending " + $vstsCommandString
Remove-Item -Path $modulePath -Recurse -Force -ErrorAction Ignore Write-Host "##$vstsCommandString"
} displayName: Capture PowerShellVersion
if (! (Test-Path -Path $modulePath)) {
Write-Verbose -Verbose "Creating new temp module path: $modulePath"
$null = New-Item -Path $modulePath -ItemType Directory
}
displayName: Create temporary module path
- pwsh: | - ${{ parameters.powershellExecutable }}: |
$modulePath = Join-Path -Path $env:AGENT_TEMPDIRECTORY -ChildPath 'TempModules' dir env:PATH
Write-Verbose -Verbose "Install PowerShellGet V3 to temp module path" displayName: Capture Path
Save-Module -Name PowerShellGet -Path $modulePath -MinimumVersion 3.0.0-beta10 -AllowPrerelease -Force
Write-Verbose -Verbose "Install PlatyPS to temp module path"
Save-Module -Name "platyPS" -Path $modulePath -Force
Write-Verbose -Verbose "Install PSScriptAnalyzer to temp module path"
Save-Module -Name "PSScriptAnalyzer" -Path $modulePath -RequiredVersion 1.18.0 -Force
Write-Verbose -Verbose "Install Pester 4.X to temp module path"
Save-Module -Name "Pester" -MaximumVersion 4.99 -Path $modulePath -Force
Write-Verbose -Verbose "Install PSPackageProject to temp module path"
Save-Module -Name PSPackageProject -Path $modulePath -Force
#
$vstsCommandString = "vso[task.setvariable variable=modulePath]${modulePath}"
Write-Host "sending " + $vstsCommandString
Write-Host "##$vstsCommandString"
displayName: Install PSPackageProject and dependencies
- download: current
artifact: Build
- pwsh: | - ${{ parameters.powershellExecutable }}: |
"PSVersionTable is"| Write-Verbose -Verbose Get-PSRepository
$PSVersionTable | Out-String | Write-Verbose -Verbose displayName: Capture PSRepository
#
$targetModuleLocation = Join-Path -Path $(modulePath) -ChildPath 'PSDesiredStateConfiguration' - ${{ parameters.powershellExecutable }}: |
Move-Item -Path "$(Pipeline.Workspace)\Build" -Destination $targetModuleLocation -Force Install-module Pester -Force -MaximumVersion 4.99
# displayName: Install dependencies - Pester
$env:PSModulePath = '$(modulePath)' + [System.IO.Path]::PathSeparator + $env:PSModulePath timeoutInMinutes: 10
"PSModulePath is"| Write-Verbose -Verbose
$env:PSModulePath | Write-Verbose -Verbose - ${{ parameters.powershellExecutable }}: |
# Install-Module -Name "platyPS" -Force
Get-Module -ListAvailable -Name PSDesiredStateConfiguration | select Name,Version,PreRelease,Path | Write-Verbose -Verbose displayName: Install dependencies - PlatyPS
# timeoutInMinutes: 10
"Listing contents of $targetModuleLocation"| Write-Verbose -Verbose
Get-ChildItem -Recurse -Path $targetModuleLocation | Write-Verbose -Verbose - ${{ parameters.powershellExecutable }}: |
# Install-Module -Name "PSScriptAnalyzer" -RequiredVersion 1.18.0 -Force
Invoke-PSPackageProjectTest -Type Functional displayName: Install dependencies - PSScriptAnalyzer
displayName: Execute functional tests timeoutInMinutes: 10
errorActionPreference: continue
- ${{ parameters.powershellExecutable }}: |
Install-Module -Name PSPackageProject -Force
displayName: Install PSPackageProject module
- ${{ parameters.powershellExecutable }}: |
Get-InstalledModule -Name pester -AllVersions | Where-Object {$_.Version -ge ([version]::new(5,0,0))} | Uninstall-Module -Force
displayName: Remove >= 5.0.0 Pester
- task: DownloadBuildArtifacts@0
displayName: 'Download artifacts'
inputs:
buildType: current
downloadType: specific
itemPattern: '**/*.nupkg'
downloadPath: '$(System.ArtifactsDirectory)'
- ${{ parameters.powershellExecutable }}: |
$sourceName = 'pspackageproject-local-repo'
Register-PSRepository -Name $sourceName -SourceLocation '$(System.ArtifactsDirectory)' -ErrorAction Ignore
$config = Get-PSPackageProjectConfiguration
$buildOutputPath = $config.BuildOutputPath
$null = New-Item -ItemType Directory -Path $buildOutputPath -Verbose
$moduleName = $config.ModuleName
Save-Module -Repository $sourceName -Name $moduleName -Path $config.BuildOutputPath
displayName: Extract product artifact
timeoutInMinutes: 10
- ${{ parameters.powershellExecutable }}: |
Invoke-PSPackageProjectTest -Type Functional
displayName: Execute functional tests - InvokeDscResource Disabled
errorActionPreference: continue
- ${{ parameters.powershellExecutable }}: |
$configFolder = split-path $PROFILE
$configPath = Join-Path $configFolder -ChildPath powershell.config.json
copy-Item $(Build.SourcesDirectory)/assets/powershell.config.json $configPath
displayName: Enable ExperimentalFeature
errorActionPreference: continue
- ${{ parameters.powershellExecutable }}: |
Invoke-PSPackageProjectTest -Type Functional
displayName: Execute functional tests - InvokeDscResource Enabled
errorActionPreference: continue
- ${{ parameters.powershellExecutable }}: |
Invoke-PSPackageProjectTest -Type StaticAnalysis
displayName: Execute static analysis tests
# need to figure out how to disable PSAvoidOverwritingBuiltInCmdlets
continueOnError: true
errorActionPreference: continue
condition: succeededOrFailed()
- ${{ parameters.powershellExecutable }}: |
Unregister-PSRepository -Name 'pspackageproject-local-repo' -ErrorAction Ignore
displayName: Unregister temporary PSRepository
condition: always()
timeoutInMinutes: 10
+31
View File
@@ -0,0 +1,31 @@
parameters:
pool: 'Hosted VS2017'
jobName: 'credscan'
displayName: Secret Scan
jobs:
- job: ${{ parameters.jobName }}
pool:
name: ${{ parameters.pool }}
displayName: ${{ parameters.displayName }}
steps:
- powershell: Write-Host "##vso[build.updatebuildnumber]$env:BUILD_SOURCEBRANCHNAME-$env:BUILD_SOURCEVERSION-$((get-date).ToString("yyyyMMddhhmmss"))"
displayName: Set Build Name for Non-PR
condition: ne(variables['Build.Reason'], 'PullRequest')
- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2
displayName: 'Scan for secrets'
inputs:
debugMode: false
- task: securedevelopmentteam.vss-secure-development-tools.build-task-publishsecurityanalysislogs.PublishSecurityAnalysisLogs@2
displayName: 'Publish Secret Scan Logs to Build Artifacts'
continueOnError: true
- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1
displayName: 'Check for failures'
inputs:
CredScan: true
ToolLogsNotFoundAction: Error
+17
View File
@@ -0,0 +1,17 @@
steps:
- powershell: |
$shouldSign = $true
if($env:BUILD_REASON -ne 'Manual')
{
$shouldSign = $false
}
if($env:SKIP_SIGNING -eq 'Yes')
{
$shouldSign = $false
}
$vstsCommandString = "vso[task.setvariable variable=SHOULD_SIGN]$($shouldSign.ToString().ToLowerInvariant())"
Write-Host ("sending " + $vstsCommandString)
Write-Host "##$vstsCommandString"
displayName: 'Set SHOULD_SIGN Variable'
-3
View File
@@ -1,3 +0,0 @@
# Changelogs
* [v2 changelog](v2.md)
-15
View File
@@ -1,15 +0,0 @@
# v2 Changelog
## [v2.0.6]
### Main changes
- Fixed `PathSeparator` bug in Get-DSCResourceModules.
- Changed `PSDesiredStateConfiguration.InvokeDscResource` from experimental to permanently enabled feature.
- Changed `ErrorAction` to `Ignore` so that the error doesn't show up in `$Error`.
- Removed duplicate result resources from `Get-DSCResourcesModules`.
- Add `ImplementationDetail` member to results only when the member does not already exist.
- Updated v2 Release pipeline with latest Compliance requirements.
- Added SBOM generation that is now released with v2 module.
[v2.0.6]: https://www.powershellgallery.com/packages/PSDesiredStateConfiguration/2.0.6
-21
View File
@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2022 PowerShell Team
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.
+24 -53
View File
@@ -1,60 +1,31 @@
# PSDesiredStateConfiguration module # How to Create PSDesiredStateConfiguration NuGet package for PoweShell Core
- Modify psm1 file in PSDesiredStateConfiguration module.
-- Remove the signature from the bottom of the file.
-- Add your changes.
-- Get it signed from DSC Azure dev ops pipeline.
Following is the expected signing settings:
<file src="__INPATHROOT__\Modules\PSDesiredStateConfiguration\PSDesiredStateConfiguration.psm1" signType="AuthenticodeFormer" dest="__OUTPATHROOT__\Modules\PSDesiredStateConfiguration\PSDesiredStateConfiguration.psm1" />
**NOTE: We are currently NOT accepting PRs for this project** - Other files under PSDesiredStateConfiguration module doesnt need to be signed, you can modify them directly.
**PSDesiredStateConfiguration** (DSC) is the PowerShell module that enables writing configuration as code. - Change the version in nuget spec file.
The DSC platform was originally built on top of WMI for Windows. Starting in PowerShell 7.1 and working - Check-in these changes in DesiredStateConfiguration repository.
with internal partner teams
[Azure Guest Configuration](https://docs.microsoft.com/azure/governance/policy/concepts/guest-configuration)
and [Automanage](https://azure.microsoft.com/services/azure-automanage), we started making
DSC cross-platform by enabling `Invoke-DSCResource` to directly use resources without going through
the Local Configuration Manager (LCM).
Our initial cross-platform work to enable partner teams: - Create a NuGet package by running following command, it will generate NuGet package (PSDesiredStateConfiguration.6.2.0.nupkg). Get it published by PowerShell team.
nuget pack .\psdesiredstateconfiguration.nuspec
- Separated out the DSC parts in the PowerShell engine and moved them as a subsystem into the # Modify PowerShell code to pick up new version of NuGet package.
PSDesiredStateConfiguration module - Sync PowerShell/PowerShell repository and change NuGet package version in following files
- Remove PSDesiredStateConfiguration module from the PowerShell 7 package. This allows the src/powershell-unix/powershell-unix.csproj
PSDesiredStateConfiguration module to be developed independently of PowerShell and users can mix src/powershell-win-core/powershell-win-core.csproj
and match versions of PowerShell and PSDesiredStateConfiguration for their environment.
- This is now available on the PowerShell Gallery: [PSDesiredStateConfiguration 2.x](https://www.powershellgallery.com/packages/PSDesiredStateConfiguration)
- Removing the dependency on MOF: Initially, only support DSC Resources written as PowerShell
classes. This includes tooling to convert existing script based DSC Resources to be wrapped as
PowerShell classes.
## Documentation and resources ```sh
<ItemGroup>
- <PackageReference Include="PSDesiredStateConfiguration" Version="6.0.0-beta.8" />
+ <PackageReference Include="PSDesiredStateConfiguration" Version="6.2.0" />
<PackageReference Include="PowerShellHelpFiles" Version="1.0.0-*" />
</ItemGroup>
```
The documentation for **PSDesiredStateConfiguration** 3.0.0-beta1 is a work-in-progress. We invite the - Send PR to PowerShell team
community to review the documentation and assist us as we work on new documentation during the platform
development.
For more information about DSC v3, see [PowerShell Desired State Configuration Overview](https://docs.microsoft.com/powershell/dsc/overview?view=dsc-3.0)
To download the latest release from the PowerShell Gallery, see [PSDesiredStateConfiguration 3.0.0-beta1](https://www.powershellgallery.com/packages/PSDesiredStateConfiguration/3.0.0-beta1)
## Community Feedback
As we continue this journey to make DSC a cross-platform technology, we invite the community to
share your ideas and open
[issues](https://github.com/PowerShell/PSDesiredStateConfiguration/issues). During the PowerShell
7.3 timeframe, we remain focused on enabling partner teams and will not be accepting public pull
requests.
## Build
### Requirements
- [Any recent PowerShell Core release](https://github.com/PowerShell/powershell/releases) to run the build script
- [.NET Core SDK](https://dotnet.microsoft.com/download/dotnet/thank-you/sdk-6.0.100-preview.4-windows-x64-binaries) of the version specified in `global.json` (`dotnet` should be visible through PATH env var)
- [`PSPackageProject` module](https://www.powershellgallery.com/packages/PSPackageProject) installed from PS Gallery
### Build Process
- Run `build.ps1 -Build -Clean`
- Compiled module will be in `./out/PSDesiredStateConfiguration`
## CI - Continuous Integration
CI pipeline definition is in `.vsts-ci\azure-pipelines-ci.yml` and running Compliance and Pester tests in `test\PSDesiredStateConfiguration.Tests.ps1` on Windows, Linux and Mac. CI builds are not signed.
## Publishing Releases
[The module is released on Powershell Gallery](https://www.powershellgallery.com/packages/PSDesiredStateConfiguration).
For a release the code of this repo is mirrored into an internal repo and `.vsts-ci\azure-pipelines-release.yml` pipeline is run. Release builds are signed.
+1
View File
@@ -0,0 +1 @@
{"ExperimentalFeatures":["PSCommandNotFoundSuggestion","PSForEachObjectParallel","PSImplicitRemotingBatching","Microsoft.PowerShell.Utility.PSDebugRunspaceWithBreakpoints","PSDesiredStateConfiguration.InvokeDscResource"]}
+19
View File
@@ -0,0 +1,19 @@
# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
steps:
- script: echo Hello, world!
displayName: 'Run a one-line script'
- script: |
echo Add other tasks to build, test, and deploy your project.
echo See https://aka.ms/yaml
displayName: 'Run a multi-line script'
+10 -12
View File
@@ -13,14 +13,17 @@ Implement build and packaging of the package and place the output $OutDirectory/
function DoBuild function DoBuild
{ {
Write-Verbose -Verbose -Message "Starting DoBuild" Write-Verbose -Verbose -Message "Starting DoBuild"
Write-Verbose -Verbose -Message "Make sure that 'nuget' and 'dotnet' are visible through PATH"
Write-Verbose -Verbose -Message "Copying module files to '${OutDirectory}/${ModuleName}'" Write-Verbose -Verbose -Message "Copying module files to '${OutDirectory}/${ModuleName}'"
# copy psm1 and psd1 files # copy psm1 and psd1 files
copy-item "${SrcPath}/*" "${OutDirectory}/${ModuleName}" -Recurse copy-item "${SrcPath}/*" "${OutDirectory}/${ModuleName}" -Recurse
$smaPackageVersionToUse = "7.2.0-preview.6" # 7.2.0-preview.6 - is the first SMA version that has DSC subsystem changes # copy help
$subsystemCodePath = Resolve-Path "${SrcPath}/../DscSubsystem" # Write-Verbose -Verbose -Message "Copying help files to '${OutDirectory}/${ModuleName}'"
# copy-item -Recurse "${HelpPath}/${Culture}" "${OutDirectory}/${ModuleName}"
$subsystemCodePath = Resolve-Path "${SrcPath}\..\DscSubsystem"
$subsystemBinPath = "bin/Debug/net6.0/publish/Microsoft.PowerShell.DscSubsystem.dll"
Write-Verbose -Verbose -Message "Subsystem code path ${subsystemCodePath}" Write-Verbose -Verbose -Message "Subsystem code path ${subsystemCodePath}"
if ( Test-Path $subsystemCodePath ) if ( Test-Path $subsystemCodePath )
@@ -28,27 +31,22 @@ function DoBuild
Write-Verbose -Verbose -Message "Building assembly and copying to '${OutDirectory}/${ModuleName}'" Write-Verbose -Verbose -Message "Building assembly and copying to '${OutDirectory}/${ModuleName}'"
Push-Location $subsystemCodePath Push-Location $subsystemCodePath
$result = dotnet publish
$PackageReferencesPath = Join-Path $subsystemCodePath "PackageReferences"
nuget install System.Management.Automation -OutputDirectory ./PackageReferences -PreRelease -Version $smaPackageVersionToUse -DependencyVersion Ignore -ExcludeVersion
dotnet publish
$subsystemBinPath = Join-Path (Get-ChildItem -Recurse "publish" -Directory) "Microsoft.PowerShell.DscSubsystem.dll"
if (Test-Path $subsystemBinPath) if (Test-Path $subsystemBinPath)
{ {
Copy-Item $subsystemBinPath "${OutDirectory}/${ModuleName}" Copy-Item $subsystemBinPath "${OutDirectory}/${ModuleName}"
} }
else else
{ {
Write-Error -Message "dotnet build failed - $subsystemBinPath not found" Write-Error "dotnet build failed - $subsystemBinPath not found - $result"
} }
Pop-Location Pop-Location
} }
else { else {
Write-Error -Message "No code to build in '$subsystemCodePath'" Write-Verbose -Verbose -Message "No code to build in '$subsystemCodePath'"
} }
## Add build and packaging here
Write-Verbose -Verbose -Message "Ending DoBuild" Write-Verbose -Verbose -Message "Ending DoBuild"
} }
-5
View File
@@ -1,5 +0,0 @@
{
"sdk": {
"version": "6.0.100-preview.4.21255.9"
}
}
-10
View File
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
<disabledPackageSources>
<clear />
</disabledPackageSources>
</configuration>
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata minClientVersion="3.4">
<id>PSDesiredStateConfiguration</id>
<version>2.0</version>
<title>PSDesiredStateConfiguration</title>
<authors>Microsoft</authors>
<owners>microsoft,powershell</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Provides pre-built PSDesiredStateConfiguration module for PowerShell.</description>
<summary></summary>
<copyright>© Microsoft Corporation. All rights reserved.</copyright>
<contentFiles>
<files include="**/*" buildAction="None" copyToOutput="true" flatten="false" />
</contentFiles>
</metadata>
</package>
+2 -24
View File
@@ -399,13 +399,6 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration.Internal.CrossPlatform
} }
} }
// as last resort - check if requested class is one of base classes
moduleQualifiedResourceName = GetModuleQualifiedResourceName(s_defaultModuleInfoForResource.Item1, s_defaultModuleInfoForResource.Item2.ToString(), className, className);
if (GuestConfigClassCache.TryGetValue(moduleQualifiedResourceName, out classCacheEntry))
{
return classCacheEntry.CimClassInstance;
}
return null; return null;
} }
} }
@@ -1330,29 +1323,14 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration.Internal.CrossPlatform
// MOF-based implementation of this used to generate MOF string representing classes/typeAst and pass it to MMI/MOF deserializer to get CimClass array // MOF-based implementation of this used to generate MOF string representing classes/typeAst and pass it to MMI/MOF deserializer to get CimClass array
// Here we are avoiding that roundtrip by constructing the resulting PSObjects directly // Here we are avoiding that roundtrip by constructing the resulting PSObjects directly
var className = typeAst.Name; var className = typeAst.Name;
var cimClassProperties = new List<PSObject>();
string cimSuperClassName = null; string cimSuperClassName = null;
if (typeAst.Attributes.Any(a => a.TypeName.GetReflectionAttributeType() == typeof(DscResourceAttribute))) if (typeAst.Attributes.Any(a => a.TypeName.GetReflectionAttributeType() == typeof(DscResourceAttribute)))
{ {
// In v2 code, PS classes with DscResourceAttribute were automtically inheriting (resource properties) from "OMI_BaseResource"
cimSuperClassName = "OMI_BaseResource"; cimSuperClassName = "OMI_BaseResource";
var moduleQualifiedResourceName = GetModuleQualifiedResourceName(s_defaultModuleInfoForResource.Item1, s_defaultModuleInfoForResource.Item2.ToString(), cimSuperClassName, cimSuperClassName);
DscClassCacheEntry baseResource = null;
if (ClassCache.TryGetValue(moduleQualifiedResourceName, out baseResource))
{
dynamic baseProperties = baseResource.CimClassInstance.Properties["ClassProperties"]?.Value;
if (baseProperties != null)
{
foreach(PSObject prop in baseProperties)
{
cimClassProperties.Add(prop);
}
}
}
} }
cimClassProperties.AddRange(ProcessMembers(embeddedInstanceTypes, typeAst, className)); var cimClassProperties = ProcessMembers(embeddedInstanceTypes, typeAst, className);
Queue<object> bases = new Queue<object>(); Queue<object> bases = new Queue<object>();
foreach (var b in typeAst.BaseTypes) foreach (var b in typeAst.BaseTypes)
@@ -1,20 +1,16 @@
<!-- USE "./build.ps1 -Build" TO BUILD THIS -->
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0"> <Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<PlatformTarget>AnyCPU</PlatformTarget>
<AssemblyName>Microsoft.PowerShell.DscSubsystem</AssemblyName> <AssemblyName>Microsoft.PowerShell.DscSubsystem</AssemblyName>
<!-- Assembly is fully signed in \.vsts-ci\azure-pipelines-release.yml -->
<DelaySign>true</DelaySign> <DelaySign>true</DelaySign>
<AssemblyOriginatorKeyFile>visualstudiopublic.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>visualstudiopublic.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<!-- Can't use PackageReference here because subsystem uses internal SMA types that are not available in `ref` version of the SMA package. <!-- TEMPORARY: This needs to be replaced with <PackageReference Include="System.Management.Automation" /> when Preview 6 is published with subsystem interface. -->
So a workaround is to download SMA package and reference local file (full runtime SMA assembly) in `runtimes` folder. --> <Reference Include="C:\Temp\SMA-Reference\System.Management.Automation.dll"></Reference>
<Reference Include="PackageReferences/System.Management.Automation/runtimes/win/lib/net6.0/System.Management.Automation.dll"></Reference>
</ItemGroup> </ItemGroup>
</Project> </Project>
@@ -30,7 +30,7 @@ Copyright = '(c) Microsoft Corporation. All rights reserved.'
Description = 'PowerShell Desired State Configuration' Description = 'PowerShell Desired State Configuration'
# Minimum version of the Windows PowerShell engine required by this module # Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '7.2' PowerShellVersion = '7.1'
# Name of the Windows PowerShell host required by this module # Name of the Windows PowerShell host required by this module
# PowerShellHostName = '' # PowerShellHostName = ''
@@ -63,7 +63,7 @@ PowerShellVersion = '7.2'
# FormatsToProcess = @() # FormatsToProcess = @()
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
NestedModules = @('Microsoft.PowerShell.DscSubsystem.dll') NestedModules = @('Microsoft.PowerShell.DscSubsystem.dll')
# 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. # 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.
FunctionsToExport = @( FunctionsToExport = @(
@@ -101,13 +101,13 @@ HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=2113535'
PrivateData = @{ PrivateData = @{
PSData = @{ PSData = @{
Prerelease = 'beta1' ExperimentalFeatures = @(
Tags = @('PSDesiredStateConfiguration', @{
'PSEdition_Core', Name = 'PSDesiredStateConfiguration.InvokeDscResource'
'Linux', Description = "Enables the Invoke-DscResource cmdlet and related features."
'Mac', }
'Windows') )
ProjectUri = 'https://github.com/PowerShell/PSDesiredStateConfiguration'
} }
} }
} }
@@ -47,7 +47,7 @@ data LocalizedData
GetDscResourceInputName=The Get-DscResource input '{0}' parameter value is '{1}'. GetDscResourceInputName=The Get-DscResource input '{0}' parameter value is '{1}'.
ResourceNotMatched=Skipping resource '{0}' as it does not match the requested name. ResourceNotMatched=Skipping resource '{0}' as it does not match the requested name.
InitializingClassCache=Initializing class cache InitializingClassCache=Initializing class cache
LoadingDefaultKeywords=Loading default keywords LoadingDefaultCimKeywords=Loading default CIM keywords
GettingModuleList=Getting module list GettingModuleList=Getting module list
CreatingResourceList=Creating resource list CreatingResourceList=Creating resource list
CreatingResource=Creating resource '{0}'. CreatingResource=Creating resource '{0}'.
@@ -71,7 +71,7 @@ data LocalizedData
Set-StrictMode -Off Set-StrictMode -Off
# In case localized resource is not available we revert back to English as defined in LocalizedData section so ignore the error instead of showing it to user. # In case localized resource is not available we revert back to English as defined in LocalizedData section so ignore the error instead of showing it to user.
Import-LocalizedData -BindingVariable LocalizedData -FileName PSDesiredStateConfiguration.Resource.psd1 -ErrorAction Ignore Import-LocalizedData -BindingVariable LocalizedData -FileName PSDesiredStateConfiguration.Resource.psd1 -ErrorAction SilentlyContinue
Import-Module $PSScriptRoot/helpers/DscResourceInfo.psm1 Import-Module $PSScriptRoot/helpers/DscResourceInfo.psm1
@@ -701,6 +701,33 @@ function ConvertTo-MOFInstance
$OFS = $oldOFS $OFS = $oldOFS
} }
#
# Add extra information about Author, GenerationHost, GenerationDate and Name if they are not specified
#
if ($Type -match 'OMI_ConfigurationDocument' -and $Properties)
{
if (-not $Properties.ContainsKey('Author'))
{
$result += " Author = `"$([system.environment]::UserName)`";`n"
}
if (-not $Properties.ContainsKey('GenerationDate'))
{
$result += " GenerationDate = `"$(Get-Date)`";`n"
}
if (-not $Properties.ContainsKey('GenerationHost'))
{
$result += " GenerationHost = `"$([system.environment]::MachineName)`";`n"
}
# todo: report error is configuration name does't match
if (-not $Properties.ContainsKey('Name'))
{
$result += " Name = `"$(Get-PSTopConfigurationName)`";`n"
}
}
# #
# Append the completed mof instance text to the overall document # Append the completed mof instance text to the overall document
# #
@@ -2272,7 +2299,7 @@ function Update-ModuleVersion
$moduleVersionstring = "ModuleVersion = " $moduleVersionstring = "ModuleVersion = "
$moduleVersionstring += "`"$moduleVersionValue`"" + ";" $moduleVersionstring += "`"$moduleVersionValue`"" + ";"
$NodeInstanceAliases[$alias] = $first + $moduleVersionstring + "`n};" $NodeInstanceAliases[$alias] = $first + $moduleVersionstring + "`r`n};"
} }
} }
} }
@@ -2308,14 +2335,14 @@ function Update-DependsOn
$needAdd = $true $needAdd = $true
$first = $instanceText.Substring(0, $curlyPosition) $first = $instanceText.Substring(0, $curlyPosition)
$dependsOn = "DependsOn = {`n" $dependsOn = "DependsOn = {`r`n"
$len = @($NodeResources[$resourceId]).Length $len = @($NodeResources[$resourceId]).Length
$dependsOn += foreach ($resourceId in $NodeResources[$resourceId]) $dependsOn += foreach ($resourceId in $NodeResources[$resourceId])
{ {
' ' + "`"$($resourceId -replace '\\', '\\' -replace '"', '\"')`"" + ' ' + "`"$($resourceId -replace '\\', '\\' -replace '"', '\"')`"" +
$(if (--$len -gt 0) $(if (--$len -gt 0)
{ {
",`n" ",`r`n"
} }
else else
{ {
@@ -2329,7 +2356,7 @@ function Update-DependsOn
if($needAdd) if($needAdd)
{ {
$NodeInstanceAliases[$alias] = $first + $dependsOn + "`n};" $NodeInstanceAliases[$alias] = $first + $dependsOn + "`r`n};"
} }
} }
} }
@@ -2371,12 +2398,12 @@ function Update-ConfigurationDocumentRef
$needAdd = $true $needAdd = $true
$first = $instanceText.Substring(0, $curlyPosition).TrimEnd() $first = $instanceText.Substring(0, $curlyPosition).TrimEnd()
$ConfigurationNameRef = "`n ConfigurationName = `"$ConfigurationName`";" $ConfigurationNameRef = "`r`n ConfigurationName = `"$ConfigurationName`";"
} }
if($needAdd) if($needAdd)
{ {
$NodeInstanceAliases[$alias] = $first + $ConfigurationNameRef + "`n};`n" $NodeInstanceAliases[$alias] = $first + $ConfigurationNameRef + "`r`n};"
} }
} }
} }
@@ -2429,7 +2456,7 @@ function Write-MetaConfigFile
) )
# Set up prefix for both the configuration and metaconfiguration documents. # Set up prefix for both the configuration and metaconfiguration documents.
$nodeDoc = $null $nodeDoc = "/*`n@TargetNode='$mofNode'`n" + "@GeneratedBy=$([system.environment]::UserName)`n@GenerationDate=$(Get-Date)`n@GenerationHost=$([system.environment]::MachineName)`n*/`n"
$nodeConfigurationDocument = $null $nodeConfigurationDocument = $null
[int]$nodeDocCount = 0 [int]$nodeDocCount = 0
$resourceManagers = $null $resourceManagers = $null
@@ -2555,15 +2582,18 @@ function Write-MetaConfigFile
Write-Debug -Message " ${ConfigurationName}: Adding missing OMI_ConfigurationDocument element to the document" Write-Debug -Message " ${ConfigurationName}: Adding missing OMI_ConfigurationDocument element to the document"
if($Script:NodesPasswordEncrypted[$mofNode]) if($Script:NodesPasswordEncrypted[$mofNode])
{ {
$nodeDoc += "`ninstance of OMI_ConfigurationDocument`n{`n Version=`"2.0.0`";`n MinimumCompatibleVersion = `"$($script:PSMetaConfigDocumentInstVersionInfo['MinimumCompatibleVersion'])`";`n CompatibleVersionAdditionalProperties= $(Get-CompatibleVersionAddtionaPropertiesStr);`n ContentType=`"PasswordEncrypted`";`n Name=`"$(Get-PSTopConfigurationName)`";`n};" $nodeDoc += "`ninstance of OMI_ConfigurationDocument`n{`n Version=`"2.0.0`";`n MinimumCompatibleVersion = `"$($script:PSMetaConfigDocumentInstVersionInfo['MinimumCompatibleVersion'])`";`n CompatibleVersionAdditionalProperties= $(Get-CompatibleVersionAddtionaPropertiesStr);`n Author=`"$([system.environment]::UserName)`";`n GenerationDate=`"$(Get-Date)`";`n GenerationHost=`"$([system.environment]::MachineName)`";`n ContentType=`"PasswordEncrypted`";`n Name=`"$(Get-PSTopConfigurationName)`";`n};"
} }
else else
{ {
$nodeDoc += "`ninstance of OMI_ConfigurationDocument`n{`n Version=`"2.0.0`";`n MinimumCompatibleVersion = `"$($script:PSMetaConfigDocumentInstVersionInfo['MinimumCompatibleVersion'])`";`n CompatibleVersionAdditionalProperties= $(Get-CompatibleVersionAddtionaPropertiesStr);`n Name=`"$(Get-PSTopConfigurationName)`";`n};" $nodeDoc += "`ninstance of OMI_ConfigurationDocument`n{`n Version=`"2.0.0`";`n MinimumCompatibleVersion = `"$($script:PSMetaConfigDocumentInstVersionInfo['MinimumCompatibleVersion'])`";`n CompatibleVersionAdditionalProperties= $(Get-CompatibleVersionAddtionaPropertiesStr);`n Author=`"$([system.environment]::UserName)`";`n GenerationDate=`"$(Get-Date)`";`n GenerationHost=`"$([system.environment]::MachineName)`";`n Name=`"$(Get-PSTopConfigurationName)`";`n};"
} }
} }
} }
# Fix up newlines to be CRLF
$nodeDoc = $nodeDoc -replace "`n", "`r`n"
# todo: meta configuration might not be verifiable currently # todo: meta configuration might not be verifiable currently
$errMsg = Test-MofInstanceText $nodeDoc $errMsg = Test-MofInstanceText $nodeDoc
if($errMsg) if($errMsg)
@@ -2658,7 +2688,7 @@ function Write-NodeMOFFile
) )
# Set up prefix for both the configuration and metaconfiguration documents. # Set up prefix for both the configuration and metaconfiguration documents.
$nodeDoc = $null $nodeDoc = "/*`n@TargetNode='$mofNode'`n" + "@GeneratedBy=$([system.environment]::UserName)`n@GenerationDate=$(Get-Date)`n@GenerationHost=$([system.environment]::MachineName)`n*/`n"
$nodeMetaDoc = $nodeDoc $nodeMetaDoc = $nodeDoc
$nodeConfigurationDocument = $null $nodeConfigurationDocument = $null
[int]$metaDocCount = 0 [int]$metaDocCount = 0
@@ -2716,11 +2746,11 @@ function Write-NodeMOFFile
Write-Debug -Message " ${ConfigurationName}: Adding missing OMI_ConfigurationDocument element to the document" Write-Debug -Message " ${ConfigurationName}: Adding missing OMI_ConfigurationDocument element to the document"
if($Script:NodesPasswordEncrypted[$mofNode]) if($Script:NodesPasswordEncrypted[$mofNode])
{ {
$nodeMetaDoc += "`ninstance of OMI_ConfigurationDocument`n{`n Version=`"2.0.0`";`n MinimumCompatibleVersion = `"1.0.0`";`n CompatibleVersionAdditionalProperties= $(Get-CompatibleVersionAddtionaPropertiesStr);`n ContentType=`"PasswordEncrypted`";`n Name=`"$(Get-PSTopConfigurationName)`";`n};" $nodeMetaDoc += "`ninstance of OMI_ConfigurationDocument`n{`n Version=`"2.0.0`";`n MinimumCompatibleVersion = `"1.0.0`";`n CompatibleVersionAdditionalProperties= $(Get-CompatibleVersionAddtionaPropertiesStr);`n Author=`"$([system.environment]::UserName)`";`n GenerationDate=`"$(Get-Date)`";`n GenerationHost=`"$([system.environment]::MachineName)`";`n ContentType=`"PasswordEncrypted`";`n Name=`"$(Get-PSTopConfigurationName)`";`n};"
} }
else else
{ {
$nodeMetaDoc += "`ninstance of OMI_ConfigurationDocument`n{`n Version=`"2.0.0`";`n MinimumCompatibleVersion = `"1.0.0`";`n CompatibleVersionAdditionalProperties= $(Get-CompatibleVersionAddtionaPropertiesStr);`n Name=`"$(Get-PSTopConfigurationName)`";`n};" $nodeMetaDoc += "`ninstance of OMI_ConfigurationDocument`n{`n Version=`"2.0.0`";`n MinimumCompatibleVersion = `"1.0.0`";`n CompatibleVersionAdditionalProperties= $(Get-CompatibleVersionAddtionaPropertiesStr);`n Author=`"$([system.environment]::UserName)`";`n GenerationDate=`"$(Get-Date)`";`n GenerationHost=`"$([system.environment]::MachineName)`";`n Name=`"$(Get-PSTopConfigurationName)`";`n};"
} }
} }
} }
@@ -2739,26 +2769,62 @@ function Write-NodeMOFFile
{ {
if($nodeDoc.Contains("PsDscRunAsCredential")) if($nodeDoc.Contains("PsDscRunAsCredential"))
{ {
$nodeDoc += "`ninstance of OMI_ConfigurationDocument`n{`n Version=`"2.0.0`";`n MinimumCompatibleVersion = `"2.0.0`";`n CompatibleVersionAdditionalProperties= {`"Omi_BaseResource:ConfigurationName`"};`n ContentType=`"PasswordEncrypted`";`n Name=`"$(Get-PSTopConfigurationName)`";`n};" $nodeDoc += "`ninstance of OMI_ConfigurationDocument`n
{`n Version=`"2.0.0`";`n
MinimumCompatibleVersion = `"2.0.0`";`n
CompatibleVersionAdditionalProperties= {`"Omi_BaseResource:ConfigurationName`"};`n
Author=`"$([system.environment]::UserName)`";`n
GenerationDate=`"$(Get-Date)`";`n
GenerationHost=`"$([system.environment]::MachineName)`";`n
ContentType=`"PasswordEncrypted`";`n
Name=`"$(Get-PSTopConfigurationName)`";`n
};"
} }
else else
{ {
$nodeDoc += "`ninstance of OMI_ConfigurationDocument`n{`n Version=`"2.0.0`";`n MinimumCompatibleVersion = `"1.0.0`";`n CompatibleVersionAdditionalProperties= {`"Omi_BaseResource:ConfigurationName`"};`n ContentType=`"PasswordEncrypted`";`n Name=`"$(Get-PSTopConfigurationName)`";`n};" $nodeDoc += "`ninstance of OMI_ConfigurationDocument`n
{`n Version=`"2.0.0`";`n
MinimumCompatibleVersion = `"1.0.0`";`n
CompatibleVersionAdditionalProperties= {`"Omi_BaseResource:ConfigurationName`"};`n
Author=`"$([system.environment]::UserName)`";`n
GenerationDate=`"$(Get-Date)`";`n
GenerationHost=`"$([system.environment]::MachineName)`";`n
ContentType=`"PasswordEncrypted`";`n
Name=`"$(Get-PSTopConfigurationName)`";`n
};"
} }
} }
else else
{ {
if($nodeDoc.Contains("PsDscRunAsCredential")) if($nodeDoc.Contains("PsDscRunAsCredential"))
{ {
$nodeDoc += "`ninstance of OMI_ConfigurationDocument`n{`n Version=`"2.0.0`";`n MinimumCompatibleVersion = `"2.0.0`";`n CompatibleVersionAdditionalProperties= {`"Omi_BaseResource:ConfigurationName`"};`n Name=`"$(Get-PSTopConfigurationName)`";`n};" $nodeDoc += "`ninstance of OMI_ConfigurationDocument`n
{`n Version=`"2.0.0`";`n
MinimumCompatibleVersion = `"2.0.0`";`n
CompatibleVersionAdditionalProperties= {`"Omi_BaseResource:ConfigurationName`"};`n
Author=`"$([system.environment]::UserName)`";`n
GenerationDate=`"$(Get-Date)`";`n
GenerationHost=`"$([system.environment]::MachineName)`";`n
Name=`"$(Get-PSTopConfigurationName)`";`n
};"
} }
else else
{ {
$nodeDoc += "`ninstance of OMI_ConfigurationDocument`n{`n Version=`"2.0.0`";`n MinimumCompatibleVersion = `"1.0.0`";`n CompatibleVersionAdditionalProperties= {`"Omi_BaseResource:ConfigurationName`"};`n Name=`"$(Get-PSTopConfigurationName)`";`n};" $nodeDoc += "`ninstance of OMI_ConfigurationDocument`n
{`n Version=`"2.0.0`";`n
MinimumCompatibleVersion = `"1.0.0`";`n
CompatibleVersionAdditionalProperties= {`"Omi_BaseResource:ConfigurationName`"};`n
Author=`"$([system.environment]::UserName)`";`n
GenerationDate=`"$(Get-Date)`";`n
GenerationHost=`"$([system.environment]::MachineName)`";`n
Name=`"$(Get-PSTopConfigurationName)`";`n
};"
} }
} }
} }
} }
# Fix up newlines to be CRLF
$nodeDoc = $nodeDoc -replace "`n", "`r`n"
if($nodeDocCount -gt 0) if($nodeDocCount -gt 0)
{ {
@@ -2772,6 +2838,7 @@ function Write-NodeMOFFile
if($nodeMetaDoc -match 'MSFT_DSCMetaConfiguration' -and $Script:PSConfigurationErrors -eq 0) if($nodeMetaDoc -match 'MSFT_DSCMetaConfiguration' -and $Script:PSConfigurationErrors -eq 0)
{ {
$nodeMetaDoc = $nodeMetaDoc -replace "`n", "`r`n"
$nodeMetaDoc > $nodeMetaOutfile $nodeMetaDoc > $nodeMetaOutfile
Get-ChildItem $nodeMetaOutfile Get-ChildItem $nodeMetaOutfile
} }
@@ -3481,7 +3548,7 @@ function New-DscChecksum
} }
# If the Force parameter was not specified and the hash file already exists for the current file, log this, and skip this file # If the Force parameter was not specified and the hash file already exists for the current file, log this, and skip this file
if (!$Force -and (Get-Item -Path $fileOutpath -ErrorAction Ignore)) if (!$Force -and (Get-Item -Path $fileOutpath -ErrorAction SilentlyContinue))
{ {
Write-Log -Message ($LocalizedData.CheckSumFileExists -f $fileOutpath) Write-Log -Message ($LocalizedData.CheckSumFileExists -f $fileOutpath)
continue continue
@@ -3859,7 +3926,7 @@ function Get-DscResource
{ {
$initialized = $false $initialized = $false
$ModuleString = $null $ModuleString = $null
Write-Progress -Id 1 -Activity $LocalizedData.LoadingDefaultKeywords Write-Progress -Id 1 -Activity $LocalizedData.LoadingDefaultCimKeywords
$keywordErrors = New-Object -TypeName 'System.Collections.ObjectModel.Collection[System.Exception]' $keywordErrors = New-Object -TypeName 'System.Collections.ObjectModel.Collection[System.Exception]'
@@ -4091,8 +4158,10 @@ function GetResourceFromKeyword
Ascending = $true Ascending = $true
} }
$resource.UpdateProperties($updatedProperties) $resource.UpdateProperties($updatedProperties)
if ([ExperimentalFeature]::IsEnabled("PSDesiredStateConfiguration.InvokeDscResource"))
$resource | Add-Member -MemberType NoteProperty -Name 'ImplementationDetail' -Value $implementationDetail {
$resource | Add-Member -MemberType NoteProperty -Name 'ImplementationDetail' -Value $implementationDetail
}
return $resource return $resource
} }
@@ -4525,6 +4594,7 @@ Export-ModuleMember -Function Get-DscResource, Configuration
function Invoke-DscResource function Invoke-DscResource
{ {
[Experimental("PSDesiredStateConfiguration.InvokeDscResource", "Show")]
[CmdletBinding(HelpUri = '')] [CmdletBinding(HelpUri = '')]
param ( param (
[Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Mandatory)] [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Mandatory)]
@@ -4625,27 +4695,30 @@ function Invoke-DscClassBasedResource
$type = $resource.ResourceType $type = $resource.ResourceType
Write-Debug "Importing $path ..." Write-Debug "Importing $path ..."
$powershell = [PowerShell]::Create('CurrentRunspace') $iss = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault2()
# next line prevents PSModulePath from being reset to default
$iss.EnvironmentVariables.Add([System.Management.Automation.Runspaces.SessionStateVariableEntry]::new("PSModulePath", $env:PSModulePath, $null))
$powershell = [PowerShell]::Create($iss)
$script = @" $script = @"
using module $path using module $path
return [$type]::new() return [$type]
"@ "@
$null= $powershell.AddScript($script) $null = $powershell.AddScript($script)
$dscObj=$powershell.Invoke() | Select-object -First 1 $dscType = $powershell.Invoke() | Select-object -First 1
Write-Debug "Imported Type: $($dscType | Out-String)"
$dscObj = $dscType::new()
foreach($key in $Property.Keys) foreach($key in $Property.Keys)
{ {
$value = $Property.$key $value = $Property.$key
Write-Debug "Setting $key to $value" Write-Debug "Setting $key to $value"
$dscObj.$key = $value $dscObj.$key = $value
} }
$info = $dscObj | Out-String Write-Debug "Object with filled keys: $($dscObj | Out-String)"
Write-Debug $info
Write-Debug "calling $type.$Method() ..." Write-Debug "Calling $type.$Method() ..."
$global:DSCMachineStatus = $null $global:DSCMachineStatus = $null
$output = $dscObj.$Method() $output = $dscObj.$Method()
return Get-InvokeDscResourceResult -Output $output -Method $Method return Get-InvokeDscResourceResult -Output $output -Method $Method
} }
+368 -263
View File
@@ -21,7 +21,11 @@ Function Install-ModuleIfMissing {
} }
} }
Describe "Test PSDesiredStateConfiguration" { Function Test-IsInvokeDscResourceEnable {
return [ExperimentalFeature]::IsEnabled("PSDesiredStateConfiguration.InvokeDscResource")
}
Describe "Test PSDesiredStateConfiguration" -tags CI {
Context "Module loading" { Context "Module loading" {
BeforeAll { BeforeAll {
Function BeCommand { Function BeCommand {
@@ -62,7 +66,7 @@ Describe "Test PSDesiredStateConfiguration" {
$commands | Should -HaveCommand -CommandName 'Configuration' -ModuleName PSDesiredStateConfiguration $commands | Should -HaveCommand -CommandName 'Configuration' -ModuleName PSDesiredStateConfiguration
} }
It "The module should have the New-DscChecksum Command" { It "The module should have the Configuration Command" {
$commands | Should -HaveCommand -CommandName 'New-DscChecksum' -ModuleName PSDesiredStateConfiguration $commands | Should -HaveCommand -CommandName 'New-DscChecksum' -ModuleName PSDesiredStateConfiguration
} }
@@ -70,15 +74,195 @@ Describe "Test PSDesiredStateConfiguration" {
$commands | Should -HaveCommand -CommandName 'Get-DscResource' -ModuleName PSDesiredStateConfiguration $commands | Should -HaveCommand -CommandName 'Get-DscResource' -ModuleName PSDesiredStateConfiguration
} }
It "The module should have the Invoke-DscResource Command" { It "The module should have the Invoke-DscResource Command" -Skip:(!(Test-IsInvokeDscResourceEnable)) {
$commands | Should -HaveCommand -CommandName 'Invoke-DscResource' -ModuleName PSDesiredStateConfiguration $commands | Should -HaveCommand -CommandName 'Invoke-DscResource' -ModuleName PSDesiredStateConfiguration
} }
}
Context "Get-DscResource - Composite Resources" {
BeforeAll {
$origProgress = $global:ProgressPreference
$global:ProgressPreference = 'SilentlyContinue'
Install-ModuleIfMissing -Name PSDscResources
$testCases = @(
@{
TestCaseName = 'case mismatch in resource name'
Name = 'groupset'
ModuleName = 'PSDscResources'
}
@{
TestCaseName = 'Both names have matching case'
Name = 'GroupSet'
ModuleName = 'PSDscResources'
}
@{
TestCaseName = 'case mismatch in module name'
Name = 'GroupSet'
ModuleName = 'psdscResources'
}
)
}
It "The module should have the ConvertTo-DscJsonSchema Command" { AfterAll {
$commands | Should -HaveCommand -CommandName 'ConvertTo-DscJsonSchema' -ModuleName PSDesiredStateConfiguration $Global:ProgressPreference = $origProgress
}
it "should be able to get <Name> - <TestCaseName>" -TestCases $testCases {
param($Name)
if ($IsWindows) {
Set-ItResult -Pending -Because "Will only find script from PSDesiredStateConfiguration without modulename"
}
if ($IsLinux) {
Set-ItResult -Pending -Because "https://github.com/PowerShell/PSDesiredStateConfiguration/issues/26"
}
$resource = Get-DscResource -Name $name
$resource | Should -Not -BeNullOrEmpty
$resource.Name | Should -Be $Name
if (Test-IsInvokeDscResourceEnable) {
$resource.ImplementationDetail | Should -BeNullOrEmpty
}
else {
$resource.ImplementationDetail | Should -BeNullOrEmpty
}
}
it "should be able to get <Name> from <ModuleName> - <TestCaseName>" -TestCases $testCases {
param($Name, $ModuleName, $PendingBecause)
if ($IsLinux) {
Set-ItResult -Pending -Because "https://github.com/PowerShell/PSDesiredStateConfiguration/issues/26"
}
if ($PendingBecause) {
Set-ItResult -Pending -Because $PendingBecause
}
$resource = Get-DscResource -Name $Name -Module $ModuleName
$resource | Should -Not -BeNullOrEmpty
$resource.Name | Should -Be $Name
if (Test-IsInvokeDscResourceEnable) {
$resource.ImplementationDetail | Should -BeNullOrEmpty
}
else {
$resource.ImplementationDetail | Should -BeNullOrEmpty
}
} }
} }
Context "Get-DscResource - ScriptResources" {
BeforeAll {
$origProgress = $global:ProgressPreference
$global:ProgressPreference = 'SilentlyContinue'
Install-ModuleIfMissing -Name PSDscResources -Force
# Install PowerShellGet only if PowerShellGet 2.2.1 or newer does not exist
Install-ModuleIfMissing -Name PowerShellGet -MinimumVersion '2.2.1'
$module = Get-Module PowerShellGet -ListAvailable | Sort-Object -Property Version -Descending | Select-Object -First 1
$psGetModuleSpecification = @{ModuleName = $module.Name; ModuleVersion = $module.Version.ToString() }
$psGetModuleCount = @(Get-Module PowerShellGet -ListAvailable).Count
$testCases = @(
@{
TestCaseName = 'case mismatch in resource name'
Name = 'script'
ModuleName = 'PSDscResources'
}
@{
TestCaseName = 'Both names have matching case'
Name = 'Script'
ModuleName = 'PSDscResources'
}
@{
TestCaseName = 'case mismatch in module name'
Name = 'Script'
ModuleName = 'psdscResources'
}
<#
Add these back when PowerShellGet is fixed https://github.com/PowerShell/PowerShellGet/pull/529
@{
TestCaseName = 'case mismatch in resource name'
Name = 'PsModule'
ModuleName = 'PowerShellGet'
}
@{
TestCaseName = 'Both names have matching case'
Name = 'PSModule'
ModuleName = 'PowerShellGet'
}
@{
TestCaseName = 'case mismatch in module name'
Name = 'PSModule'
ModuleName = 'powershellget'
}
#>
)
}
AfterAll {
$Global:ProgressPreference = $origProgress
}
it "should be able to get <Name> - <TestCaseName>" -TestCases $testCases {
param($Name)
if ($IsWindows) {
Set-ItResult -Pending -Because "Will only find script from PSDesiredStateConfiguration without modulename"
}
if ($PendingBecause) {
Set-ItResult -Pending -Because $PendingBecause
}
$resources = @(Get-DscResource -Name $name)
$resources | Should -Not -BeNullOrEmpty
foreach ($resource in $resource) {
$resource.Name | Should -Be $Name
if (Test-IsInvokeDscResourceEnable) {
$resource.ImplementationDetail | Should -Be 'ScriptBased'
}
else {
$resource.ImplementationDetail | Should -BeNullOrEmpty
}
}
}
it "should be able to get <Name> from <ModuleName> - <TestCaseName>" -TestCases $testCases {
param($Name, $ModuleName, $PendingBecause)
if ($IsLinux) {
Set-ItResult -Pending -Because "https://github.com/PowerShell/PSDesiredStateConfiguration/issues/12 and https://github.com/PowerShell/PowerShellGet/pull/529"
}
if ($PendingBecause) {
Set-ItResult -Pending -Because $PendingBecause
}
$resources = @(Get-DscResource -Name $name -Module $ModuleName)
$resources | Should -Not -BeNullOrEmpty
foreach ($resource in $resource) {
$resource.Name | Should -Be $Name
if (Test-IsInvokeDscResourceEnable) {
$resource.ImplementationDetail | Should -Be 'ScriptBased'
}
else {
$resource.ImplementationDetail | Should -BeNullOrEmpty
}
}
}
it "should throw when resource is not found" {
Set-ItResult -Pending -Because "https://github.com/PowerShell/PSDesiredStateConfiguration/issues/17"
{
Get-DscResource -Name antoehusatnoheusntahoesnuthao -Module tanshoeusnthaosnetuhasntoheusnathoseun
} |
Should -Throw -ErrorId 'Microsoft.PowerShell.Commands.WriteErrorException,CheckResourceFound'
}
}
Context "Get-DscResource - Class base Resources" { Context "Get-DscResource - Class base Resources" {
BeforeAll { BeforeAll {
@@ -118,11 +302,19 @@ Describe "Test PSDesiredStateConfiguration" {
$resource = Get-DscResource -Name $Name -Module $ModuleName $resource = Get-DscResource -Name $Name -Module $ModuleName
$resource | Should -Not -BeNullOrEmpty $resource | Should -Not -BeNullOrEmpty
$resource.Name | Should -Be $Name $resource.Name | Should -Be $Name
$resource.ImplementationDetail | Should -Be 'ClassBased' if (Test-IsInvokeDscResourceEnable) {
$resource.ImplementationDetail | Should -Be 'ClassBased'
}
else {
$resource.ImplementationDetail | Should -BeNullOrEmpty
}
} }
it "should be able to get class resource - <Name> - <TestCaseName>" -TestCases $classTestCases { it "should be able to get class resource - <Name> - <TestCaseName>" -TestCases $classTestCases {
param($Name, $ModuleName, $PendingBecause) param($Name, $ModuleName, $PendingBecause)
if ($IsWindows) {
Set-ItResult -Pending -Because "https://github.com/PowerShell/PSDesiredStateConfiguration/issues/19"
}
if ($PendingBecause) { if ($PendingBecause) {
Set-ItResult -Pending -Because $PendingBecause Set-ItResult -Pending -Because $PendingBecause
@@ -131,10 +323,14 @@ Describe "Test PSDesiredStateConfiguration" {
$resource = Get-DscResource -Name $Name $resource = Get-DscResource -Name $Name
$resource | Should -Not -BeNullOrEmpty $resource | Should -Not -BeNullOrEmpty
$resource.Name | Should -Be $Name $resource.Name | Should -Be $Name
$resource.ImplementationDetail | Should -Be 'ClassBased' if (Test-IsInvokeDscResourceEnable) {
$resource.ImplementationDetail | Should -Be 'ClassBased'
}
else {
$resource.ImplementationDetail | Should -BeNullOrEmpty
}
} }
} }
Context "Invoke-DscResource" { Context "Invoke-DscResource" {
BeforeAll { BeforeAll {
$origProgress = $global:ProgressPreference $origProgress = $global:ProgressPreference
@@ -150,6 +346,169 @@ Describe "Test PSDesiredStateConfiguration" {
$Global:ProgressPreference = $origProgress $Global:ProgressPreference = $origProgress
} }
Context "mof resources" {
BeforeAll {
$dscMachineStatusCases = @(
@{
value = '1'
expectedResult = $true
}
@{
value = '$true'
expectedResult = $true
}
@{
value = '0'
expectedResult = $false
}
@{
value = '$false'
expectedResult = $false
}
)
Install-ModuleIfMissing -Name PowerShellGet -Force -SkipPublisherCheck -MinimumVersion '2.2.1'
Install-ModuleIfMissing -Name xWebAdministration
$module = Get-Module PowerShellGet -ListAvailable | Sort-Object -Property Version -Descending | Select-Object -First 1
$psGetModuleSpecification = @{ModuleName = $module.Name; ModuleVersion = $module.Version.ToString() }
}
it "Set method should work" -Skip:(!(Test-IsInvokeDscResourceEnable)) {
if (!$IsLinux) {
$result = Invoke-DscResource -Name PSModule -ModuleName $psGetModuleSpecification -Method set -Property @{
Name = 'PsDscResources'
InstallationPolicy = 'Trusted'
}
}
else {
# workraound because of https://github.com/PowerShell/PowerShellGet/pull/529
Install-ModuleIfMissing -Name PsDscResources -Force
}
$result.RebootRequired | Should -BeFalse
$module = Get-module PsDscResources -ListAvailable
$module | Should -Not -BeNullOrEmpty -Because "Resource should have installed module"
}
it 'Set method should return RebootRequired=<expectedResult> when $global:DSCMachineStatus = <value>' -Skip:(!(Test-IsInvokeDscResourceEnable)) -TestCases $dscMachineStatusCases {
param(
$value,
$ExpectedResult
)
# using create scriptBlock because $using:<variable> doesn't work with existing Invoke-DscResource
# Verified in Windows PowerShell on 20190814
$result = Invoke-DscResource -Name Script -ModuleName PSDscResources -Method Set -Property @{TestScript = { Write-Output 'test'; return $false }; GetScript = { return @{ } }; SetScript = [scriptblock]::Create("`$global:DSCMachineStatus = $value;return") }
$result | Should -Not -BeNullOrEmpty
$result.RebootRequired | Should -BeExactly $expectedResult
}
it "Test method should return false" -Skip:(!(Test-IsInvokeDscResourceEnable)) {
$result = Invoke-DscResource -Name Script -ModuleName PSDscResources -Method Test -Property @{TestScript = { Write-Output 'test'; return $false }; GetScript = { return @{ } }; SetScript = { return } }
$result | Should -Not -BeNullOrEmpty
$result.InDesiredState | Should -BeFalse -Because "Test method return false"
}
it "Test method should return true" -Skip:(!(Test-IsInvokeDscResourceEnable)) {
$result = Invoke-DscResource -Name Script -ModuleName PSDscResources -Method Test -Property @{TestScript = { Write-Verbose 'test'; return $true }; GetScript = { return @{ } }; SetScript = { return } }
$result | Should -BeTrue -Because "Test method return true"
}
it "Test method should return true with moduleSpecification" -Skip:(!(Test-IsInvokeDscResourceEnable)) {
$module = get-module PsDscResources -ListAvailable
$moduleSpecification = @{ModuleName = $module.Name; ModuleVersion = $module.Version.ToString() }
$result = Invoke-DscResource -Name Script -ModuleName $moduleSpecification -Method Test -Property @{TestScript = { Write-Verbose 'test'; return $true }; GetScript = { return @{ } }; SetScript = { return } }
$result | Should -BeTrue -Because "Test method return true"
}
it "Invalid moduleSpecification" -Skip:(!(Test-IsInvokeDscResourceEnable)) {
Set-ItResult -Pending -Because "https://github.com/PowerShell/PSDesiredStateConfiguration/issues/17"
$moduleSpecification = @{ModuleName = 'PsDscResources'; ModuleVersion = '99.99.99.993' }
{
Invoke-DscResource -Name Script -ModuleName $moduleSpecification -Method Test -Property @{TestScript = { Write-Host 'test'; return $true }; GetScript = { return @{ } }; SetScript = { return } } -ErrorAction Stop
} |
Should -Throw -ErrorId 'InvalidResourceSpecification,Invoke-DscResource' -ExpectedMessage 'Invalid Resource Name ''Script'' or module specification.'
}
it "Test an embedded DSC resource" {
if (!(Test-IsInvokeDscResourceEnable)) {
Set-ItResult -Skipped -Because "Feature not enabled"
}
$resourceName="TestRes"
$moduleName="TestEmbeddedDSCResource"
$embObj = @(New-Object -TypeName psobject -Property @{embclassprop="property1"})
Install-ModuleIfMissing -Name $moduleName -Force
$resource = Get-DscResource -Name $resourceName -Module $moduleName -ErrorAction Stop
$resource | Should -Not -BeNullOrEmpty
$resource.Name | Should -Be $resourceName
$methodName="Test"
$result = Invoke-DscResource -Name $resourceName -ModuleName $moduleName -Method $methodName -Property @{embclassobj=$embObj;propName="property1"}
$result.InDesiredState | Should -BeTrue
$result = Invoke-DscResource -Name $resourceName -ModuleName $moduleName -Method $methodName -Property @{embclassobj=$embObj;propName="property2"}
$result.InDesiredState | Should -BeFalse
$methodName="Get"
$result = Invoke-DscResource -Name $resourceName -ModuleName $moduleName -Method $methodName -Property @{embclassobj=$embObj;propName="property1"}
$result.propName | Should -Be "property1"
$result = Invoke-DscResource -Name $resourceName -ModuleName $moduleName -Method $methodName -Property @{embclassobj=$embObj;propName="property2"}
$result.propName | Should -Not -Be "property1"
$methodName="Set"
$result = Invoke-DscResource -Name $resourceName -ModuleName $moduleName -Method $methodName -Property @{embclassobj=$embObj;propName="property1"}
$result | Should -Not -BeNullOrEmpty
$result.RebootRequired | Should -BeFalse
}
it "Using PsDscRunAsCredential should say not supported" -Skip:(!(Test-IsInvokeDscResourceEnable)) {
{
Invoke-DscResource -Name Script -ModuleName PSDscResources -Method Set -Property @{TestScript = { Write-Output 'test'; return $false }; GetScript = { return @{ } }; SetScript = {return}; PsDscRunAsCredential='natoheu'} -ErrorAction Stop
} |
Should -Throw -ErrorId 'PsDscRunAsCredentialNotSupport,Invoke-DscResource'
}
# waiting on Get-DscResource to be fixed
it "Invalid module name" -Skip:(!(Test-IsInvokeDscResourceEnable)) {
Set-ItResult -Pending -Because "https://github.com/PowerShell/PSDesiredStateConfiguration/issues/17"
{
Invoke-DscResource -Name Script -ModuleName santoheusnaasonteuhsantoheu -Method Test -Property @{TestScript = { Write-Host 'test'; return $true }; GetScript = { return @{ } }; SetScript = { return } } -ErrorAction Stop
} |
Should -Throw -ErrorId 'Microsoft.PowerShell.Commands.WriteErrorException,CheckResourceFound'
}
it "Invalid resource name" -Skip:(!(Test-IsInvokeDscResourceEnable)) {
if ($IsWindows) {
Set-ItResult -Pending -Because "https://github.com/PowerShell/PSDesiredStateConfiguration/issues/17"
}
{
Invoke-DscResource -Name santoheusnaasonteuhsantoheu -Method Test -Property @{TestScript = { Write-Host 'test'; return $true }; GetScript = { return @{ } }; SetScript = { return } } -ErrorAction Stop
} |
Should -Throw -ErrorId 'Microsoft.PowerShell.Commands.WriteErrorException,CheckResourceFound'
}
it "Get method should work" -Skip:(!(Test-IsInvokeDscResourceEnable)) {
if ($IsLinux) {
Set-ItResult -Pending -Because "https://github.com/PowerShell/PSDesiredStateConfiguration/issues/12 and https://github.com/PowerShell/PowerShellGet/pull/529"
}
$result = Invoke-DscResource -Name PSModule -ModuleName $psGetModuleSpecification -Method Get -Property @{ Name = 'PsDscResources' }
$result | Should -Not -BeNullOrEmpty
$result.Author | Should -BeLike 'Microsoft*'
$result.InstallationPolicy | Should -BeOfType [string]
$result.Guid | Should -BeOfType [Guid]
$result.Ensure | Should -Be 'Present'
$result.Name | Should -be 'PsDscResources'
$result.Description | Should -BeLike 'This*DSC*'
$result.InstalledVersion | should -BeOfType [Version]
$result.ModuleBase | Should -BeLike '*PSDscResources*'
$result.Repository | should -BeOfType [string]
$result.ModuleType | Should -Be 'Manifest'
}
}
Context "Class Based Resources" { Context "Class Based Resources" {
BeforeAll { BeforeAll {
Install-ModuleIfMissing -Name XmlContentDsc -Force Install-ModuleIfMissing -Name XmlContentDsc -Force
@@ -171,7 +530,7 @@ Describe "Test PSDesiredStateConfiguration" {
$resolvedXmlPath = (Resolve-Path -Path $testXmlPath).ProviderPath $resolvedXmlPath = (Resolve-Path -Path $testXmlPath).ProviderPath
} }
it 'Set method should work' { it 'Set method should work' -Skip:(!(Test-IsInvokeDscResourceEnable)) {
param( param(
$value, $value,
$ExpectedResult $ExpectedResult
@@ -180,263 +539,9 @@ Describe "Test PSDesiredStateConfiguration" {
$testString = '890574209347509120348' $testString = '890574209347509120348'
$result = Invoke-DscResource -Name XmlFileContentResource -ModuleName XmlContentDsc -Property @{Path = $resolvedXmlPath; XPath = '/configuration/appSetting/Test1'; Ensure = 'Present'; Attributes = @{ TestValue2 = $testString; Name = $testString } } -Method Set $result = Invoke-DscResource -Name XmlFileContentResource -ModuleName XmlContentDsc -Property @{Path = $resolvedXmlPath; XPath = '/configuration/appSetting/Test1'; Ensure = 'Present'; Attributes = @{ TestValue2 = $testString; Name = $testString } } -Method Set
$result | Should -Not -BeNullOrEmpty $result | Should -Not -BeNullOrEmpty
$result.GetType() | Should -Be 'InvokeDscResourceSetResult'
$result.RebootRequired | Should -BeFalse $result.RebootRequired | Should -BeFalse
$testXmlPath | Should -FileContentMatch $testString $testXmlPath | Should -FileContentMatch $testString
} }
it 'Get method should work' {
param(
$value,
$ExpectedResult
)
$result = Invoke-DscResource -Name XmlFileContentResource -ModuleName XmlContentDsc -Property @{Path = $resolvedXmlPath; XPath = '/configuration/appSetting/Test1'} -Method Get
$result.GetType() | Should -Be 'XmlFileContentResource'
}
it 'Test method should work' {
param(
$value,
$ExpectedResult
)
$result = Invoke-DscResource -Name XmlFileContentResource -ModuleName XmlContentDsc -Property @{Path = $resolvedXmlPath; XPath = '/configuration/appSetting/Test1'} -Method Test
$result | Should -Not -BeNullOrEmpty
$result.GetType() | Should -Be 'InvokeDscResourceTestResult'
$result.InDesiredState | Should -Not -BeNullOrEmpty
}
} }
} }
} }
Describe "DSC MOF Compilation" {
BeforeAll {
# ensure that module is imported
Import-Module -Name PSDesiredStateConfiguration -MinimumVersion 3.0.0
Install-ModuleIfMissing -Name XmlContentDsc -Force
}
It "Should be able to compile a MOF using configuration keyword" {
Write-Verbose "DSC_HOME: ${env:DSC_HOME}" -Verbose
[Scriptblock]::Create(@"
configuration DSCTestConfig
{
Import-DscResource -ModuleName XmlContentDsc
Node "localhost" {
XmlFileContentResource f1
{
Path = 'testpath'
XPath = '/configuration/appSetting/Test1'
Ensure = 'Absent'
}
}
}
DSCTestConfig -OutputPath TestDrive:\DscTestConfig2
"@) | Should -Not -Throw
"TestDrive:\DscTestConfig2\localhost.mof" | Should -Exist
}
}
Describe "All types DSC resource tests" {
BeforeAll {
Import-Module -Name PSDesiredStateConfiguration -MinimumVersion 3.0.0
$SavedPSModulePath = $env:PSModulePath
$testModulesPath = Join-Path $PSScriptRoot "TestModules"
"TestModulesPath is " + $testModulesPath | Write-Verbose -Verbose
$env:PSModulePath = $testModulesPath + [System.IO.Path]::PathSeparator + $env:PSModulePath
"PSModulePath is " + $env:PSModulePath | Write-Verbose -Verbose
}
AfterAll {
$env:PSModulePath = $SavedPSModulePath
}
It "Check all property types in Get-DscResource" {
$resource = Get-DscResource | ? {$_.Name -eq "xTestClassResource"}
$resource | Should -Not -BeNullOrEmpty
$resource.Properties.Count | Should -Be 34
foreach($dscResourcePropertyInfo in $resource.Properties)
{
switch ($dscResourcePropertyInfo.Name)
{
"Name" {$dscResourcePropertyInfo.PropertyType | Should -Be '[string]'}
"Value" {$dscResourcePropertyInfo.PropertyType | Should -Be '[string]'}
"bValue" {$dscResourcePropertyInfo.PropertyType | Should -Be '[bool]'}
"sArray" {$dscResourcePropertyInfo.PropertyType | Should -Be '[string[]]'}
"bValueArray" {$dscResourcePropertyInfo.PropertyType | Should -Be '[bool[]]'}
"char16Value" {$dscResourcePropertyInfo.PropertyType | Should -Be '[char]'}
"char16ValueArray" {$dscResourcePropertyInfo.PropertyType | Should -Be '[char[]]'}
"dateTimeVal" {$dscResourcePropertyInfo.PropertyType | Should -Be '[DateTime]'}
"dateTimeArrayVal" {$dscResourcePropertyInfo.PropertyType | Should -Be '[DateTime[]]'}
"EmbClassObj" {$dscResourcePropertyInfo.PropertyType | Should -Be '[EmbClass]'}
"EmbClassObjArray" {$dscResourcePropertyInfo.PropertyType | Should -Be '[EmbClass[]]'}
"Ensure" {$dscResourcePropertyInfo.PropertyType | Should -Be '[string]'}
"Real32Value" {$dscResourcePropertyInfo.PropertyType | Should -Be '[Single]'}
"Real32ValueArray" {$dscResourcePropertyInfo.PropertyType | Should -Be '[Single[]]'}
"Real64Value" {$dscResourcePropertyInfo.PropertyType | Should -Be '[double]'}
"Real64ValueArray" {$dscResourcePropertyInfo.PropertyType | Should -Be '[double[]]'}
"sInt8Value" {$dscResourcePropertyInfo.PropertyType | Should -Be '[SByte]'}
"sInt8ValueArray" {$dscResourcePropertyInfo.PropertyType | Should -Be '[SByte[]]'}
"sInt16Value" {$dscResourcePropertyInfo.PropertyType | Should -Be '[Int16]'}
"sInt16ValueArray" {$dscResourcePropertyInfo.PropertyType | Should -Be '[Int16[]]'}
"sInt32Value" {$dscResourcePropertyInfo.PropertyType | Should -Be '[Int32]'}
"sInt32ValueArray" {$dscResourcePropertyInfo.PropertyType | Should -Be '[Int32[]]'}
"sInt64Value" {$dscResourcePropertyInfo.PropertyType | Should -Be '[Int64]'}
"sInt64ValueArray" {$dscResourcePropertyInfo.PropertyType | Should -Be '[Int64[]]'}
"uInt8Value" {$dscResourcePropertyInfo.PropertyType | Should -Be '[Byte]'}
"uInt8ValueArray" {$dscResourcePropertyInfo.PropertyType | Should -Be '[Byte[]]'}
"uInt16Value" {$dscResourcePropertyInfo.PropertyType | Should -Be '[UInt16]'}
"uInt16ValueArray" {$dscResourcePropertyInfo.PropertyType | Should -Be '[UInt16[]]'}
"uInt32Value" {$dscResourcePropertyInfo.PropertyType | Should -Be '[UInt32]'}
"uInt32ValueArray" {$dscResourcePropertyInfo.PropertyType | Should -Be '[UInt32[]]'}
"uInt64Value" {$dscResourcePropertyInfo.PropertyType | Should -Be '[UInt64]'}
"uInt64ValueArray" {$dscResourcePropertyInfo.PropertyType | Should -Be '[UInt64[]]'}
}
}
}
It "Check all property types in Invoke-DscResource" {
$resource = Invoke-DscResource -Name xTestClassResource -ModuleName xTestClassResource -Method Get -Property @{Name="Test"}
$resource | Should -Not -BeNullOrEmpty
$resource.GetType().Name | Should -Be "xTestClassResource"
$resource.Name | Should -Be "Test"
$resource.Value | Should -Be "Inside if"
$resource.Name.GetType().Name | Should -Be "String"
$resource.Value.GetType().Name | Should -Be "String"
$resource.sArray.GetType().Name | Should -Be "String[]"
$resource.bValue.GetType().Name | Should -Be "Boolean"
$resource.bValueArray.GetType().Name | Should -Be "Boolean[]"
$resource.char16Value.GetType().Name | Should -Be "Char"
$resource.char16ValueArray.GetType().Name | Should -Be "Char[]"
$resource.dateTimeVal.GetType().Name | Should -Be "DateTime"
$resource.dateTimeArrayVal.GetType().Name | Should -Be "DateTime[]"
$resource.EmbClassObj.GetType().Name | Should -Be "EmbClass"
$resource.EmbClassObjArray.GetType().Name | Should -Be "EmbClass[]"
$resource.Ensure.GetType().Name | Should -Be "Ensure"
$resource.Real32Value.GetType().Name | Should -Be "Single"
$resource.Real32ValueArray.GetType().Name | Should -Be "Single[]"
$resource.Real64Value.GetType().Name | Should -Be "Double"
$resource.Real64ValueArray.GetType().Name | Should -Be "Double[]"
$resource.sInt8Value.GetType().Name | Should -Be "SByte"
$resource.sInt8ValueArray.GetType().Name | Should -Be "SByte[]"
$resource.sInt16Value.GetType().Name | Should -Be "Int16"
$resource.sInt16ValueArray.GetType().Name | Should -Be "Int16[]"
$resource.sInt32Value.GetType().Name | Should -Be "Int32"
$resource.sInt32ValueArray.GetType().Name | Should -Be "Int32[]"
$resource.sInt64Value.GetType().Name | Should -Be "Int64"
$resource.sInt64ValueArray.GetType().Name | Should -Be "Int64[]"
$resource.uInt8Value.GetType().Name | Should -Be "Byte"
$resource.uInt8ValueArray.GetType().Name | Should -Be "Byte[]"
$resource.uInt16Value.GetType().Name | Should -Be "UInt16"
$resource.uInt16ValueArray.GetType().Name | Should -Be "UInt16[]"
$resource.uInt32Value.GetType().Name | Should -Be "UInt32"
$resource.uInt32ValueArray.GetType().Name | Should -Be "UInt32[]"
$resource.uInt64Value.GetType().Name | Should -Be "UInt64"
$resource.uInt64ValueArray.GetType().Name | Should -Be "UInt64[]"
# extra check for embedded objects
$resource.EmbClassObj.EmbClassStr1 | Should -Be "TestEmbObjValue"
$resource.EmbClassObjArray[0].EmbClassStr1 | Should -Be "TestEmbClassStr1Value"
}
It "Check all property types in configuration compilation" {
[Scriptblock]::Create(@"
configuration DSCAllTypesConfig
{
Import-DscResource -ModuleName xTestClassResource
Node "localhost" {
xTestClassResource f1
{
Name = 'TestName'
Value = 'TestValue'
char16Value = 'A'
char16ValueArray = @('A','B')
sArray = @('Test1','Test2')
bValue = `$true
bValueArray = @(`$true,`$false)
dateTimeVal = Get-Date
dateTimeArrayVal = @(`$(Get-Date), `$(Get-Date))
Ensure = 'Present'
uInt8Value = 255
sInt8Value = -128
uInt16Value = 65535
sInt16Value = -32768
uInt32Value = 4294967295
sInt32Value = -2147483648
uInt64Value = 18446744073709551615
sInt64Value = -9223372036854775808
Real32Value = [Single]-1.234
Real64Value = [Double]-1.234
uInt8ValueArray = @(255)
sInt8ValueArray = @(-128)
uInt16ValueArray = @(65535)
sInt16ValueArray = @(-32768)
uInt32ValueArray = @(4294967295)
sInt32ValueArray = @(-2147483648)
uInt64ValueArray = @(18446744073709551615)
sInt64ValueArray = @(-9223372036854775808)
}
}
}
DSCAllTypesConfig -OutputPath TestDrive:\DSCAllTypesConfig
"@) | Should -Not -Throw
"TestDrive:\DSCAllTypesConfig\localhost.mof" | Should -Exist
Get-Content -Raw -Path "TestDrive:\DSCAllTypesConfig\localhost.mof" | Write-Verbose -Verbose
}
It "Check multi-resource configuration compilation with dependencies" {
[Scriptblock]::Create(@"
configuration MultiResourceConfig
{
Import-DscResource -ModuleName xTestClassResource
ResourceForTests1 r1
{
Prop1 = 'Test'
}
ResourceForTests2 r2
{
Prop1 = 'Test'
DependsOn = '[ResourceForTests1]r1'
}
ResourceForTests3 r3
{
Prop1 = 'Test'
DependsOn = '[ResourceForTests1]r1','[ResourceForTests2]r2'
}
}
MultiResourceConfig -OutputPath TestDrive:\MultiResourceConfig
"@) | Should -Not -Throw
"TestDrive:\MultiResourceConfig\localhost.mof" | Should -Exist
Get-Content -Raw -Path "TestDrive:\MultiResourceConfig\localhost.mof" | Write-Verbose -Verbose
}
}
@@ -1,325 +0,0 @@
enum Ensure
{
Absent
Present
}
class EmbClass
{
[DscProperty()]
[string] $EmbClassStr1
}
[DscResource()]
class xTestClassResource
{
[DscProperty(Key)]
[string]$Name
[DscProperty(Mandatory)]
[string] $Value
[DscProperty()]
[Ensure] $Ensure
[DscProperty()]
[string[]] $sArray
[DscProperty()]
[EmbClass] $EmbClassObj
[DscProperty()]
[EmbClass[]] $EmbClassObjArray
[DscProperty()]
[DateTime] $dateTimeVal;
[DscProperty()]
[DateTime[]] $dateTimeArrayVal;
[DscProperty()]
[Boolean] $bValue;
[DscProperty()]
[Byte] $uInt8Value;
[DscProperty()]
[SByte] $sInt8Value;
[DscProperty()]
[UInt16] $uInt16Value;
[DscProperty()]
[Int16] $sInt16Value;
[DscProperty()]
[UInt32] $uInt32Value;
[DscProperty()]
[Int32] $sInt32Value;
[DscProperty()]
[UInt64] $uInt64Value;
[DscProperty()]
[Int64] $sInt64Value;
[DscProperty()]
[Single] $Real32Value;
[DscProperty()]
[Double] $Real64Value;
[DscProperty()]
[Char] $char16Value;
[DscProperty()]
[Boolean[]] $bValueArray;
[DscProperty()]
[Byte[]] $uInt8ValueArray;
[DscProperty()]
[SByte[]] $sInt8ValueArray;
[DscProperty()]
[UInt16[]] $uInt16ValueArray;
[DscProperty()]
[Int16[]] $sInt16ValueArray;
[DscProperty()]
[UInt32[]] $uInt32ValueArray;
[DscProperty()]
[Int32[]] $sInt32ValueArray;
[DscProperty()]
[UInt64[]] $uInt64ValueArray;
[DscProperty()]
[Int64[]] $sInt64ValueArray;
[DscProperty()]
[single[]] $Real32ValueArray;
[DscProperty()]
[double[]] $Real64ValueArray;
[DscProperty()]
[Char[]] $char16ValueArray;
[void] Set()
{
Set-StrictMode -Version Latest
if ($this.Ensure -eq [Ensure]::Present)
{
if ($this.Value -eq "fail")
{
Write-Error "Ensure=Present failed for $($this.Name) due to value $($this.Value)"
}
}
elseif ($this.Ensure -eq [Ensure]::Absent)
{
if ($this.Value -eq "fail")
{
Write-Error "Ensure=Absent failed for $($this.Name) due to value $($this.Value)"
}
}
}
[bool] Test()
{
Write-Debug "Inside Test()"
Set-StrictMode -Version Latest
[bool] $result = $false
if ($this.value -eq "fail")
{
Write-Error "Failing Test-TargetResource because Value is set to 'fail'"
}
else
{
Write-Verbose "Start of EmbClassObjArray" -Verbose
foreach ($classObj in $this.EmbClassObjArray)
{
$classObj.EmbClassStr1 | write-Verbose -verbose
}
Write-Verbose "End of EmbClassObjArray" -Verbose
Write-Verbose "Ensure: $($this.Ensure)" -verbose
Write-Verbose "sArray: $($this.sArray)" -verbose
Write-Verbose "dateTimeVal: $($this.dateTimeVal)" -verbose
Write-Verbose "dateTimeArrayVal: $($this.dateTimeArrayVal)" -verbose
Write-Verbose "bValue: $($this.bValue)" -verbose
Write-Verbose "uInt8Value: $($this.uInt8Value)" -verbose
Write-Verbose "sInt8Value: $($this.sInt8Value)" -verbose
Write-Verbose "uInt16Value: $($this.uInt16Value)" -verbose
Write-Verbose "sInt16Value: $($this.sInt16Value)" -verbose
Write-Verbose "uInt32Value: $($this.uInt32Value)" -verbose
Write-Verbose "sInt32Value: $($this.sInt32Value)" -verbose
Write-Verbose "uInt64Value: $($this.uInt64Value)" -verbose
Write-Verbose "sInt64Value: $($this.sInt64Value)" -verbose
Write-Verbose "Real32Value: $($this.Real32Value)" -verbose
Write-Verbose "Real64Value: $($this.Real64Value)" -verbose
Write-Verbose "bValueArray: $($this.bValueArray)" -verbose
Write-Verbose "char16Value: $($this.char16Value)" -verbose
Write-Verbose "uInt8ValueArray: $($this.uInt8ValueArray)" -verbose
Write-Verbose "sInt8ValueArray: $($this.sInt8ValueArray)" -verbose
Write-Verbose "uInt16ValueArray: $($this.uInt16ValueArray)" -verbose
Write-Verbose "sInt16ValueArray: $($this.sInt16ValueArray)" -verbose
Write-Verbose "uInt32ValueArray: $($this.uInt32ValueArray)" -verbose
Write-Verbose "sInt32ValueArray: $($this.sInt32ValueArray)" -verbose
Write-Verbose "uInt64ValueArray: $($this.uInt64ValueArray)" -verbose
Write-Verbose "sInt64ValueArray: $($this.sInt64ValueArray)" -verbose
Write-Verbose "Real32ValueArray: $($this.Real32ValueArray)" -verbose
Write-Verbose "Real64ValueArray: $($this.Real64ValueArray)" -verbose
Write-Verbose "char16ValueArray: $($this.char16ValueArray)" -verbose
[Single]$f = -1.000003
[double]$d = -1.234
$result = ($this.EmbClassObjArray[1].EmbClassStr1 -eq $this.Ensure) -and `
($this.sArray[1] -eq "s2") -and `
($this.dateTimeVal -lt (get-date 2020-12-12)) -and `
($this.dateTimeArrayVal[1] -gt (get-date 2020-08-20)) -and `
($this.bValue -eq $true) -and `
($this.uInt8Value -eq 255) -and `
($this.sInt8Value -eq -128) -and `
($this.uInt16Value -eq 65535) -and `
($this.sInt16Value -eq -32768) -and `
($this.uInt32Value -eq 4294967295) -and `
($this.sInt32Value -eq -2147483648) -and `
($this.uInt64Value -eq 18446744073709551615) -and `
($this.sInt64Value -eq -9223372036854775808) -and `
($this.Real32Value -eq $f) -and `
($this.Real64Value -eq $d) -and `
($this.bValueArray[1] -eq $true) -and `
($this.char16Value -eq 'c') -and `
($this.uInt8ValueArray[1] -eq 254) -and `
($this.sInt8ValueArray[1] -eq -127) -and `
($this.uInt16ValueArray[1] -eq 65534) -and `
($this.sInt16ValueArray[1] -eq -32767) -and `
($this.uInt32ValueArray[1] -eq 4294967294) -and `
($this.sInt32ValueArray[1] -eq -2147483647) -and `
($this.uInt64ValueArray[1] -eq 18446744073709551614) -and `
($this.sInt64ValueArray[1] -eq -9223372036854775807) -and `
($this.Real32ValueArray[1] -eq $f) -and `
($this.Real64ValueArray[1] -eq $d) -and `
($this.char16ValueArray[1] -eq 'd')
}
return $result
}
[xTestClassResource] Get()
{
Write-Debug "Inside Get()"
if ($this.Value -ne "fail")
{
$this.Value = "Inside if"
}
else
{
$this.Value = "Inside else"
}
# initialize properties so that they are not null
$this.char16Value = "A"
$this.sArray = [String[]]::new(0)
$this.EmbClassObj = [EmbClass]::new()
$this.EmbClassObj.EmbClassStr1 = "TestEmbObjValue"
$EmbObj = [EmbClass]::new()
$EmbObj.EmbClassStr1 = "TestEmbClassStr1Value"
$this.EmbClassObjArray = [EmbClass[]]::new(1)
$this.EmbClassObjArray[0] = $EmbObj
$this.dateTimeVal = [DateTime]::Now
$this.dateTimeArrayVal = [DateTime[]]::new(0)
$this.bValueArray = [Boolean[]]::new(0)
$this.char16ValueArray = [Char[]]::new(0)
$this.uInt8ValueArray = [Byte[]]::new(0)
$this.sInt8ValueArray = [SByte[]]::new(0)
$this.uInt16ValueArray = [UInt16[]]::new(0)
$this.sInt16ValueArray = [Int16[]]::new(0)
$this.uInt32ValueArray = [UInt32[]]::new(0)
$this.sInt32ValueArray = [Int32[]]::new(0)
$this.uInt64ValueArray = [UInt64[]]::new(0)
$this.sInt64ValueArray = [Int64[]]::new(0)
$this.Real32ValueArray = [single[]]::new(0)
$this.Real64ValueArray = [double[]]::new(0)
return $this
}
}
[DscResource()]
class ResourceForTests1
{
[DscProperty(Key)]
[string] $Prop1
[void] Set()
{
}
[bool] Test()
{
return $true
}
[ResourceForTests1] Get()
{
return $this
}
}
[DscResource()]
class ResourceForTests2
{
[DscProperty(Key)]
[string] $Prop1
[void] Set()
{
}
[bool] Test()
{
return $true
}
[ResourceForTests2] Get()
{
return $this
}
}
[DscResource()]
class ResourceForTests3
{
[DscProperty(Key)]
[string] $Prop1
[void] Set()
{
}
[bool] Test()
{
return $true
}
[ResourceForTests3] Get()
{
return $this
}
}
+38
View File
@@ -0,0 +1,38 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
Describe "DSC MOF Compilation" -tags "CI" {
BeforeAll {
$module = Get-Module PowerShellGet -ListAvailable | Sort-Object -Property Version -Descending | Select-Object -First 1
$psGetModuleVersion = $module.Version.ToString()
if (!$env:DSC_HOME)
{
Import-Module PSDesiredStateConfiguration
}
}
It "Should be able to compile a MOF using PSModule resource" {
if ($IsLinux) {
Set-ItResult -Pending -Because "https://github.com/PowerShell/PowerShellGet/pull/529"
}
Write-Verbose "DSC_HOME: ${env:DSC_HOME}" -verbose
[Scriptblock]::Create(@"
configuration DSCTestConfig
{
Import-DscResource -ModuleName PowerShellGet -ModuleVersion $psGetModuleVersion
Node "localhost" {
PSModule f1
{
Name = 'PsDscResources'
InstallationPolicy = 'Trusted'
}
}
}
DSCTestConfig -OutputPath TestDrive:\DscTestConfig2
"@) | Should -Not -Throw
"TestDrive:\DscTestConfig2\localhost.mof" | Should -Exist
}
}
+7
View File
@@ -0,0 +1,7 @@
&$PSScriptRoot/build.ps1 -Build -Clean
Write-Verbose -Message "Updating signing.xml ..." -Verbose
$files = @(Get-ChildItem $PSScriptRoot/out/*.ps* -Recurse | Select-Object -ExpandProperty FullName)
&$PSScriptRoot/tools/releaseBuild/generatePackgeSigning.ps1 -AuthenticodeFiles $files -path $PSScriptRoot/tools/releaseBuild/signing.xml -rootPath $PSScriptRoot/out/
Write-Verbose -Message "Done ..." -Verbose
# Make sure the file ends with an empty line
Add-Content -value '' -Path $PSScriptRoot/tools/releaseBuild/signing.xml