Compare commits

..

21 Commits

Author SHA1 Message Date
Andy Jordan f665242c1b Move installation of test modules to bootstrapping (#132)
So we can get this working on OneBranch.
2026-02-19 18:14:20 -08:00
Andy Jordan 8d7e4303d3 Update build and release pipeline (#131) 2026-02-19 17:00:39 -08:00
Steve Lee 820ac1a06e Update to v2.0.8 and backport two fixes (#130) 2025-12-04 13:13:30 -08:00
Andrew 79d47ceed9 Fixed Invoke-DscResource error when a class-based resource module path contains a space (#112) 2023-05-13 11:34:20 -07:00
Andrew 727085ecaa Fixed link in v2 changelog 2023-02-27 13:53:37 -08:00
Andrew a935614790 Added v2 changelog 2023-02-27 13:48:07 -08:00
Andrew 7c063aed9d Updated Sbom task parameters 2023-02-24 11:39:47 -08:00
Andrew b83ba2ccc0 Updated EsrpSign parameters 2023-02-24 10:28:36 -08:00
Andrew 316773dfe6 release pipeline - updated machine pool 2023-02-23 20:46:55 -08:00
Andrew 11b3bd0fdb Updated version to v2.0.6 2023-02-23 20:35:27 -08:00
Andrew 4af8841d74 Added SBOM generation and changed image to PSMMS2019-Secure (#69) 2023-02-23 20:32:43 -08:00
Andrew ad361bfe4b Update release pipeline for 1ES (#61) 2023-02-23 20:32:26 -08:00
Andrew 08b5f4de0e Release pipeline updates for 1ES (#63) 2023-02-23 20:31:17 -08:00
Andrew f142525bc7 Updated version to v2.0.6 2023-02-23 20:00:37 -08:00
Andrew a9182cf60e Add ImplementationDetail member only when the member does not already exist 2023-02-23 19:59:36 -08:00
Andrew 68cfed18c9 Remove duplicate result resources from Get-DSCResourcesModules 2023-02-23 19:54:34 -08:00
Steve Lee 3ae4b6afda Change ErrorAction to Ignore so that the error doesn't show up in $Error (#93) 2023-02-23 19:51:42 -08:00
Andrew 4777a3ed77 Remove PSDesiredStateConfiguration.InvokeDscResource experimental feature. (#52) 2023-02-23 19:49:35 -08:00
Andrew 85eeda51a6 Updating CI and Release pipelines with latest Compliance (#43) 2023-02-23 19:40:46 -08:00
bagajjal 70dad1f41e support embedded resource (#38) 2023-02-23 19:37:28 -08:00
Travis Plunk 1cb7076792 Fix CI issues (#40) 2023-02-23 19:36:28 -08:00
39 changed files with 1121 additions and 5734 deletions
+10
View File
@@ -0,0 +1,10 @@
{
"instanceUrl": "https://msazure.visualstudio.com",
"projectName": "One",
"areaPath": "One\\MGMT\\Compute\\Powershell\\Powershell\\PowerShell Core",
"notificationAliases": [
"andschwa@microsoft.com",
"slee@microsoft.com"
],
"codebaseName": "PSDSC_202502"
}
-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
+45
View File
@@ -0,0 +1,45 @@
name: CI Tests
on:
push:
branches: [ v2 ]
pull_request:
branches: [ v2 ]
jobs:
ci:
name: pester
runs-on: windows-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install PSResources
run: ./tools/installPSResources.ps1
shell: pwsh
- name: Build
run: ./build.ps1 -Build
shell: pwsh
- name: Test
run: ./build.ps1 -Test
shell: pwsh
- name: Package
run: ./build.ps1 -Publish
shell: pwsh
- name: Upload build artifacts
uses: actions/upload-artifact@v4
if: always()
with:
name: PSDesiredStateConfiguration-package
path: out/**/*.nupkg
- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: PSDesiredStateConfiguration-tests
path: out/testResults.xml
@@ -0,0 +1,155 @@
trigger:
- main
schedules:
- cron: '18 11 * * 5'
displayName: Weekly CodeQL
branches:
include:
- main
always: true
parameters:
- name: debug
displayName: Enable debug output
type: boolean
default: false
- name: OfficialBuild
displayName: Use Official OneBranch template
type: boolean
default: true
- name: Release
displayName: Generate a release
type: boolean
default: false
variables:
system.debug: ${{ parameters.debug }}
BuildConfiguration: Release
WindowsContainerImage: onebranch.azurecr.io/windows/ltsc2022/vse2022:latest
OneBranchTemplate: ${{ iif(parameters.OfficialBuild, 'v2/OneBranch.Official.CrossPlat.yml@templates', 'v2/OneBranch.NonOfficial.CrossPlat.yml@templates') }}
resources:
repositories:
- repository: templates
type: git
name: OneBranch.Pipelines/GovernedTemplates
ref: refs/heads/main
extends:
# https://aka.ms/obpipelines/templates
template: ${{ variables.OneBranchTemplate }}
parameters:
globalSdl: # https://aka.ms/obpipelines/sdl
asyncSdl:
enabled: true
forStages: [build]
featureFlags:
EnableCDPxPAT: false
WindowsHostVersion:
Version: 2022
Network: KS3
release:
category: NonAzure
stages:
- stage: build
jobs:
- job: main
displayName: Build package
pool:
type: windows
variables:
ob_outputDirectory: $(Build.SourcesDirectory)/out
steps:
- pwsh: |
$manifest = Import-PowerShellDataFile ./src/PSDesiredStateConfiguration/PSDesiredStateConfiguration.psd1
$version = $manifest.ModuleVersion
Write-Output "##vso[task.setvariable variable=version;isOutput=true]$version"
name: package
displayName: Get version from module manifest
- task: onebranch.pipeline.version@1
displayName: Set OneBranch version
inputs:
system: Custom
customVersion: $(package.version)
- pwsh: ./tools/installPSResources.ps1 -PSRepository CFS
displayName: Install PSResources
- pwsh: ./build.ps1 -Clean -Build -Test
displayName: Build
- task: onebranch.pipeline.signing@1
displayName: Sign 1st-party files
inputs:
command: sign
signing_profile: external_distribution
search_root: $(Build.SourcesDirectory)/out
files_to_sign: |
**/*.psd1;
**/*.psm1;
- pwsh: ./build.ps1 -Publish
displayName: Package module
- task: onebranch.pipeline.signing@1
displayName: Sign NuGet package
inputs:
command: sign
signing_profile: external_distribution
search_root: $(Build.SourcesDirectory)/out
files_to_sign: |
*.nupkg
- stage: release
dependsOn: build
condition: and(succeeded(), ${{ eq(parameters.Release, true) }})
variables:
ob_release_environment: ${{ iif(parameters.OfficialBuild, 'Production', 'Test') }}
version: $[ stageDependencies.build.main.outputs['package.version'] ]
jobs:
- job: github
displayName: Publish draft to GitHub
pool:
type: release
templateContext:
inputs:
- input: pipelineArtifact
artifactName: drop_build_main
steps:
- task: GitHubRelease@1
displayName: Create GitHub release
inputs:
gitHubConnection: GitHub
repositoryName: PowerShell/PSDesiredStateConfiguration
target: main
assets: $(Pipeline.Workspace)/PSDesiredStateConfiguration.$(version).nupkg
tagSource: userSpecifiedTag
tag: $(version)
isDraft: true
addChangeLog: false
releaseNotesSource: inline
releaseNotesInline: "<!-- TODO: Generate release notes on GitHub! -->"
- job: validation
displayName: Manual validation
pool:
type: server
timeoutInMinutes: 1440
steps:
- task: ManualValidation@0
displayName: Wait 24 hours for validation
inputs:
notifyUsers: $(Build.RequestedForEmail)
instructions: Please validate the release and then publish it!
timeoutInMinutes: 1440
- job: publish
dependsOn: validation
displayName: Publish to PowerShell Gallery
pool:
type: release
templateContext:
inputs:
- input: pipelineArtifact
artifactName: drop_build_main
steps:
- task: NuGetCommand@2
displayName: Publish module to PowerShell Gallery
inputs:
command: push
packagesToPush: $(Pipeline.Workspace)/PSDesiredStateConfiguration.$(version).nupkg
nuGetFeedType: external
publishFeedCredentials: PowerShellGallery
-151
View File
@@ -1,151 +0,0 @@
name: Build-$(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:
repositories:
- repository: ComplianceRepo
type: github
endpoint: ComplianceGHRepo
name: PowerShell/compliance
stages:
- stage: Build
displayName: Build PSDesiredStateConfiguration module
pool:
vmImage: windows-latest
jobs:
- job: BuildPkg
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:
vmImage: windows-latest
steps:
- checkout: self
- checkout: ComplianceRepo
- download: current
artifact: Build
- pwsh: |
Get-ChildItem -Path "$(Pipeline.Workspace)\Build" -Recurse
displayName: Capture downloaded artifacts
- template: ci-compliance.yml@ComplianceRepo
parameters:
# component-governance
sourceScanPath: '$(Pipeline.Workspace)\Build'
# credscan
suppressionsFile: ''
# TermCheck
optionsRulesDBPath: ''
optionsFTPath: ''
# tsa-upload
codeBaseName: 'PSDesiredStateConfiguration_20210423'
# selections
APIScan: false # set to false when not using Windows APIs.
- stage: Test
displayName: Test Package
dependsOn: Build
jobs:
- template: templates/ci-test.yml
parameters:
jobName: TestPkgWin
displayName: PowerShell Core on Windows
imageName: windows-latest
- template: templates/ci-test.yml
parameters:
jobName: TestPkgUbuntu
displayName: PowerShell Core on Ubuntu
imageName: ubuntu-latest
- template: templates/ci-test.yml
parameters:
jobName: TestPkgWinMacOS
displayName: PowerShell Core on macOS
imageName: macOS-latest
-213
View File
@@ -1,213 +0,0 @@
name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)
trigger: none
resources:
repositories:
- repository: ComplianceRepo
type: github
endpoint: ComplianceGHRepo
name: PowerShell/compliance
variables:
- name: PackageName
value: 'PSDesiredStateConfiguration'
- name: PackageVersion
value: '3.0.0'
stages:
- stage: Build
displayName: Build PSDesiredStateConfiguration module
pool:
name: 1ES
demands:
- ImageOverride -equals PSMMS2019-Secure
jobs:
- job: BuildPkg
displayName: Build Package
variables:
- group: ESRP
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 -Preview -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'
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
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'
-74
View File
@@ -1,74 +0,0 @@
parameters:
jobName: TestPkgWin
imageName: windows-2019
displayName: PowerShell Core on Windows
powershellExecutable: pwsh
jobs:
- job: ${{ parameters.jobName }}
pool:
vmImage: ${{ parameters.imageName }}
displayName: ${{ parameters.displayName }}
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 -Preview -Destination $powerShellPath
$newPath = $powerShellPath + [System.IO.Path]::PathSeparator + $env:PATH
$vstsCommandString = "vso[task.setvariable variable=PATH]$newPath"
Write-Host "sending " + $vstsCommandString
Write-Host "##$vstsCommandString"
displayName: Install PowerShell Core
- 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
#
$vstsCommandString = "vso[task.setvariable variable=modulePath]${modulePath}"
Write-Host "sending " + $vstsCommandString
Write-Host "##$vstsCommandString"
displayName: Install PSPackageProject and dependencies
- download: current
artifact: Build
- pwsh: |
"PSVersionTable is"| Write-Verbose -Verbose
$PSVersionTable | Out-String | Write-Verbose -Verbose
#
$targetModuleLocation = Join-Path -Path $(modulePath) -ChildPath 'PSDesiredStateConfiguration'
Move-Item -Path "$(Pipeline.Workspace)\Build" -Destination $targetModuleLocation -Force
#
$env:PSModulePath = '$(modulePath)' + [System.IO.Path]::PathSeparator + $env:PSModulePath
"PSModulePath is"| Write-Verbose -Verbose
$env:PSModulePath | Write-Verbose -Verbose
#
Get-Module -ListAvailable -Name PSDesiredStateConfiguration | select Name,Version,PreRelease,Path | Write-Verbose -Verbose
#
"Listing contents of $targetModuleLocation"| Write-Verbose -Verbose
Get-ChildItem -Recurse -Path $targetModuleLocation | Write-Verbose -Verbose
#
Invoke-PSPackageProjectTest -Type Functional
displayName: Execute functional tests
errorActionPreference: continue
+13
View File
@@ -1,5 +1,18 @@
# v2 Changelog # v2 Changelog
## [v2.0.8]
- Fixed an issue with array parameters is key-value pairs (#128).
- ConvertTo-MOFInstance: Include resource properties with empty array value (#127)
## [v2.0.7]
### Main changes
- Fixed Invoke-DscResource error when a class-based resource module path contains a space.
[v2.0.7]: https://www.powershellgallery.com/packages/PSDesiredStateConfiguration/2.0.7
## [v2.0.6] ## [v2.0.6]
### Main changes ### Main changes
+2 -2
View File
@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2022 PowerShell Team Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. 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.
+40 -57
View File
@@ -1,7 +1,6 @@
# Copyright (c) Microsoft Corporation. All rights reserved. # Copyright (c) Microsoft Corporation.
# Licensed under the MIT License. # Licensed under the MIT License.
# Do NOT edit this file. Edit dobuild.ps1
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingWriteHost", "")] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingWriteHost", "")]
param ( param (
[Parameter(ParameterSetName="build")] [Parameter(ParameterSetName="build")]
@@ -15,9 +14,6 @@ param (
[Parameter(ParameterSetName="publish")] [Parameter(ParameterSetName="publish")]
[switch] [switch]
$Publish, $Publish,
[Parameter(ParameterSetName="publish")]
[switch]
$Signed,
[Parameter(ParameterSetName="build")] [Parameter(ParameterSetName="build")]
[switch] [switch]
@@ -37,34 +33,15 @@ param (
$TestInvokeDscResource $TestInvokeDscResource
) )
$config = Get-PSPackageProjectConfiguration -ConfigPath $PSScriptRoot # Build configuration
$script:ModuleName = "PSDesiredStateConfiguration"
$script:ModuleName = $config.ModuleName $script:SrcPath = Join-Path (Join-Path $PSScriptRoot "src") $ModuleName
$script:SrcPath = $config.SourcePath $script:OutDirectory = Join-Path $PSScriptRoot "out"
$script:OutDirectory = $config.BuildOutputPath $script:Culture = "en-US"
$script:SignedDirectory = $config.SignedOutputPath $script:HelpPath = Join-Path $PSScriptRoot "help"
$script:TestPath = $config.TestPath
$script:ModuleRoot = $PSScriptRoot
$script:Culture = $config.Culture
$script:HelpPath = $config.HelpPath
if ($env:TF_BUILD) {
$vstsCommandString = "vso[task.setvariable variable=BUILD_OUTPUT_PATH]$OutDirectory"
Write-Host ("sending " + $vstsCommandString)
Write-Host "##$vstsCommandString"
$vstsCommandString = "vso[task.setvariable variable=SIGNED_OUTPUT_PATH]$SignedDirectory"
Write-Host ("sending " + $vstsCommandString)
Write-Host "##$vstsCommandString"
}
. $PSScriptRoot\dobuild.ps1 . $PSScriptRoot\dobuild.ps1
if ( ! ( Get-Module -ErrorAction SilentlyContinue PSPackageProject) ) {
Install-Module PSPackageProject
}
if ($Clean -and (Test-Path $OutDirectory)) if ($Clean -and (Test-Path $OutDirectory))
{ {
Remove-Item -Force -Recurse $OutDirectory -ErrorAction Stop -Verbose Remove-Item -Force -Recurse $OutDirectory -ErrorAction Stop -Verbose
@@ -81,42 +58,48 @@ else
if ($Build.IsPresent) if ($Build.IsPresent)
{ {
$sb = (Get-Item Function:DoBuild).ScriptBlock DoBuild
Invoke-PSPackageProjectBuild -BuildScript $sb -SkipPublish
} }
if ($Publish.IsPresent) if ($Publish.IsPresent)
{ {
Invoke-PSPackageProjectPublish -Signed:$Signed.IsPresent DoPackage
} }
if ( $TestInvokeDscResource.IsPresent ) { if ($Test.IsPresent) {
$backupName = $null Import-Module Pester -MinimumVersion 5.0.0
try { Import-Module $PSScriptRoot\out\PSDesiredStateConfiguration\PSDesiredStateConfiguration.psd1
$configFolder = split-path $PROFILE
$configPath = Join-Path $configFolder -ChildPath powershell.config.json
if(Test-Path ~/.config/powershell/powershell.config.json)
{
$backupName = Join-Path $configFolder -ChildPath "powershell.config-((Get-Date).ToString('yyyyMMddHHmm')).json"
Copy-Item $configPath $backupName -force
}
copy-Item $PSScriptRoot/assets/powershell.config.json $configPath $testPath = Join-Path $PSScriptRoot "test"
Invoke-PSPackageProjectTest -Type $TestType $config = [PesterConfiguration]::Default
} $config.Run.Path = $testPath
finally { $config.Run.Exit = $false
remove-item $configPath $config.TestResult.Enabled = $true
if($backupName) $config.TestResult.OutputPath = Join-Path $OutDirectory "testResults.xml"
{ $config.Output.Verbosity = "Detailed"
Copy-Item $backupName $configPath -force
}
}
}
if ( $Test.IsPresent ) { Write-Verbose -Verbose "Running tests from: $testPath"
Invoke-PSPackageProjectTest -Type $TestType $result = Invoke-Pester -Configuration $config
if ($result.FailedCount -gt 0) {
throw "$($result.FailedCount) test(s) failed"
}
} }
if ($UpdateHelp.IsPresent) { if ($UpdateHelp.IsPresent) {
Add-PSPackageProjectCmdletHelp -ProjectRoot $ModuleRoot -ModuleName $ModuleName -Culture $Culture # Build help using platyPS
$docsPath = Join-Path $PSScriptRoot "help"
$markdownDocsPath = Join-Path $docsPath "en-US"
$outputDocsPath = Join-Path $OutModule "en-US"
if (-not (Get-Module -ListAvailable platyPS)) {
Write-Verbose -Verbose "platyPS module not found, installing"
Install-Module -Force -Name platyPS -Scope CurrentUser
}
Import-Module platyPS -Verbose:$false
if (-not (Test-Path $outputDocsPath)) {
$null = New-Item -Type Directory -Path $outputDocsPath -Force
}
$null = New-ExternalHelp -Path $markdownDocsPath -OutputPath $outputDocsPath -Force
} }
+21 -48
View File
@@ -1,54 +1,27 @@
# Copyright (c) Microsoft Corporation. All rights reserved. # Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. # Licensed under the MIT License.
#####################################################
# Do NOT edit anything outside the DoBuild function.
# You can define functions inside the scope of DoBuild.
#####################################################
<#
.DESCRIPTION
Implement build and packaging of the package and place the output $OutDirectory/$ModuleName
#>
function DoBuild function DoBuild
{ {
Write-Verbose -Verbose -Message "Starting DoBuild" Write-Verbose -Verbose -Message "Running DoBuild to layout module at: '${OutDirectory}/${ModuleName}'"
Write-Verbose -Verbose -Message "Make sure that 'nuget' and 'dotnet' are visible through PATH" Copy-Item "${SrcPath}/*" "${OutDirectory}/${ModuleName}" -Recurse
Copy-Item -Recurse "${HelpPath}/${Culture}" "${OutDirectory}/${ModuleName}"
Write-Verbose -Verbose -Message "Copying module files to '${OutDirectory}/${ModuleName}'" }
# copy psm1 and psd1 files
copy-item "${SrcPath}/*" "${OutDirectory}/${ModuleName}" -Recurse function DoPackage
{
$smaPackageVersionToUse = "7.2.0-preview.6" # 7.2.0-preview.6 - is the first SMA version that has DSC subsystem changes try {
$subsystemCodePath = Resolve-Path "${SrcPath}/../DscSubsystem" $repoName = [guid]::NewGuid().ToString()
Write-Verbose -Verbose -Message "Subsystem code path ${subsystemCodePath}" $modulePath = Join-Path $OutDirectory $ModuleName
$null = Register-PSRepository -Name $repoName -InstallationPolicy Trusted -SourceLocation $OutDirectory
if ( Test-Path $subsystemCodePath )
{ Write-Verbose -Verbose -Message "Publishing module from: '$modulePath'"
Write-Verbose -Verbose -Message "Building assembly and copying to '${OutDirectory}/${ModuleName}'" Publish-Module -Path $modulePath -Repository $repoName
Push-Location $subsystemCodePath $nupkgPath = (Get-ChildItem -Path $OutDirectory -Filter "$ModuleName*.nupkg" | Select-Object -First 1).FullName
Write-Verbose -Verbose -Message "Created package: $nupkgPath"
$PackageReferencesPath = Join-Path $subsystemCodePath "PackageReferences" }
finally {
nuget install System.Management.Automation -OutputDirectory ./PackageReferences -PreRelease -Version $smaPackageVersionToUse -DependencyVersion Ignore -ExcludeVersion Unregister-PSRepository -Name $repoName
dotnet publish }
$subsystemBinPath = Join-Path (Get-ChildItem -Recurse "publish" -Directory) "Microsoft.PowerShell.DscSubsystem.dll"
if (Test-Path $subsystemBinPath)
{
Copy-Item $subsystemBinPath "${OutDirectory}/${ModuleName}"
}
else
{
Write-Error -Message "dotnet build failed - $subsystemBinPath not found"
}
Pop-Location
}
else {
Write-Error -Message "No code to build in '$subsystemCodePath'"
}
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>
-9
View File
@@ -1,9 +0,0 @@
{
"HelpPath": "help",
"ModuleName": "PSDesiredStateConfiguration",
"BuildOutputPath": "out",
"SignedOutputPath": "signed",
"SourcePath": "src/PSDesiredStateConfiguration",
"TestPath": "test",
"Culture": "en-US"
}
-89
View File
@@ -1,89 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#nullable enable
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Management.Automation;
using System.Management.Automation.Internal;
using System.Management.Automation.Language;
namespace System.Management.Automation.Subsystem.DSC
{
/// <summary>
/// Interface for implementing a cross platform desired state configuration component.
/// </summary>
public class CrossPlatformDsc : ICrossPlatformDsc, IModuleAssemblyInitializer
{
/// <summary>
/// Gets the unique identifier for a subsystem implementation.
/// </summary>
public Guid Id { get {return Guid.NewGuid();} }
/// <summary>
/// Gets the name of a subsystem implementation.
/// </summary>
public string Name { get {return "Cross platform desired state configuration";} }
/// <summary>
/// Gets the description of a subsystem implementation.
/// </summary>
public string Description { get {return "Cross platform desired state configuration";} }
/// <summary>
/// Gets a dictionary that contains the functions to be defined at the global scope of a PowerShell session.
/// Key: function name; Value: function script.
/// </summary>
Dictionary<string, string>? ISubsystem.FunctionsToDefine => null;
/// <summary>
/// Test.
/// </summary>
public void LoadDefaultKeywords(Collection<Exception> errors)
{
Microsoft.PowerShell.DesiredStateConfiguration.Internal.CrossPlatform.DscClassCache.LoadDefaultCimKeywords(errors);
}
/// <summary>
/// Default summary.
/// </summary>
public void ClearCache()
{
Microsoft.PowerShell.DesiredStateConfiguration.Internal.CrossPlatform.DscClassCache.ClearCache();
}
/// <summary>
/// Default summary.
/// </summary>
public string GetDSCResourceUsageString(DynamicKeyword keyword)
{
return Microsoft.PowerShell.DesiredStateConfiguration.Internal.CrossPlatform.DscClassCache.GetDSCResourceUsageString(keyword);
}
/// <summary>
/// Checks if a string is one of dynamic keywords that can be used in both configuration and meta configuration.
/// </summary>
public bool IsSystemResourceName(string name)
{
return Microsoft.PowerShell.DesiredStateConfiguration.Internal.CrossPlatform.DscClassCache.SystemResourceNames.Contains(name);
}
/// <summary>
/// Checks if a string matches default module name used for meta configuration resources.
/// </summary>
public bool IsDefaultModuleNameForMetaConfigResource(string name)
{
return name.Equals(Microsoft.PowerShell.DesiredStateConfiguration.Internal.CrossPlatform.DscClassCache.DefaultModuleInfoForMetaConfigResource.Item1, StringComparison.OrdinalIgnoreCase);
}
public void OnImport()
{
if (SubsystemManager.GetSubsystem<ICrossPlatformDsc>() == null)
{
SubsystemManager.RegisterSubsystem(SubsystemKind.CrossPlatformDsc, this);
}
}
}
}
-68
View File
@@ -1,68 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Management.Automation;
using System.Security;
namespace Microsoft.PowerShell.DesiredStateConfiguration.Internal.CrossPlatform
{
/// <summary>
/// Class that does high level Cim schema parsing.
/// </summary>
internal class CimDSCParser
{
private readonly JsonDeserializer _jsonDeserializer;
internal CimDSCParser()
{
_jsonDeserializer = JsonDeserializer.Create();
}
internal IEnumerable<PSObject> ParseSchemaJson(string filePath, bool useNewRunspace = false)
{
try
{
string json = File.ReadAllText(filePath);
string fileNameDefiningClass = Path.GetFileNameWithoutExtension(filePath);
int dotIndex = fileNameDefiningClass.IndexOf(".schema", StringComparison.InvariantCultureIgnoreCase);
if (dotIndex != -1)
{
fileNameDefiningClass = fileNameDefiningClass.Substring(0, dotIndex);
}
IEnumerable<PSObject> result = _jsonDeserializer.DeserializeClasses(json, useNewRunspace);
foreach (dynamic classObject in result)
{
string superClassName = classObject.SuperClassName;
string className = classObject.ClassName;
if (string.Equals(superClassName, "OMI_BaseResource", StringComparison.OrdinalIgnoreCase))
{
// Get the name of the file without schema.mof/json extension
if (!className.Equals(fileNameDefiningClass, StringComparison.OrdinalIgnoreCase))
{
PSInvalidOperationException e = PSTraceSource.NewInvalidOperationException(
ParserStrings.ClassNameNotSameAsDefiningFile, className, fileNameDefiningClass);
throw e;
}
}
}
return result;
}
catch (Exception exception)
{
PSInvalidOperationException e = PSTraceSource.NewInvalidOperationException(
exception, ParserStrings.CimDeserializationError, filePath);
e.SetErrorId("CimDeserializationError");
throw e;
}
}
}
}
-72
View File
@@ -1,72 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
namespace Microsoft.PowerShell.DesiredStateConfiguration.Internal.CrossPlatform
{
internal class JsonDeserializer
{
#region Constructors
/// <summary>
/// Instantiates a default deserializer.
/// </summary>
/// <returns>Default deserializer.</returns>
public static JsonDeserializer Create()
{
return new JsonDeserializer();
}
#endregion Constructors
#region Methods
/// <summary>
/// Returns schema of Cim classes from specified json file.
/// </summary>
/// <param name="json">Json text to deserialize.</param>
/// <param name="useNewRunspace">If a new runspace should be used.</param>
/// <returns>Deserialized PSObjects.</returns>
public IEnumerable<PSObject> DeserializeClasses(string json, bool useNewRunspace = false)
{
if (string.IsNullOrEmpty(json))
{
throw new ArgumentNullException(nameof(json));
}
System.Management.Automation.PowerShell powerShell = null;
if (useNewRunspace)
{
// currently using RunspaceMode.NewRunspace will reset PSModulePath env var for the entire process
// this is something we want to avoid in DSC GuestConfigAgent scenario, so we use following workaround
var s_iss = InitialSessionState.CreateDefault();
s_iss.EnvironmentVariables.Add(
new SessionStateVariableEntry(
"PSModulePath",
Environment.GetEnvironmentVariable("PSModulePath"),
description: null));
powerShell = System.Management.Automation.PowerShell.Create(s_iss);
}
else
{
powerShell = System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace);
}
using (powerShell)
{
return powerShell.AddCommand("Microsoft.PowerShell.Utility\\ConvertFrom-Json")
.AddParameter("InputObject", json)
.AddParameter("Depth", 100) // maximum supported by cmdlet
.Invoke();
}
}
#endregion Methods
}
}
File diff suppressed because it is too large Load Diff
@@ -1,20 +0,0 @@
<!-- USE "./build.ps1 -Build" TO BUILD THIS -->
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<PlatformTarget>AnyCPU</PlatformTarget>
<AssemblyName>Microsoft.PowerShell.DscSubsystem</AssemblyName>
<!-- Assembly is fully signed in \.vsts-ci\azure-pipelines-release.yml -->
<DelaySign>true</DelaySign>
<AssemblyOriginatorKeyFile>visualstudiopublic.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
</PropertyGroup>
<ItemGroup>
<!-- Can't use PackageReference here because subsystem uses internal SMA types that are not available in `ref` version of the SMA package.
So a workaround is to download SMA package and reference local file (full runtime SMA assembly) in `runtimes` folder. -->
<Reference Include="PackageReferences/System.Management.Automation/runtimes/win/lib/net6.0/System.Management.Automation.dll"></Reference>
</ItemGroup>
</Project>
Binary file not shown.
@@ -1,232 +0,0 @@
[
{
"ClassName": "MSFT_Credential",
"ClassVersion": "1.0.0",
"ClassProperties": [
{
"Name": "UserName",
"CimType": "String",
"Qualifiers": {
"MaxLen": 256
}
},
{
"Name": "Password",
"CimType": "String"
}
]
},
{
"ClassName": "OMI_BaseResource",
"ClassVersion": "1.0.0",
"ClassProperties": [
{
"Name": "ResourceId",
"CimType": "String",
"Qualifiers": {
"Required": true
}
},
{
"Name": "SourceInfo",
"CimType": "String",
"Qualifiers": {
"Write": true
}
},
{
"Name": "DependsOn",
"CimType": "StringArray",
"Qualifiers": {
"Write": true
}
},
{
"Name": "ModuleName",
"CimType": "String",
"Qualifiers": {
"Required": true
}
},
{
"Name": "ModuleVersion",
"CimType": "String",
"Qualifiers": {
"Required": true
}
},
{
"Name": "ConfigurationName",
"CimType": "String",
"Qualifiers": {
"Write": true
}
},
{
"Name": "PsDscRunAsCredential",
"CimType": "Instance",
"ReferenceClassName": "MSFT_Credential",
"Qualifiers": {
"Write": true,
"EmbeddedInstance": "MSFT_Credential"
}
}
]
},
{
"ClassName": "MSFT_KeyValuePair",
"ClassVersion": "1.0.0",
"ClassProperties": [
{
"Name": "Key",
"CimType": "String",
"Qualifiers": {
"Key": true
}
},
{
"Name": "Value",
"CimType": "String",
"Qualifiers": {
"Write": true
}
}
]
},
{
"ClassName": "MSFT_BaseConfigurationProviderRegistration",
"ClassVersion": "1.0.0",
"ClassProperties": [
{
"Name": "ClassName",
"CimType": "String",
"Qualifiers": {
"Key": true
}
},
{
"Name": "DSCEngineCompatVersion",
"CimType": "String"
},
{
"Name": "DSCModuleVersion",
"CimType": "String"
}
]
},
{
"ClassName": "MSFT_CimConfigurationProviderRegistration",
"ClassVersion": "1.0.0",
"SuperClassName": "MSFT_BaseConfigurationProviderRegistration",
"ClassProperties": [
{
"Name": "Namespace",
"CimType": "String"
}
]
},
{
"ClassName": "MSFT_PSConfigurationProviderRegistration",
"ClassVersion": "1.0.0",
"SuperClassName": "MSFT_BaseConfigurationProviderRegistration",
"ClassProperties": [
{
"Name": "ModuleName",
"CimType": "String"
},
{
"Name": "ProviderPath",
"CimType": "String"
},
{
"Name": "ModulePath",
"CimType": "String"
}
]
},
{
"ClassName": "OMI_ConfigurationDocument",
"ClassVersion": "1.0.0",
"ClassProperties": [
{
"Name": "Version",
"CimType": "String"
},
{
"Name": "Author",
"CimType": "String"
},
{
"Name": "Copyright",
"CimType": "String"
},
{
"Name": "HelpInfoUri",
"CimType": "String"
},
{
"Name": "ContentType",
"CimType": "String"
},
{
"Name": "GenerationDate",
"CimType": "String"
},
{
"Name": "GenerationHost",
"CimType": "String"
},
{
"Name": "Name",
"CimType": "String"
},
{
"Name": "MinimumCompatibleVersion",
"CimType": "String"
},
{
"Name": "CompatibleVersionAdditionalProperties",
"CimType": "StringArray"
},
{
"Name": "UseCms",
"CimType": "Boolean"
}
]
},
{
"ClassName": "OMI_MetaConfigurationResource",
"ClassVersion": "1.0.0",
"ClassProperties": [
{
"Name": "ResourceId",
"CimType": "String",
"Qualifiers": {
"Required": true
}
},
{
"Name": "SourceInfo",
"CimType": "String",
"Qualifiers": {
"Write": true
}
}
]
},
{
"ClassName": "OMI_ResourceModuleManager",
"ClassVersion": "1.0.0",
"SuperClassName": "OMI_MetaConfigurationResource"
},
{
"ClassName": "OMI_ConfigurationDownloadManager",
"ClassVersion": "1.0.0",
"SuperClassName": "OMI_MetaConfigurationResource"
},
{
"ClassName": "OMI_ReportManager",
"ClassVersion": "1.0.0",
"SuperClassName": "OMI_MetaConfigurationResource"
}
]
@@ -1,218 +0,0 @@
{
"ClassName": "MSFT_DSCMetaConfiguration",
"FriendlyName": "LocalConfigurationManager",
"ClassVersion": "1.0.0",
"ClassProperties": [
{
"Name": "ConfigurationModeFrequencyMins",
"CimType": "UInt32"
},
{
"Name": "RebootNodeIfNeeded",
"CimType": "Boolean"
},
{
"Name": "ConfigurationMode",
"CimType": "String",
"Qualifiers": {
"ValueMap": [
"ApplyOnly",
"ApplyAndMonitor",
"ApplyAndAutoCorrect",
"MonitorOnly"
],
"Values": [
"ApplyOnly",
"ApplyAndMonitor",
"ApplyAndAutoCorrect",
"MonitorOnly"
]
}
},
{
"Name": "ActionAfterReboot",
"CimType": "String",
"Qualifiers": {
"ValueMap": [
"ContinueConfiguration",
"StopConfiguration"
],
"Values": [
"ContinueConfiguration",
"StopConfiguration"
]
}
},
{
"Name": "Credential",
"CimType": "Instance",
"ReferenceClassName": "MSFT_Credential",
"Qualifiers": {
"EmbeddedInstance": "MSFT_Credential"
}
},
{
"Name": "RefreshMode",
"CimType": "String",
"Qualifiers": {
"ValueMap": [
"Push",
"Pull",
"Disabled"
],
"Values": [
"Push",
"Pull",
"Disabled"
]
}
},
{
"Name": "CertificateID",
"CimType": "String"
},
{
"Name": "ConfigurationID",
"CimType": "String"
},
{
"Name": "DownloadManagerName",
"CimType": "String"
},
{
"Name": "DownloadManagerCustomData",
"CimType": "InstanceArray",
"ReferenceClassName": "MSFT_KeyValuePair",
"Qualifiers": {
"EmbeddedInstance": "MSFT_KeyValuePair"
}
},
{
"Name": "RefreshFrequencyMins",
"CimType": "UInt32"
},
{
"Name": "AllowModuleOverwrite",
"CimType": "Boolean"
},
{
"Name": "DebugMode",
"CimType": "StringArray",
"Qualifiers": {
"ValueMap": [
"None",
"ForceModuleImport",
"All",
"ResourceScriptBreakAll",
"ResourceScriptBreakpoint"
],
"Values": [
"None",
"ForceModuleImport",
"All",
"ResourceScriptBreakAll",
"ResourceScriptBreakpoint"
]
}
},
{
"Name": "LCMVersion",
"CimType": "String",
"Qualifiers": {
"Read": true
}
},
{
"Name": "LCMCompatibleVersions",
"CimType": "StringArray",
"Qualifiers": {
"Read": true
}
},
{
"Name": "LCMState",
"CimType": "String",
"Qualifiers": {
"Read": true,
"ValueMap": [
"Idle",
"Busy",
"PendingReboot",
"PendingConfiguration"
],
"Values": [
"Idle",
"Busy",
"PendingReboot",
"PendingConfiguration"
]
}
},
{
"Name": "LCMStateDetail",
"CimType": "String",
"Qualifiers": {
"Read": true
}
},
{
"Name": "ConfigurationDownloadManagers",
"CimType": "InstanceArray",
"ReferenceClassName": "OMI_ConfigurationDownloadManager",
"Qualifiers": {
"EmbeddedInstance": "OMI_ConfigurationDownloadManager"
}
},
{
"Name": "ResourceModuleManagers",
"CimType": "InstanceArray",
"ReferenceClassName": "OMI_ResourceModuleManager",
"Qualifiers": {
"EmbeddedInstance": "OMI_ResourceModuleManager"
}
},
{
"Name": "ReportManagers",
"CimType": "InstanceArray",
"ReferenceClassName": "OMI_ReportManager",
"Qualifiers": {
"EmbeddedInstance": "OMI_ReportManager"
}
},
{
"Name": "PartialConfigurations",
"CimType": "InstanceArray",
"ReferenceClassName": "MSFT_PartialConfiguration",
"Qualifiers": {
"EmbeddedInstance": "MSFT_PartialConfiguration"
}
},
{
"Name": "StatusRetentionTimeInDays",
"CimType": "UInt32"
},
{
"Name": "AgentId",
"CimType": "String",
"Qualifiers": {
"Read": true
}
},
{
"Name": "SignatureValidationPolicy",
"CimType": "String"
},
{
"Name": "SignatureValidations",
"CimType": "InstanceArray",
"ReferenceClassName": "MSFT_SignatureValidation",
"Qualifiers": {
"EmbeddedInstance": "MSFT_SignatureValidation"
}
},
{
"Name": "MaximumDownloadSizeMB",
"CimType": "UInt32"
}
]
}
@@ -1,455 +0,0 @@
[
{
"ClassName": "MSFT_WebDownloadManager",
"FriendlyName": "ConfigurationRepositoryWeb",
"ClassVersion": "1.0.0",
"SuperClassName": "OMI_ConfigurationDownloadManager",
"ClassProperties": [
{
"Name": "ServerURL",
"CimType": "String",
"Qualifiers": {
"Key": true
}
},
{
"Name": "CertificateID",
"CimType": "String"
},
{
"Name": "AllowUnsecureConnection",
"CimType": "Boolean"
},
{
"Name": "RegistrationKey",
"CimType": "String"
},
{
"Name": "ConfigurationNames",
"CimType": "StringArray"
},
{
"Name": "ProxyURL",
"CimType": "String"
},
{
"Name": "ProxyCredential",
"CimType": "Instance",
"ReferenceClassName": "MSFT_Credential",
"Qualifiers": {
"EmbeddedInstance": "MSFT_Credential"
}
}
]
},
{
"ClassName": "MSFT_FileDownloadManager",
"FriendlyName": "ConfigurationRepositoryShare",
"ClassVersion": "1.0.0",
"SuperClassName": "OMI_ConfigurationDownloadManager",
"ClassProperties": [
{
"Name": "SourcePath",
"CimType": "String",
"Qualifiers": {
"Key": true
}
},
{
"Name": "Credential",
"CimType": "Instance",
"ReferenceClassName": "MSFT_Credential",
"Qualifiers": {
"EmbeddedInstance": "MSFT_Credential"
}
}
]
},
{
"ClassName": "MSFT_WebResourceManager",
"FriendlyName": "ResourceRepositoryWeb",
"ClassVersion": "1.0.0",
"SuperClassName": "OMI_ResourceModuleManager",
"ClassProperties": [
{
"Name": "ServerURL",
"CimType": "String",
"Qualifiers": {
"Key": true
}
},
{
"Name": "CertificateID",
"CimType": "String"
},
{
"Name": "AllowUnsecureConnection",
"CimType": "Boolean"
},
{
"Name": "RegistrationKey",
"CimType": "String"
},
{
"Name": "ProxyURL",
"CimType": "String"
},
{
"Name": "ProxyCredential",
"CimType": "Instance",
"ReferenceClassName": "MSFT_Credential",
"Qualifiers": {
"EmbeddedInstance": "MSFT_Credential"
}
}
]
},
{
"ClassName": "MSFT_FileResourceManager",
"FriendlyName": "ResourceRepositoryShare",
"ClassVersion": "1.0.0",
"SuperClassName": "OMI_ResourceModuleManager",
"ClassProperties": [
{
"Name": "SourcePath",
"CimType": "String",
"Qualifiers": {
"Key": true
}
},
{
"Name": "Credential",
"CimType": "Instance",
"ReferenceClassName": "MSFT_Credential",
"Qualifiers": {
"EmbeddedInstance": "MSFT_Credential"
}
}
]
},
{
"ClassName": "MSFT_WebReportManager",
"FriendlyName": "ReportServerWeb",
"ClassVersion": "1.0.0",
"SuperClassName": "OMI_ReportManager",
"ClassProperties": [
{
"Name": "ServerURL",
"CimType": "String",
"Qualifiers": {
"Key": true
}
},
{
"Name": "CertificateID",
"CimType": "String"
},
{
"Name": "AllowUnsecureConnection",
"CimType": "Boolean"
},
{
"Name": "RegistrationKey",
"CimType": "String"
},
{
"Name": "ProxyURL",
"CimType": "String"
},
{
"Name": "ProxyCredential",
"CimType": "Instance",
"ReferenceClassName": "MSFT_Credential",
"Qualifiers": {
"EmbeddedInstance": "MSFT_Credential"
}
}
]
},
{
"ClassName": "MSFT_PartialConfiguration",
"FriendlyName": "PartialConfiguration",
"ClassVersion": "1.0.0",
"SuperClassName": "OMI_MetaConfigurationResource",
"ClassProperties": [
{
"Name": "Description",
"CimType": "String",
"Qualifiers": {
"Write": true
}
},
{
"Name": "ExclusiveResources",
"CimType": "StringArray",
"Qualifiers": {
"Write": true
}
},
{
"Name": "ConfigurationSource",
"CimType": "StringArray",
"Qualifiers": {
"Write": true
}
},
{
"Name": "ResourceModuleSource",
"CimType": "StringArray",
"Qualifiers": {
"Write": true
}
},
{
"Name": "DependsOn",
"CimType": "StringArray",
"Qualifiers": {
"Write": true
}
},
{
"Name": "RefreshMode",
"CimType": "String",
"Qualifiers": {
"ValueMap": [
"Push",
"Pull",
"Disabled"
],
"Values": [
"Push",
"Pull",
"Disabled"
]
}
}
]
},
{
"ClassName": "MSFT_SignatureValidation",
"FriendlyName": "SignatureValidation",
"ClassVersion": "1.0.0",
"SuperClassName": "OMI_MetaConfigurationResource",
"ClassProperties": [
{
"Name": "TrustedStorePath",
"CimType": "String",
"Qualifiers": {
"Write": true
}
},
{
"Name": "SignedItemType",
"CimType": "StringArray",
"Qualifiers": {
"ValueMap": [
"Configuration",
"Module"
],
"Values": [
"Configuration",
"Module"
]
}
}
]
},
{
"ClassName": "MSFT_DSCMetaConfigurationV2",
"FriendlyName": "Settings",
"ClassVersion": "2.0.0",
"ClassProperties": [
{
"Name": "ConfigurationModeFrequencyMins",
"CimType": "UInt32"
},
{
"Name": "RebootNodeIfNeeded",
"CimType": "Boolean"
},
{
"Name": "ConfigurationMode",
"CimType": "String",
"Qualifiers": {
"ValueMap": [
"ApplyOnly",
"ApplyAndMonitor",
"ApplyAndAutoCorrect",
"MonitorOnly"
],
"Values": [
"ApplyOnly",
"ApplyAndMonitor",
"ApplyAndAutoCorrect",
"MonitorOnly"
]
}
},
{
"Name": "ActionAfterReboot",
"CimType": "String",
"Qualifiers": {
"ValueMap": [
"ContinueConfiguration",
"StopConfiguration"
],
"Values": [
"ContinueConfiguration",
"StopConfiguration"
]
}
},
{
"Name": "RefreshMode",
"CimType": "String",
"Qualifiers": {
"ValueMap": [
"Push",
"Pull",
"Disabled"
],
"Values": [
"Push",
"Pull",
"Disabled"
]
}
},
{
"Name": "CertificateID",
"CimType": "String"
},
{
"Name": "ConfigurationID",
"CimType": "String"
},
{
"Name": "RefreshFrequencyMins",
"CimType": "UInt32"
},
{
"Name": "AllowModuleOverwrite",
"CimType": "Boolean"
},
{
"Name": "DebugMode",
"CimType": "StringArray",
"Qualifiers": {
"ValueMap": [
"None",
"ForceModuleImport",
"All",
"ResourceScriptBreakAll",
"ResourceScriptBreakpoint"
],
"Values": [
"None",
"ForceModuleImport",
"All",
"ResourceScriptBreakAll",
"ResourceScriptBreakpoint"
]
}
},
{
"Name": "LCMVersion",
"CimType": "String",
"Qualifiers": {
"Read": true
}
},
{
"Name": "LCMCompatibleVersions",
"CimType": "StringArray",
"Qualifiers": {
"Read": true
}
},
{
"Name": "LCMState",
"CimType": "String",
"Qualifiers": {
"Read": true,
"ValueMap": [
"Idle",
"Busy",
"PendingReboot",
"PendingConfiguration"
],
"Values": [
"Idle",
"Busy",
"PendingReboot",
"PendingConfiguration"
]
}
},
{
"Name": "LCMStateDetail",
"CimType": "String",
"Qualifiers": {
"Read": true
}
},
{
"Name": "ConfigurationDownloadManagers",
"CimType": "InstanceArray",
"ReferenceClassName": "OMI_ConfigurationDownloadManager",
"Qualifiers": {
"EmbeddedInstance": "OMI_ConfigurationDownloadManager"
}
},
{
"Name": "ResourceModuleManagers",
"CimType": "InstanceArray",
"ReferenceClassName": "OMI_ResourceModuleManager",
"Qualifiers": {
"EmbeddedInstance": "OMI_ResourceModuleManager"
}
},
{
"Name": "ReportManagers",
"CimType": "InstanceArray",
"ReferenceClassName": "OMI_ReportManager",
"Qualifiers": {
"EmbeddedInstance": "OMI_ReportManager"
}
},
{
"Name": "PartialConfigurations",
"CimType": "InstanceArray",
"ReferenceClassName": "MSFT_PartialConfiguration",
"Qualifiers": {
"EmbeddedInstance": "MSFT_PartialConfiguration"
}
},
{
"Name": "StatusRetentionTimeInDays",
"CimType": "UInt32"
},
{
"Name": "AgentId",
"CimType": "String",
"Qualifiers": {
"Read": true
}
},
{
"Name": "SignatureValidationPolicy",
"CimType": "String"
},
{
"Name": "SignatureValidations",
"CimType": "InstanceArray",
"ReferenceClassName": "MSFT_SignatureValidation",
"Qualifiers": {
"EmbeddedInstance": "MSFT_SignatureValidation"
}
},
{
"Name": "MaximumDownloadSizeMB",
"CimType": "UInt32"
}
]
}
]
@@ -9,7 +9,7 @@
RootModule = 'PSDesiredStateConfiguration.psm1' RootModule = 'PSDesiredStateConfiguration.psm1'
# Version number of this module. # Version number of this module.
moduleVersion = '3.0.0' moduleVersion = '2.0.8'
# Supported PSEditions # Supported PSEditions
CompatiblePSEditions = @('Core') CompatiblePSEditions = @('Core')
@@ -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 = '6.1'
# Name of the Windows PowerShell host required by this module # Name of the Windows PowerShell host required by this module
# PowerShellHostName = '' # PowerShellHostName = ''
@@ -48,7 +48,7 @@ PowerShellVersion = '7.2'
# ProcessorArchitecture = '' # ProcessorArchitecture = ''
# Modules that must be imported into the global environment prior to importing this module # Modules that must be imported into the global environment prior to importing this module
#RequiredModules = @() # RequiredModules = @()
# Assemblies that must be loaded prior to importing this module # Assemblies that must be loaded prior to importing this module
# RequiredAssemblies = @() # RequiredAssemblies = @()
@@ -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 = @()
# 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 = @(
@@ -71,7 +71,6 @@ FunctionsToExport = @(
'New-DscChecksum' 'New-DscChecksum'
'Get-DscResource' 'Get-DscResource'
'Invoke-DscResource' 'Invoke-DscResource'
'ConvertTo-DscJsonSchema'
) )
@@ -101,13 +100,11 @@ HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=2113535'
PrivateData = @{ PrivateData = @{
PSData = @{ PSData = @{
Prerelease = 'beta1'
Tags = @('PSDesiredStateConfiguration', Tags = @('PSDesiredStateConfiguration',
'PSEdition_Core',
'Linux', 'Linux',
'Mac', 'Mac',
'Windows') 'Windows')
ProjectUri = 'https://github.com/PowerShell/PSDesiredStateConfiguration' ProjectUri = 'https://github.com/PowerShell/PSDesiredStateConfiguration'
}
} }
} }
}
@@ -16,7 +16,7 @@ data LocalizedData
InvalidConfigurationName = Invalid Configuration Name '{0}' is specified. Standard names may only contain letters (a-z, A-Z), numbers (0-9), and underscore (_). The name may not be null or empty, and should start with a letter. InvalidConfigurationName = Invalid Configuration Name '{0}' is specified. Standard names may only contain letters (a-z, A-Z), numbers (0-9), and underscore (_). The name may not be null or empty, and should start with a letter.
InvalidResourceSpecification = Found more than one resource named '{0}'. Please use the module specification to be more specific. InvalidResourceSpecification = Found more than one resource named '{0}'. Please use the module specification to be more specific.
UnsupportedResourceImplementation = The resource '{0}' implemented as '{1}' is not supported by Invoke-DscResource. UnsupportedResourceImplementation = The resource '{0}' implemented as '{1}' is not supported by Invoke-DscResource.
NoValidConfigFileFound = No valid config files (json,zip) were found. NoValidConfigFileFound = No valid config files (mof,zip) were found.
InputFileNotExist=File {0} doesn't exist. InputFileNotExist=File {0} doesn't exist.
FileReadError=Error Reading file {0}. FileReadError=Error Reading file {0}.
MatchingFileNotFound=No matching file found. MatchingFileNotFound=No matching file found.
@@ -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}'.
@@ -76,7 +76,7 @@ Import-LocalizedData -BindingVariable LocalizedData -FileName PSDesiredStateCon
Import-Module $PSScriptRoot/helpers/DscResourceInfo.psm1 Import-Module $PSScriptRoot/helpers/DscResourceInfo.psm1
# Set DSC HOME environment variable. # Set DSC HOME environment variable.
$env:DSC_HOME = Join-Path $PSScriptRoot "Configuration" $env:DSC_HOME = "$PSScriptRoot/Configuration"
$script:V1MetaConfigPropertyList = @('ConfigurationModeFrequencyMins', 'RebootNodeIfNeeded', 'ConfigurationMode', 'ActionAfterReboot', 'RefreshMode', 'CertificateID', 'ConfigurationID', 'DownloadManagerName', 'DownloadManagerCustomData', 'RefreshFrequencyMins', 'AllowModuleOverwrite', 'DebugMode', 'Credential') $script:V1MetaConfigPropertyList = @('ConfigurationModeFrequencyMins', 'RebootNodeIfNeeded', 'ConfigurationMode', 'ActionAfterReboot', 'RefreshMode', 'CertificateID', 'ConfigurationID', 'DownloadManagerName', 'DownloadManagerCustomData', 'RefreshFrequencyMins', 'AllowModuleOverwrite', 'DebugMode', 'Credential')
$script:DirectAccessMetaConfigPropertyList = @('AllowModuleOverWrite', 'CertificateID', 'ConfigurationDownloadManagers', 'ResourceModuleManagers', 'DebugMode', 'RebootNodeIfNeeded', 'RefreshMode', 'ConfigurationAgent') $script:DirectAccessMetaConfigPropertyList = @('AllowModuleOverWrite', 'CertificateID', 'ConfigurationDownloadManagers', 'ResourceModuleManagers', 'DebugMode', 'RebootNodeIfNeeded', 'RefreshMode', 'ConfigurationAgent')
@@ -307,7 +307,7 @@ function ConvertTo-MOFInstance
elseif ($Value -is [PSCredential] ) elseif ($Value -is [PSCredential] )
{ {
# If the input object is a PSCredential, turn it into an MSFT_Credential with an encrypted password. # If the input object is a PSCredential, turn it into an MSFT_Credential with an encrypted password.
$clearText = [Microsoft.PowerShell.DesiredStateConfiguration.Internal.CrossPlatform.DscClassCache]::GetStringFromSecureString($Value.Password) $clearText = [Microsoft.PowerShell.DesiredStateConfiguration.Internal.DscClassCache]::GetStringFromSecureString($Value.Password)
$newValue = @{ $newValue = @{
UserName = $Value.UserName UserName = $Value.UserName
Password = $clearText Password = $clearText
@@ -509,7 +509,7 @@ function ConvertTo-MOFInstance
$targetTypeName = $PropertyTypes[$p.Name].TypeConstraint $targetTypeName = $PropertyTypes[$p.Name].TypeConstraint
# see if the target type is an array # see if the target type is an array
$asArray = $p.Name -eq 'DependsOn' -or $targetTypeName -match 'Array' $asArray = $p.Name -eq 'DependsOn' -or $targetTypeName -match 'Array' -or ((-not [string]::IsNullOrEmpty($targetTypeName)) -and $targetTypeName.EndsWith('[]'))
# Convert the CIM typename to the appropriate .NET type to use # Convert the CIM typename to the appropriate .NET type to use
# to convert the input object into an appropriately encoded string # to convert the input object into an appropriately encoded string
@@ -671,10 +671,7 @@ function ConvertTo-MOFInstance
} }
else else
{ {
if ($targetTypeName -notmatch 'Array' -or $p.Value.Count) $p.Name + ' = ' + (stringify -value $p.Value -asArray $asArray -targetType $targetType ) + ";`n"
{
$p.Name + ' = ' + (stringify -value $p.Value -asArray $asArray -targetType $targetType ) + ";`n"
}
} }
} }
} }
@@ -701,6 +698,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
# #
@@ -1766,6 +1790,59 @@ function ValidateUpdate-ConfigurationData
return $true return $true
} }
##############################################################
#
# Checks to see if a module defining composite resources should be reloaded
# based the last write time of the schema file. Returns true if the file exists
# and the last modified time was either not recorded or has change.
#
function Test-ModuleReloadRequired
{
[OutputType([bool])]
param (
[Parameter(Mandatory)]
[string]
$SchemaFilePath
)
if (-not $SchemaFilePath -or $SchemaFilePath -notmatch '\.schema\.psm1$')
{
# not a composite res
return $false
}
# If the path doesn't exist, then we can't reload it.
# Note: this condition is explicitly not an error for this function.
if ( -not (Test-Path $SchemaFilePath))
{
if ($schemaFileLastUpdate.ContainsKey($SchemaFilePath))
{
$schemaFileLastUpdate.Remove($SchemaFilePath)
}
return $false
}
# If we have a modified date, then return it.
if ($schemaFileLastUpdate.ContainsKey($SchemaFilePath))
{
if ( (Get-Item $SchemaFilePath).LastWriteTime -eq $schemaFileLastUpdate[$SchemaFilePath] )
{
return $false
}
else
{
return $true
}
}
# Otherwise, record the last write time and return true.
$script:schemaFileLastUpdate[$SchemaFilePath] = (Get-Item $SchemaFilePath).LastWriteTime
$true
}
# Holds the schema file to lastwritetime mapping.
[System.Collections.Generic.Dictionary[string,DateTime]] $script:schemaFileLastUpdate =
New-Object -TypeName 'System.Collections.Generic.Dictionary[string,datetime]'
########################################################### ###########################################################
# Configuration keyword implementation # Configuration keyword implementation
########################################################### ###########################################################
@@ -1891,7 +1968,7 @@ function Configuration
# Load the default CIM keyword/function definitions set, populating the function collection # Load the default CIM keyword/function definitions set, populating the function collection
# with the default functions. # with the default functions.
[Microsoft.PowerShell.DesiredStateConfiguration.Internal.CrossPlatform.DscClassCache]::LoadDefaultCimKeywords($functionsToDefine) [Microsoft.PowerShell.DesiredStateConfiguration.Internal.DscClassCache]::LoadDefaultCimKeywords($functionsToDefine)
# Set up the rest of the configuration runtime state. # Set up the rest of the configuration runtime state.
Initialize-ConfigurationRuntimeState $Name Initialize-ConfigurationRuntimeState $Name
@@ -1982,8 +2059,25 @@ function Configuration
foreach ($mod in $modulesInfo) { foreach ($mod in $modulesInfo) {
$null = ImportClassResourcesFromModule -Module $mod -Resources $res -functionsToDefine $functionsToDefine $null = ImportClassResourcesFromModule -Module $mod -Resources $res -functionsToDefine $functionsToDefine
$dscResourcesPath = Join-Path -Path $mod.ModuleBase -ChildPath 'DscResources'
if ($moduleInfos.Count -eq 1) if(Test-Path $dscResourcesPath)
{
foreach($requiredResource in $res)
{
if ($requiredResource.Contains('*')) {
# we historically resolve wildcards by Get-Item File System rules.
# We don't support wildcards resolutions for Friendly names.
foreach ($resource in Get-ChildItem -Path $dscResourcesPath -Directory -Name -Filter $requiredResource)
{
$null = ImportCimAndScriptKeywordsFromModule -Module $mod -Resource $resource -functionsToDefine $functionsToDefine
}
} else {
# ImportCimAndScriptKeywordsFromModule takes care about resolving $requiredResources names to ClassNames or FriendlyNames.
$null = ImportCimAndScriptKeywordsFromModule -Module $mod -Resource $requiredResource -functionsToDefine $functionsToDefine
}
}
}
elseif ($moduleInfos.Count -eq 1)
{ {
$modules.Add($moduleInfos) $modules.Add($moduleInfos)
} }
@@ -2219,7 +2313,7 @@ function Configuration
{ {
Write-Debug -Message " CONFIGURATION $Name : DOING TOP-LEVEL CLEAN UP" Write-Debug -Message " CONFIGURATION $Name : DOING TOP-LEVEL CLEAN UP"
[System.Management.Automation.Language.DynamicKeyword]::Reset() [System.Management.Automation.Language.DynamicKeyword]::Reset()
[Microsoft.PowerShell.DesiredStateConfiguration.Internal.CrossPlatform.DscClassCache]::ClearCache() [Microsoft.PowerShell.DesiredStateConfiguration.Internal.DscClassCache]::ClearCache()
Initialize-ConfigurationRuntimeState Initialize-ConfigurationRuntimeState
} }
@@ -2272,7 +2366,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 +2402,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 +2423,7 @@ function Update-DependsOn
if($needAdd) if($needAdd)
{ {
$NodeInstanceAliases[$alias] = $first + $dependsOn + "`n};" $NodeInstanceAliases[$alias] = $first + $dependsOn + "`r`n};"
} }
} }
} }
@@ -2371,12 +2465,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};"
} }
} }
} }
@@ -2396,16 +2490,66 @@ function ImportClassResourcesFromModule
$functionsToDefine $functionsToDefine
) )
$Errors = New-Object -TypeName 'System.Collections.ObjectModel.Collection[System.Exception]' $resourcesFound = [Microsoft.PowerShell.DesiredStateConfiguration.Internal.DscClassCache]::ImportClassResourcesFromModule($Module, $Resources, $functionsToDefine)
return ,$resourcesFound
}
$resourcesFound = [Microsoft.PowerShell.DesiredStateConfiguration.Internal.CrossPlatform.DscClassCache]::ImportClassResourcesFromModule($Module, $Resources, $functionsToDefine, $Errors) function ImportCimAndScriptKeywordsFromModule
{
param (
[Parameter(Mandatory)]
$Module,
foreach($ex in $Errors) [Parameter(Mandatory)]
$resource,
$functionsToDefine
)
trap
{ {
Write-Error -Exception $ex continue
} }
return ,$resourcesFound $SchemaFilePath = $null
$oldCount = $functionsToDefine.Count
$keywordErrors = New-Object -TypeName 'System.Collections.ObjectModel.Collection[System.Exception]'
$foundCimSchema = [Microsoft.PowerShell.DesiredStateConfiguration.Internal.DscClassCache]::ImportCimKeywordsFromModule(
$Module, $resource, [ref] $SchemaFilePath, $functionsToDefine, $keywordErrors)
foreach($ex in $keywordErrors)
{
Write-Error -Exception $ex
if($ex.InnerException)
{
Write-Error -Exception $ex.InnerException
}
}
$functionsAdded = $functionsToDefine.Count - $oldCount
Write-Debug -Message " $Name : PROCESSING RESOURCE FILE: Added $functionsAdded type handler functions from '$SchemaFilePath'"
$SchemaFilePath = $null
$oldCount = $functionsToDefine.Count
$foundScriptSchema = [Microsoft.PowerShell.DesiredStateConfiguration.Internal.DscClassCache]::ImportScriptKeywordsFromModule(
$Module, $resource, [ref] $SchemaFilePath, $functionsToDefine )
$functionsAdded = $functionsToDefine.Count - $oldCount
Write-Debug -Message " $Name : PROCESSING RESOURCE FILE: Added $functionsAdded type handler functions from '$SchemaFilePath'"
if ($foundScriptSchema -and $SchemaFilePath)
{
$resourceDirectory = Split-Path $SchemaFilePath
if($null -ne $resourceDirectory)
{
Import-Module -Force: (Test-ModuleReloadRequired $SchemaFilePath) -Verbose:$false -Name $resourceDirectory -Global -ErrorAction SilentlyContinue
}
}
return $foundCimSchema -or $foundScriptSchema
} }
# #
@@ -2429,7 +2573,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 +2699,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 +2805,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 +2863,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 +2886,72 @@ 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"
$errMsg = Test-MofInstanceText $nodeDoc
if($errMsg)
{
$errorMessage = $LocalizedData.InvalidMOFDefinition -f @($mofNode, $errMsg)
$exception = New-Object -TypeName System.InvalidOperationException -ArgumentList $errorMessage
Write-Error -Exception $exception -Message $errorMessage -Category InvalidOperation -ErrorId InvalidMOFDefinition
Update-ConfigurationErrorCount
$nodeOutfile = "$ConfigurationOutputDirectory/$($mofNode).mof.error"
}
if($nodeDocCount -gt 0) if($nodeDocCount -gt 0)
{ {
@@ -2772,6 +2965,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
} }
@@ -3215,7 +3409,7 @@ function Test-MofInstanceText
{ {
try try
{ {
[Microsoft.PowerShell.DesiredStateConfiguration.Internal.CrossPlatform.DscClassCache]::ValidateInstanceText($instanceText) [Microsoft.PowerShell.DesiredStateConfiguration.Internal.DscClassCache]::ValidateInstanceText($instanceText)
} }
catch [System.Management.Automation.MethodInvocationException] catch [System.Management.Automation.MethodInvocationException]
{ {
@@ -3458,7 +3652,7 @@ function New-DscChecksum
# Retrieve all valid configuration files at the specified $Path # Retrieve all valid configuration files at the specified $Path
$allConfigFiles = $Path | ForEach-Object -Process { $allConfigFiles = $Path | ForEach-Object -Process {
(Get-ChildItem -Path $_ -Recurse | Where-Object -FilterScript { (Get-ChildItem -Path $_ -Recurse | Where-Object -FilterScript {
$_.Extension -eq '.json' -or $_.Extension -eq '.zip' $_.Extension -eq '.mof' -or $_.Extension -eq '.zip'
} }
) )
} }
@@ -3467,6 +3661,7 @@ function New-DscChecksum
if ($allConfigFiles.Length -eq 0) if ($allConfigFiles.Length -eq 0)
{ {
Write-Log -Message $LocalizedData.NoValidConfigFileFound Write-Log -Message $LocalizedData.NoValidConfigFileFound
return return
} }
@@ -3652,12 +3847,22 @@ function Get-DSCResourceModules
foreach($moduleFolder in Get-ChildItem $folder -Directory) foreach($moduleFolder in Get-ChildItem $folder -Directory)
{ {
$addModule = $false $addModule = $false
foreach($psd1 in Get-ChildItem -Recurse -Filter "$($moduleFolder.Name).psd1" -Path $moduleFolder.fullname -Depth 2)
$dscFolders = Get-childitem "$($moduleFolder.FullName)\DscResources","$($moduleFolder.FullName)\*\DscResources" -ErrorAction Ignore
if($null -ne $dscFolders)
{ {
$containsDSCResource = select-string -LiteralPath $psd1 -pattern '^[^#]*\bDscResourcesToExport\b.*' $addModule = $true
if($null -ne $containsDSCResource) }
if(-not $addModule)
{
foreach($psd1 in Get-ChildItem -Recurse -Filter "$($moduleFolder.Name).psd1" -Path $moduleFolder.fullname -Depth 2)
{ {
$addModule = $true $containsDSCResource = select-string -LiteralPath $psd1 -pattern '^[^#]*\bDscResourcesToExport\b.*'
if($null -ne $containsDSCResource)
{
$addModule = $true
}
} }
} }
@@ -3671,167 +3876,14 @@ function Get-DSCResourceModules
$dscModuleFolderList $dscModuleFolderList
} }
function CimPropertyIsInherited
{
param(
[parameter(Mandatory)]
[string]
$PropertyName,
[parameter(Mandatory)]
[AllowNull()]
[System.Object]
$ParentClass)
if (-not ($ParentClass))
{
return $false;
}
else
{
foreach($property in $ParentClass.CimClassProperties)
{
if ($property.Name -eq $PropertyName)
{
return $true;
}
}
return CimPropertyIsInherited -PropertyName $PropertyName -ParentClass $ParentClass.CimSuperClass
}
}
function PrepareCimClassesForJsonConvertion
{
param(
[parameter(Mandatory)]
$classList)
$resultList = New-Object -TypeName 'System.Collections.Generic.List[PSObject]'
foreach($class in $classList)
{
Write-Verbose "Preprocessing class $($class.CimSystemProperties.ClassName)"
$properties = New-Object -TypeName 'System.Collections.Generic.List[System.Object]'
# remove inherited properties
foreach($property in $class.CimClassProperties)
{
if (-not (CimPropertyIsInherited -PropertyName $property.Name -ParentClass $class.CimSuperClass))
{
Write-Verbose "Adding property $($property.Name)"
$qualifiers = New-Object -TypeName 'System.Collections.Generic.Dictionary[System.String,System.Object]'
foreach($qualifier in $property.Qualifiers)
{
$qualifiers.Add($qualifier.Name, $qualifier.Value)
}
if ($qualifiers.Count -eq 0) { $qualifiers = $null}
$flags = $property.Flags
$flags = $flags -band -bnot [Microsoft.Management.Infrastructure.CimFlags]::Property # this is set for all properties
$flags = $flags -band -bnot [Microsoft.Management.Infrastructure.CimFlags]::NullValue # this is set for all properties
$flags = $flags -band -bnot [Microsoft.Management.Infrastructure.CimFlags]::Required # this is also specified in Qualifiers
$flags = $flags -band -bnot [Microsoft.Management.Infrastructure.CimFlags]::Key # this is also specified in Qualifiers
$flags = $flags -band -bnot [Microsoft.Management.Infrastructure.CimFlags]::ReadOnly # this is also specified in Qualifiers
if ($flags -eq 0) { $flags = $null}
$p = [pscustomobject]@{
Name = $property.Name
Value = $property.Value
CimType = $property.CimType
Flags = $flags
ReferenceClassName = $property.ReferenceClassName
Qualifiers = $qualifiers
}
# remove properties that have null value
$p.PSobject.Properties | % {if ($_.Value -eq $null) {$p.PSobject.Properties.Remove($_.Name)}}
$properties.Add($p);
}
else
{
Write-Verbose "Property $($property.Name) is inherited, ignoring it"
}
}
if ($properties.Count -eq 0) { $properties = $null}
# construct the processed class
$processedClass = [pscustomobject]@{
ClassName = $class.CimSystemProperties.ClassName
FriendlyName = ($class.CimClassQualifiers | Where-Object {$_.Name -eq "FriendlyName"}).Value
ClassVersion = ($class.CimClassQualifiers | Where-Object {$_.Name -eq "ClassVersion"}).Value
Description = ($class.CimClassQualifiers | Where-Object {$_.Name -eq "Description"}).Value
SuperClassName = $class.CimSuperClassName
ClassProperties = $properties
}
# remove properties that have null value
$processedClass.PSobject.Properties | % {if ($_.Value -eq $null) {$processedClass.PSobject.Properties.Remove($_.Name)}}
$resultList.Add($processedClass)
}
return $resultList
}
###########################################################
# ConvertTo-DscJsonSchema
###########################################################
#
# Reads CIM MOF schema files and creates json files with equivalent json schema
#
function ConvertTo-DscJsonSchema
{
param (
[Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
[ValidateNotNullOrEmpty()]
[Alias("Path")]
[string[]]
$Directory
)
Process
{
foreach($dir in $Directory)
{
Write-Verbose "Processing $dir"
if (-not (Test-Path -Path $dir))
{
Write-Error "Can not find directory $dir" # non-terminating error
}
else
{
[Microsoft.PowerShell.DesiredStateConfiguration.Internal.DscClassCache]::Initialize()
$schemaFilePaths = Get-ChildItem -Recurse -File -Path $dir -Filter '*.schema.mof'
foreach($mofPath in $schemaFilePaths)
{
$cimClasses = [Microsoft.PowerShell.DesiredStateConfiguration.Internal.DscClassCache]::ReadCimSchemaMof($mofPath)
Write-Verbose "Read $($cimClasses.Count) classes from $mofPath"
$preprocessedCimClasses = PrepareCimClassesForJsonConvertion $cimClasses
[string] $jsonPath = $mofPath.FullName.Substring(0, $mofPath.FullName.LastIndexOf('.')) + ".json";
Write-Verbose "Writing $jsonPath"
ConvertTo-Json -InputObject $preprocessedCimClasses -Depth 100 -EnumsAsStrings | Out-File -Force -Path $jsonPath
}
}
}
}
}
########################################################### ###########################################################
# Get-DSCResource # Get-DSCResource
########################################################### ###########################################################
# #
# Gets DSC resources on the machine. Allows to filter on a particular resource. # Gets DSC resources on the machine. Allows to filter on a particular resource.
# It parses class-based resources defined in the psm1 module files. # It parses all the resources defined in the schema.mof file and also the composite
# resources defined or imported from PowerShell modules
# #
function Get-DscResource function Get-DscResource
{ {
@@ -3859,12 +3911,12 @@ 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]'
# Load the default Inbox providers (keyword) in cache, also allow caching the resources from multiple versions of modules. # Load the default Inbox providers (keyword) in cache, also allow caching the resources from multiple versions of modules.
[Microsoft.PowerShell.DesiredStateConfiguration.Internal.CrossPlatform.DscClassCache]::LoadDefaultCimKeywords($keywordErrors, $true) [Microsoft.PowerShell.DesiredStateConfiguration.Internal.DscClassCache]::LoadDefaultCimKeywords($keywordErrors, $true)
foreach($ex in $keywordErrors) foreach($ex in $keywordErrors)
{ {
@@ -3911,6 +3963,15 @@ function Get-DscResource
{ {
$null = ImportClassResourcesFromModule -Module $mod -Resources * -functionsToDefine $functionsToDefine $null = ImportClassResourcesFromModule -Module $mod -Resources * -functionsToDefine $functionsToDefine
} }
$dscResources = Join-Path -Path $mod.ModuleBase -ChildPath 'DscResources'
if(Test-Path $dscResources)
{
foreach ($resource in Get-ChildItem -Path $dscResources -Directory -Name)
{
$null = ImportCimAndScriptKeywordsFromModule -Module $mod -Resource $resource -functionsToDefine $functionsToDefine
}
}
} }
$Resources = @() $Resources = @()
@@ -3940,7 +4001,7 @@ function Get-DscResource
Write-Progress -Id 3 -Activity $LocalizedData.CreatingResourceList Write-Progress -Id 3 -Activity $LocalizedData.CreatingResourceList
# Get resources for CIM cache # Get resources for CIM cache
$keywords = [Microsoft.PowerShell.DesiredStateConfiguration.Internal.CrossPlatform.DscClassCache]::GetKeywordsFromCachedClasses() | Where-Object -FilterScript { $keywords = [Microsoft.PowerShell.DesiredStateConfiguration.Internal.DscClassCache]::GetCachedKeywords() | Where-Object -FilterScript {
(!$_.IsReservedKeyword) -and ($null -ne $_.ResourceName) -and !(IsHiddenResource $_.ResourceName) -and (![bool]$Module -or ($_.ImplementingModule -like $ModuleString)) (!$_.IsReservedKeyword) -and ($null -ne $_.ResourceName) -and !(IsHiddenResource $_.ResourceName) -and (![bool]$Module -or ($_.ImplementingModule -like $ModuleString))
} }
@@ -3954,6 +4015,16 @@ function Get-DscResource
$_ -ne $null $_ -ne $null
} }
# Get composite resources
$Resources += Get-Command -CommandType Configuration |
ForEach-Object -Process {
GetCompositeResource $patterns $_ $ignoreResourceParameters -modules $modules
} |
Where-Object -FilterScript {
$_ -ne $null -and (![bool]$ModuleString -or ($_.Module -like $ModuleString)) -and
($_.Path -and ((Split-Path -Leaf $_.Path) -eq "$($_.Name).schema.psm1"))
}
# check whether all resources are found # check whether all resources are found
CheckResourceFound $Name $Resources CheckResourceFound $Name $Resources
} }
@@ -3962,7 +4033,7 @@ function Get-DscResource
if ($initialized) if ($initialized)
{ {
[System.Management.Automation.Language.DynamicKeyword]::Reset() [System.Management.Automation.Language.DynamicKeyword]::Reset()
[Microsoft.PowerShell.DesiredStateConfiguration.Internal.CrossPlatform.DscClassCache]::ClearCache() [Microsoft.PowerShell.DesiredStateConfiguration.Internal.DscClassCache]::ClearCache()
$initialized = $false $initialized = $false
} }
@@ -3973,7 +4044,7 @@ function Get-DscResource
End End
{ {
$Resources = $Resources | Sort-Object -Property Module, Name $Resources = $Resources | Sort-Object -Property Module, Name -Unique
foreach ($resource in $Resources) foreach ($resource in $Resources)
{ {
# return formatted string if required # return formatted string if required
@@ -3990,7 +4061,7 @@ function Get-DscResource
if ($initialized) if ($initialized)
{ {
[System.Management.Automation.Language.DynamicKeyword]::Reset() [System.Management.Automation.Language.DynamicKeyword]::Reset()
[Microsoft.PowerShell.DesiredStateConfiguration.Internal.CrossPlatform.DscClassCache]::ClearCache() [Microsoft.PowerShell.DesiredStateConfiguration.Internal.DscClassCache]::ClearCache()
$initialized = $false $initialized = $false
} }
@@ -4043,23 +4114,69 @@ function GetResourceFromKeyword
$resource.Name = $keyword.Keyword $resource.Name = $keyword.Keyword
# only supporting class-based resources at this time $schemaFiles = [Microsoft.PowerShell.DesiredStateConfiguration.Internal.DscClassCache]::GetFileDefiningClass($keyword.ResourceName)
$implementationDetail = 'ClassBased'
$Module = $modules | Where-Object -FilterScript {
$_.Name -eq $keyword.ImplementingModule -and
$_.Version -eq $keyword.ImplementingModuleVersion
} | Select-Object -First 1
if ($Module -and $Module.ExportedDscResources -contains $keyword.Keyword) if ($schemaFiles.Count)
{ {
$resource.Module = $Module # Find the correct schema file that matches module name and version
$resource.Path = $Module.Path # if same module/version is installed in multiple locations, then pick the first schema file.
$resource.ParentPath = Split-Path -Path $Module.Path foreach ($schemaFileName in $schemaFiles){
$moduleInfo = GetModule $modules $schemaFileName;
if ($moduleInfo.Name -eq $keyword.ImplementingModule -and $moduleInfo.Version -eq $keyword.ImplementingModuleVersion){
break
}
}
# if the class is not a resource we will ignore it except if it is DSC inbox resource.
if(-not $schemaFileName.StartsWith("$env:windir\system32\configuration",[stringComparison]::OrdinalIgnoreCase))
{
$classesFromSchema = [Microsoft.PowerShell.DesiredStateConfiguration.Internal.DscClassCache]::GetCachedClassByFileName($schemaFileName)
if($null -ne $classesFromSchema)
{
# check if the resource is proper DSC resource that always derives from OMI_BaseResource.
$schemaToProcess = $classesFromSchema | ForEach-Object -Process {
if(($_.CimSystemProperties.ClassName -ieq $keyword.ResourceName) -and ($_.CimSuperClassName -ieq 'OMI_BaseResource'))
{
$member = Get-Member -InputObject $_ -MemberType NoteProperty -Name 'ImplementationDetail'
if ($null -eq $member)
{
$_ | Add-Member -MemberType NoteProperty -Name 'ImplementationDetail' -Value $implementationDetail -PassThru
}
else
{
$_
}
}
}
if($null -eq $schemaToProcess)
{
return
}
}
}
$message = $LocalizedData.SchemaFileForResource -f @($schemaFileName)
Write-Verbose -Message $message
$resource.Module = $moduleInfo
$resource.Path = GetImplementingModulePath $schemaFileName
$resource.ParentPath = Split-Path $schemaFileName
} }
else else
{ {
# a class-based keyword must be in the ExportedDscResources of the module that implements it $implementationDetail = 'ClassBased'
return $null $Module = $modules | Where-Object -FilterScript {
$_.Name -eq $keyword.ImplementingModule -and
$_.Version -eq $keyword.ImplementingModuleVersion
}
if ($Module -and $Module.ExportedDscResources -contains $keyword.Keyword)
{
$implementationDetail = 'ClassBased'
$resource.Module = $Module
$resource.Path = $Module.Path
$resource.ParentPath = Split-Path -Path $Module.Path
}
} }
if ([system.string]::IsNullOrEmpty($resource.Path) -eq $false) if ([system.string]::IsNullOrEmpty($resource.Path) -eq $false)
@@ -4091,7 +4208,7 @@ function GetResourceFromKeyword
Ascending = $true Ascending = $true
} }
$resource.UpdateProperties($updatedProperties) $resource.UpdateProperties($updatedProperties)
$resource | Add-Member -MemberType NoteProperty -Name 'ImplementationDetail' -Value $implementationDetail $resource | Add-Member -MemberType NoteProperty -Name 'ImplementationDetail' -Value $implementationDetail
return $resource return $resource
@@ -4210,6 +4327,7 @@ function AddDscResourceProperty
$dscProperty.Values.Add($_) $dscProperty.Values.Add($_)
} }
} }
$dscProperty.PropertyType = $Type $dscProperty.PropertyType = $Type
$dscProperty.IsMandatory = $property.Mandatory $dscProperty.IsMandatory = $property.Mandatory
@@ -4329,13 +4447,13 @@ function GetImplementingModulePath
$schemaFileName $schemaFileName
) )
$moduleFileName = ($schemaFileName -replace ".schema.json$", '') + '.psd1' $moduleFileName = ($schemaFileName -replace ".schema.mof$", '') + '.psd1'
if (Test-Path $moduleFileName) if (Test-Path $moduleFileName)
{ {
return $moduleFileName return $moduleFileName
} }
$moduleFileName = ($schemaFileName -replace ".schema.json$", '') + '.psm1' $moduleFileName = ($schemaFileName -replace ".schema.mof$", '') + '.psm1'
if (Test-Path $moduleFileName) if (Test-Path $moduleFileName)
{ {
return $moduleFileName return $moduleFileName
@@ -4365,9 +4483,9 @@ function GetModule
} }
$schemaFileExt = $null $schemaFileExt = $null
if ($schemaFileName -match '.schema.json') if ($schemaFileName -match '.schema.mof')
{ {
$schemaFileExt = ".schema.json$" $schemaFileExt = ".schema.mof$"
} }
if ($schemaFileName -match '.schema.psm1') if ($schemaFileName -match '.schema.psm1')
@@ -4625,27 +4743,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()
$powershell = [PowerShell]::Create($iss)
$script = @" $script = @"
using module $path using module "$path"
Write-Host -Message ([$type]::new | out-string)
return [$type]::new() return [$type]::new()
"@ "@
$null= $powershell.AddScript($script) $null= $powershell.AddScript($script)
$dscObj=$powershell.Invoke() | Select-object -First 1 $dscType=$powershell.Invoke() | Select-object -First 1
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 $dscType.$key = $value
} }
$info = $dscObj | Out-String $info = $dscType | Out-String
Write-Debug $info Write-Debug $info
Write-Debug "calling $type.$Method() ..." Write-Debug "calling $type.$Method() ..."
$global:DSCMachineStatus = $null $global:DSCMachineStatus = $null
$output = $dscObj.$Method() $output = $dscType.$Method()
return Get-InvokeDscResourceResult -Output $output -Method $Method return Get-InvokeDscResourceResult -Output $output -Method $Method
} }
@@ -4710,7 +4831,6 @@ function Get-InvokeDscResourceResult
Export-ModuleMember -Function @( Export-ModuleMember -Function @(
'Invoke-DscResource' 'Invoke-DscResource'
'ConvertTo-DscJsonSchema'
) )
########################################################### ###########################################################
@@ -24,7 +24,7 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration
/// DSC resource implementation type not known /// DSC resource implementation type not known
/// </summary> /// </summary>
None = 0, None = 0,
/// <summary> /// <summary>
/// DSC resource is implemented using PowerShell module /// DSC resource is implemented using PowerShell module
/// </summary> /// </summary>
@@ -70,13 +70,13 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration
public string FriendlyName { get; set; } public string FriendlyName { get; set; }
/// <summary> /// <summary>
/// Gets or sets module which implements the resource. This could point to parent module, if the DSC resource is implemented /// Gets or sets module which implements the resource. This could point to parent module, if the DSC resource is implemented
/// by one of nested modules. /// by one of nested modules.
/// </summary> /// </summary>
public PSModuleInfo Module { get; set; } public PSModuleInfo Module { get; set; }
/// <summary> /// <summary>
/// Gets name of the module which implements the resource. /// Gets name of the module which implements the resource.
/// </summary> /// </summary>
public string ModuleName public string ModuleName
{ {
@@ -88,7 +88,7 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration
} }
/// <summary> /// <summary>
/// Gets version of the module which implements the resource. /// Gets version of the module which implements the resource.
/// </summary> /// </summary>
public Version Version public Version Version
{ {
@@ -100,7 +100,7 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration
} }
/// <summary> /// <summary>
/// Gets or sets of the file which implements the resource. For the reosurces which are defined using /// Gets or sets of the file which implements the resource. For the reosurces which are defined using
/// MOF file, this will be path to a module which resides in the same folder where schema.mof file is present. /// MOF file, this will be path to a module which resides in the same folder where schema.mof file is present.
/// For composite resources, this will be the module which implements the resource /// For composite resources, this will be the module which implements the resource
/// </summary> /// </summary>
@@ -108,7 +108,7 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration
/// <summary> /// <summary>
/// Gets or sets parent folder, where the resource is defined /// Gets or sets parent folder, where the resource is defined
/// It is the folder containing either the implementing module(=Path) or folder containing ".schema.mof". /// It is the folder containing either the implementing module(=Path) or folder containing ".schema.mof".
/// For native providers, Path will be null and only ParentPath will be present. /// For native providers, Path will be null and only ParentPath will be present.
/// </summary> /// </summary>
public string ParentPath { get; set; } public string ParentPath { get; set; }
@@ -150,7 +150,7 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration
{ {
this.Values = new List<string>(); this.Values = new List<string>();
} }
/// <summary> /// <summary>
/// Gets or sets name of the property /// Gets or sets name of the property
/// </summary> /// </summary>
+379 -289
View File
@@ -1,23 +1,9 @@
# Copyright (c) Microsoft Corporation. All rights reserved. # Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. # Licensed under the MIT License.
Function Install-ModuleIfMissing {
param(
[parameter(Mandatory)]
[String]
$Name,
[version]
$MinimumVersion,
[switch]
$SkipPublisherCheck,
[switch]
$Force
)
$module = Get-Module -Name $Name -ListAvailable -ErrorAction Ignore | Sort-Object -Property Version -Descending | Select-Object -First 1 BeforeDiscovery {
Function global:Test-IsInvokeDscResourceEnable {
if (!$module -or $module.Version -lt $MinimumVersion) { return ($PSVersionTable.PSVersion.Major -ge 7)
Write-Verbose "Installing module '$Name' ..." -Verbose
Install-Module -Name $Name -Force -SkipPublisherCheck:$SkipPublisherCheck.IsPresent
} }
} }
@@ -27,10 +13,12 @@ Describe "Test PSDesiredStateConfiguration" {
Function BeCommand { Function BeCommand {
[CmdletBinding()] [CmdletBinding()]
Param( Param(
[object[]] $ActualValue, $ActualValue,
[string] $CommandName, [string] $CommandName,
[string] $ModuleName, [string] $ModuleName,
[switch]$Negate [switch]$Negate,
[string]$Because,
$CallerSessionState
) )
$failure = if ($Negate) { $failure = if ($Negate) {
@@ -62,7 +50,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,21 +58,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'
$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 (-not $IsWindows) {
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 (-not $IsWindows) {
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'
$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 (-not $IsWindows) {
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 {
$origProgress = $global:ProgressPreference $origProgress = $global:ProgressPreference
$global:ProgressPreference = 'SilentlyContinue' $global:ProgressPreference = 'SilentlyContinue'
Install-ModuleIfMissing -Name XmlContentDsc -Force
$classTestCases = @( $classTestCases = @(
@{ @{
TestCaseName = 'Good case' TestCaseName = 'Good case'
@@ -118,11 +280,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,30 +301,204 @@ 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
$global:ProgressPreference = 'SilentlyContinue' $global:ProgressPreference = 'SilentlyContinue'
$module = Get-InstalledModule -Name PsDscResources -ErrorAction Ignore
if ($module) {
Write-Verbose "removing PSDscResources, tests will re-install..." -Verbose
Uninstall-Module -Name PsDscResources -AllVersions -Force
}
} }
AfterAll { AfterAll {
$Global:ProgressPreference = $origProgress $Global:ProgressPreference = $origProgress
} }
Context "Class Based Resources" { Context "mof resources" {
BeforeAll { BeforeAll {
Install-ModuleIfMissing -Name XmlContentDsc -Force $dscMachineStatusCases = @(
@{
value = '1'
expectedResult = $true
}
@{
value = '$true'
expectedResult = $true
}
@{
value = '0'
expectedResult = $false
}
@{
value = '$false'
expectedResult = $false
}
)
$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 ($env:TF_BUILD -eq 'true') {
Set-ItResult -Skipped -Because "cannot install PSDscResources module during tests in Azure DevOps"
}
$result = Invoke-DscResource -Name PSModule -ModuleName $psGetModuleSpecification -Method set -Property @{
Name = 'PSDscResources'
InstallationPolicy = 'Trusted'
}
$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)) {
if ($env:TF_BUILD -eq 'true') {
Set-ItResult -Skipped -Because "cannot install PSDscResources module during tests in Azure DevOps"
}
$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)) {
if ($env:TF_BUILD -eq 'true') {
Set-ItResult -Skipped -Because "cannot install PSDscResources module during tests in Azure DevOps"
}
$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)) {
if ($env:TF_BUILD -eq 'true') {
Set-ItResult -Skipped -Because "cannot install PSDscResources module during tests in Azure DevOps"
}
$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"
}
if ($env:TF_BUILD -eq 'true') {
Set-ItResult -Skipped -Because "cannot install PSDscResources module during tests in Azure DevOps"
}
$resourceName="TestRes"
$moduleName="TestEmbeddedDSCResource"
$embObj = @(New-Object -TypeName psobject -Property @{embclassprop="property1"})
Install-Module -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 ($env:TF_BUILD -eq 'true') {
Set-ItResult -Skipped -Because "cannot install PSDscResources module during tests in Azure DevOps"
}
if (-not $IsWindows) {
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" {
AfterAll { AfterAll {
$Global:ProgressPreference = $origProgress $Global:ProgressPreference = $origProgress
} }
@@ -171,7 +515,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 +524,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" {
BeforeAll {
$module = Get-Module PowerShellGet -ListAvailable | Sort-Object -Property Version -Descending | Select-Object -First 1
$psGetModuleVersion = $module.Version.ToString()
}
It "Should be able to compile a MOF using PSModule resource" {
if ($env:GITHUB_ACTIONS -eq 'true' -or $env:TF_BUILD -eq 'true') {
Set-ItResult -Skipped -Because "does not work in CI"
}
if (-not $IsWindows) {
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
}
}
+36
View File
@@ -0,0 +1,36 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
param(
[ValidateSet("PSGallery", "CFS")]
[string]$PSRepository = "PSGallery"
)
if ($PSRepository -eq "CFS" -and -not (Get-PSResourceRepository -Name CFS -ErrorAction SilentlyContinue)) {
Register-PSResourceRepository -Name CFS -Uri "https://pkgs.dev.azure.com/powershell/PowerShell/_packaging/PowerShellGalleryMirror/nuget/v3/index.json"
}
# NOTE: Due to a bug in Install-PSResource with upstream feeds, we have to
# request an exact version. Otherwise, if a newer version is available in the
# upstream feed, it will fail to install any version at all.
Install-PSResource -Verbose -TrustRepository -RequiredResource @{
platyPS = @{
version = "0.14.2"
repository = $PSRepository
}
Pester = @{
version = "5.7.1"
repository = $PSRepository
}
PSDscResources = @{
version = "2.12.0.0"
repository = $PSRepository
}
XmlContentDsc = @{
version = "0.0.1"
repository = $PSRepository
}
xWebAdministration = @{
version = "3.3.0"
repository = $PSRepository
}
}
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<SignConfigXML>
<job platform="" configuration="" dest="__OUTPATHROOT__" jobname="PSDesiredStateConfiguration Catalog" approvers="vigarg;gstolt">
<file src="__INPATHROOT__\PSDesiredStateConfiguration\PSDesiredStateConfiguration.cat" signType="AuthenticodeFormer" dest="__OUTPATHROOT__\PSDesiredStateConfiguration\PSDesiredStateConfiguration.cat" />
</job>
</SignConfigXML>
@@ -1,100 +0,0 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
param(
[Parameter(Mandatory)]
[string] $Path,
[string[]] $AuthenticodeDualFiles,
[string[]] $AuthenticodeFiles,
[string[]] $NuPkgFiles,
[string[]] $MacDeveloperFiles,
[string[]] $LinuxFiles,
[Parameter(Mandatory)]
[string] $rootPath
)
$resolvedRootPath = (Resolve-Path $rootPath).ProviderPath
if ((!$AuthenticodeDualFiles -or $AuthenticodeDualFiles.Count -eq 0) -and
(!$AuthenticodeFiles -or $AuthenticodeFiles.Count -eq 0) -and
(!$NuPkgFiles -or $NuPkgFiles.Count -eq 0) -and
(!$MacDeveloperFiles -or $MacDeveloperFiles.Count -eq 0) -and
(!$LinuxFiles -or $LinuxFiles.Count -eq 0))
{
throw "At least one file must be specified"
}
function New-Attribute
{
param(
[Parameter(Mandatory)]
[string]$Name,
[Parameter(Mandatory)]
[object]$Value,
[Parameter(Mandatory)]
[System.Xml.XmlElement]$Element
)
$attribute = $signingXml.CreateAttribute($Name)
$attribute.Value = $value
$null = $fileElement.Attributes.Append($attribute)
}
function New-FileElement
{
param(
[Parameter(Mandatory)]
[string]$File,
[Parameter(Mandatory)]
[string]$SignType,
[Parameter(Mandatory)]
[System.Xml.XmlDocument]$XmlDoc,
[Parameter(Mandatory)]
[System.Xml.XmlElement]$Job
)
if(Test-Path -Path $file)
{
$name = Split-Path -Leaf -Path $File
$fileElement = $XmlDoc.CreateElement("file")
$src = $file.replace($resolvedRootPath,'__INPATHROOT__\')
$dest = $file.replace($resolvedRootPath,'__OUTPATHROOT__\')
New-Attribute -Name 'src' -value $src -Element $fileElement
New-Attribute -Name 'signType' -value $SignType -Element $fileElement
New-Attribute -Name 'dest' -value $dest -Element $fileElement
$null = $job.AppendChild($fileElement)
}
else
{
Write-Warning -Message "Skipping $SignType; $File because it does not exist"
}
}
[xml]$signingXml = get-content (Join-Path -Path $PSScriptRoot -ChildPath 'packagesigning.xml')
$job = $signingXml.SignConfigXML.job
foreach($file in $AuthenticodeDualFiles)
{
New-FileElement -File $file -SignType 'AuthenticodeDual' -XmlDoc $signingXml -Job $job
}
foreach($file in $AuthenticodeFiles)
{
New-FileElement -File $file -SignType 'AuthenticodeFormer' -XmlDoc $signingXml -Job $job
}
foreach($file in $NuPkgFiles)
{
New-FileElement -File $file -SignType 'NuGet' -XmlDoc $signingXml -Job $job
}
foreach ($file in $MacDeveloperFiles) {
New-FileElement -File $file -SignType 'MacDeveloper' -XmlDoc $signingXml -Job $job
}
foreach ($file in $LinuxFiles) {
New-FileElement -File $file -SignType 'LinuxPack' -XmlDoc $signingXml -Job $job
}
$null = new-item -Path $path -ItemType file -Force
$savePath = (Resolve-Path $Path).ProviderPath
$signingXml.Save($savePath)
-6
View File
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- template used by generatePackageSigning.ps1 -->
<SignConfigXML>
<job platform="" configuration="" dest="__OUTPATHROOT__\signed" jobname="PSDesiredStateConfiguration module" approvers="vigarg;gstolt">
</job>
</SignConfigXML>
-9
View File
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- template used by generatePackageSigning.ps1 -->
<SignConfigXML>
<job platform="" configuration="" dest="__OUTPATHROOT__\signed" jobname="PSDesiredStateConfiguration module" approvers="vigarg;gstolt">
<file src="__INPATHROOT__\PSDesiredStateConfiguration/helpers/DscResourceInfo.psm1" signType="AuthenticodeFormer" dest="__OUTPATHROOT__\PSDesiredStateConfiguration/helpers/DscResourceInfo.psm1" />
<file src="__INPATHROOT__\PSDesiredStateConfiguration/PSDesiredStateConfiguration.psd1" signType="AuthenticodeFormer" dest="__OUTPATHROOT__\PSDesiredStateConfiguration/PSDesiredStateConfiguration.psd1" />
<file src="__INPATHROOT__\PSDesiredStateConfiguration/PSDesiredStateConfiguration.psm1" signType="AuthenticodeFormer" dest="__OUTPATHROOT__\PSDesiredStateConfiguration/PSDesiredStateConfiguration.psm1" />
</job>
</SignConfigXML>
-379
View File
@@ -1,379 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<xmldata>
<PckFileTypes TotalTypes="35" TotalExts="198" UnsupportedFilesOnly="False">
<Type ID="0" Check="1">
<Name>Pure Text Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.txt</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.des</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.pwd</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.asm</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.cmd</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ini</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.poc</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.pwt</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hpj</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.sql</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.inf</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.log</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.def</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.url</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.bat</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.aspx</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.idl</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.sys</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.resources</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.strings</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.md</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.yml</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.yaml</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.spelling</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.gitignore</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.gitattributes</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.gitmodules</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.csv</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.tsv</Ext>
</Extensions>
</Type>
<Type ID="1" Check="1">
<Name>CodeFiles</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.frm</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.inc</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.cpp</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.cls</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.c</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hpp</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.vbs</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.java</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.cs</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.cxx</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.h</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.jav</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.bas</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxx</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.js</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.pl</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.rc</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.vb</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.json</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.resjson</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.fs</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.fsi</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.fsx</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.m</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.psm1</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.config</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ps1</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.psd1</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.cmake</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.sh</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.cshtml</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.plist</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.mof</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.mc</Ext>
</Extensions>
</Type>
<Type ID="2" Check="1">
<Name>XML Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xml</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxa</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxk</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxl</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xsl</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxc</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxt</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxm</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.resx</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxe</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxf</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxv</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.acctb</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.accfl</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xaml</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ttml</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ddue</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.sln</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.props</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ps1xml</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.csproj</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xsd</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.svg</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.clixml</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.nuspec</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.cdxml</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.manifest</Ext>
</Extensions>
</Type>
<Type ID="3" Check="1">
<Name>Microsoft Word Documents</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.doc</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.dot</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.wiz</Ext>
</Extensions>
</Type>
<Type ID="4" Check="1">
<Name>Microsoft Access Database Compatible</Name>
<Extensions>
<Ext Check="0" UseCustomParser="0" DllPath="" ClassName="">.mdb</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.mda</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.mde</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.mpd</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.mdt</Ext>
</Extensions>
</Type>
<Type ID="5" Check="1">
<Name>Microsoft PowerPoint Presentation</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ppt</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.pot</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.pps</Ext>
</Extensions>
</Type>
<Type ID="6" Check="1">
<Name>Microsoft Publisher Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.pub</Ext>
</Extensions>
</Type>
<Type ID="7" Check="1">
<Name>Microsoft Excel Workbooks</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xls</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xlt</Ext>
</Extensions>
</Type>
<Type ID="8" Check="1">
<Name>Pure Binary Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.com</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.bin</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.tlb</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.drv</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.fon</Ext>
<Ext Check="0" UseCustomParser="0" DllPath="" ClassName="">.blg</Ext>
<Ext Check="0" UseCustomParser="0" DllPath="" ClassName="">.gif</Ext>
<Ext Check="0" UseCustomParser="0" DllPath="" ClassName="">.png</Ext>
<Ext Check="0" UseCustomParser="0" DllPath="" ClassName="">.icns</Ext>
<Ext Check="0" UseCustomParser="0" DllPath="" ClassName="">.ico</Ext>
<Ext Check="0" UseCustomParser="0" DllPath="" ClassName="">.bmp</Ext>
<Ext Check="0" UseCustomParser="0" DllPath="" ClassName="">.pfx</Ext>
</Extensions>
</Type>
<Type ID="9" Check="1">
<Name>Localization resource databases</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.edb</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.lcl</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xlf</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xliff</Ext>
</Extensions>
</Type>
<Type ID="10" Check="1">
<Name>Microsoft Project Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.mpp</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.mpt</Ext>
</Extensions>
</Type>
<Type ID="11" Check="1">
<Name>Microsoft Visio Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.vsd</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.vdx</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.vss</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.vst</Ext>
</Extensions>
</Type>
<Type ID="12" Check="1">
<Name>Windows Installer databases</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.msi</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.msm</Ext>
</Extensions>
</Type>
<Type ID="13" Check="1">
<Name>Zip Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.zip</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.accdt</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.axtr</Ext>
</Extensions>
</Type>
<Type ID="14" Check="1">
<Name>Cabinet / MS Compression Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.cab</Ext>
</Extensions>
</Type>
<Type ID="15" Check="1">
<Name>Table driven IME lexicons</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.mb</Ext>
</Extensions>
</Type>
<Type ID="16" Check="1">
<Name>IME ( IMD ) Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.imd</Ext>
</Extensions>
</Type>
<Type ID="17" Check="1">
<Name>TrueType Font Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ttf</Ext>
</Extensions>
</Type>
<Type ID="18" Check="1">
<Name>Microsoft Outlook Mail Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.msg</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.oft</Ext>
</Extensions>
</Type>
<Type ID="19" Check="1">
<Name>HTML Help 2.0 Files / InfoTech5.x Storage System Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.its</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxh</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxr</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxw</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxi</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxs</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxq</Ext>
</Extensions>
</Type>
<Type ID="20" Check="1">
<Name>Adobe Acrobat PDF Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.pdf</Ext>
</Extensions>
</Type>
<Type ID="21" Check="1">
<Name>HTML Files / Web Page</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.htm</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.dtd</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hhk</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.htw</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.asp</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.htc</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.htx</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.html</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hhc</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.css</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.stm</Ext>
</Extensions>
</Type>
<Type ID="22" Check="1">
<Name>Rich Text Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.rtf</Ext>
</Extensions>
</Type>
<Type ID="23" Check="1">
<Name>Windows 3.x Write Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.wri</Ext>
</Extensions>
</Type>
<Type ID="24" Check="1">
<Name>MHTML Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.eml</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.nws</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.mht</Ext>
</Extensions>
</Type>
<Type ID="25" Check="1">
<Name>Word 2007 Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.docx</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.docm</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.dotx</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.dotm</Ext>
</Extensions>
</Type>
<Type ID="26" Check="1">
<Name>Excel 2007 Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xlsx</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xlsm</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xltx</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xltm</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xlsb</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xlam</Ext>
</Extensions>
</Type>
<Type ID="27" Check="1">
<Name>Power Point 2007 Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.pptx</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.pptm</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.potx</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.potm</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ppsx</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ppsm</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ppam</Ext>
</Extensions>
</Type>
<Type ID="28" Check="1">
<Name>Access 2007 Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.accdb</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.accde</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.accdr</Ext>
</Extensions>
</Type>
<Type ID="29" Check="1">
<Name>Win32/64-based executable (image) Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.exe</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.dll</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ocx</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.scr</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.acm</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.rll</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.cpl</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.mui</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ax</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ime</Ext>
</Extensions>
</Type>
<Type ID="30" Check="1">
<Name>HTML Help 1.0 Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.chm</Ext>
</Extensions>
</Type>
<Type ID="31" Check="1">
<Name>LocStudio lsg</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.lsg</Ext>
</Extensions>
</Type>
<Type ID="32" Check="1">
<Name>Microsoft Office OneNote Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.one</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.onepkg</Ext>
</Extensions>
</Type>
<Type ID="33" Check="1">
<Name>Custom Parsers</Name>
<Extensions>
</Extensions>
</Type>
<Type ID="34" Check="1">
<Name>Visio 2011 Files</Name>
<Extensions>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.vstx</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.vsdx</Ext>
<Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.vssx</Ext>
</Extensions>
</Type>
</PckFileTypes>
</xmldata>