diff --git a/README.md b/README.md index f464d79..49c2eaf 100644 --- a/README.md +++ b/README.md @@ -1,130 +1,23 @@ -PowerShell Community DSC Modules -=========== +# BIG CHANGES -Desired State Configuration Modules to augment the initial offering in PowerShell V4 +We have moved the DSC Resources into their own repositories under PowerShell.Org. -Check out my blog series on DSC at PowerShell.org: -- Overview () -- Configuring the Pull Server (REST version) () -- Creating Configurations (, ) -- Configuring Clients () -- Building Custom Resources () -- Packaging Custom Resources -- Advanced Client Targeting +## Why? +* To make it easier to track issues for individual resources +* To allow more community members to participate in the maintence of these resources +* To make it easier to automate publishing of individual resources to PowerShellGet and other sources +## How can I contribute? -ToDo -===== -- [x] Initial upload -- [x] Make New-MofFile handle more data types and complex data types -- [x] Improve the DSC Module creation documentation for General Availability -- [ ] Add samples of complete configurations -- [ ] Add samples of composite configurations -- [ ] MORE Modules! +### If you have a new resource you want to share, +* File an issue here and let us know what the name of the project should be. +* We'll create a repository and make you an contributor to that repository. +* You can then populate that repository via a pull request. -###Required Modules -In order to run some of the code in this pack some outside resources are needed. Make sure the following are installed on the dev system. +### If you want to help maintain an existing resource +* Start by contributing something.. a bugfix, documentation, file issues +* After a contribution or two, file an issue requesting to become a maintainer for the project +* We (along with the other maintainers - if any exist), can start a conversation about how you can help the project. -* Pester () - - -Getting Started With DSC Modules --------------------------------- - - -NOTE: - - -There are two sets of MOF (Managed Object Framework) files generated in this process. Each provider module has a MOF file defining a class representing the parameters to the functions in provider module. - -The second type of MOF file is created by running the configuration, with one generated per target node. This MOF file is the serialization of the configuration defined in MOF format. It references the MOF classes defined in the provider modules schema files and contains the values supplied in the configuration associated to the appropriate parameters. - -The general flow of Resource Processing in DSC (from Configuration MOF to Desired State) - -When you run the configuration function, a MOF file for each node is generated. This describes the state the machine should be in after processing the MOF file. The generated configuration MOF will note the resources used and their host module (see below). - -For each resource defined, the DSC engine uses the classes defined in the MOF to marshal parameters to call the PowerShell DSC resource (which is basically a PowerShell module). - -The DSC engine calls Test-TargetResource with the parameters defined in the MOF file (as mapped in the schema MOF). If Test-TargetResource returns $false, then Set-TargetResource is called with the same parameter set. - -###DSC Resources - -DSC Resources are nested in a module (which I'll call the host module). Resources are located in a subfolder in a host module called DscResources. One host module can contain zero or more DSC Resources. - -DSC Resources are modules as well, but by not being located directly on the PSModulePath, they won't clutter up your environment. - -####Versioning - -DSC Resources are versioned by the module version of their host module. - - -####Naming - -The module name will be the resource name when configurations are defined, unless you specify an alias name for the module in the MOF schema (detailed below). - - -####Functions - -- Set-TargetResource - - Set-TargetResource is called if Test-TargetResource (described in a bit) returns false. Test-TargetResource is called with the same parameters as Set-TargetResource. - - This function implements the change requested. You'll need to support both the case of Ensure = 'Present' and Ensure = 'Absent'. If this resource represents a multi-step process and that process needs to support suspend/resume or requires reboots, it may be an indication that you want to break it into several resources, otherwise you'll have to implement the stage checking in this function. - - Each parameter for this function will need to be modeled in the CIM schema in a CIM class named for the resource type, so if you expect structured objects, you'll need to define comprehensive schema documents. - - Logging for this function occurs in the form of verbose output (which is written to the DSC event log). - - While the DSC engine should only call this function if Test-TargetResource returns false, it would be prudent to write the system state changes in as idempotent a manner as possible. - -- Test-TargetResource - - Test-TargetResource validates whether a resource configuration is in the desired state. - - Test-TargetResource offers the same parameters as Set-TargetResource. - - Test-TargetResource evaluate the final state of the resource (not intermediate steps) and returns a $true if the configuration matches or $false if the configuration does not. - - This function needs to support both Ensure = 'Present' and Ensure = 'Absent' declarations. - -- Get-TargetResource - - This function inventories the resource based on the key values (mandatory parameters) for the CIM schema. - - Get-TargetResource returns a hashtable containing the values that match the current state of the resource configuration. - - Get-TargetResource only needs to support parameters that are noted as key values in the schema.mof file (mandatory parameters in the Set-TargetResource and Get-TargetResource functions). - - - -###The Schema - -The final bit of creating a provider module is the MOF schema file. The MOF schema file defines a CIM class used for serializing the parameter values from the configuration file and deserializing to apply as parameters to the call the above functions. - -Detailed documentation about MOF datatypes can be found here - [http://msdn.microsoft.com/en-us/library/cc250850.aspx](http://msdn.microsoft.com/en-us/library/cc250850.aspx) - - - -####In creating the MOF schema file, there are a couple of rules. - -- All resource classes (those that represent the parameters for the Set-TargetResource) must inherit from OMI_BaseResource. -- The file is named {resource}.schema.mof -- Classes are attributed with a version number which is currently meaningless - -- Classes can be attributed with a FriendlyName, which would be the name that the resource would use in the configuration declaration. The full class name is used in the generated configuration MOF. -- Mandatory parameters are annotated as [Key] values. -- Other parameters are annotated as [Write] values. - - If there is a ValidateSet or Enumeration, they are represented in a ValueMap and Values combination as part of the Write annotation. - -- The file encoding has to be Unicode or ASCII. UTF8 will fail validation. - - -Validation of the MOF file should be done by running: - -mofcomp.exe -check {path to your mof file}. - - - -####Example of a very basic schema.mof file: - -```` -[version("1.0.0"), FriendlyName("PowerPlan")] - -class PowerPlan : OMI_BaseResource - -{ - -[Key] string Name; - -[write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; - -}; -```` +## What is still here? +So far, the DSC Tooling. We'll probably break that out as well. The focus of the repository will be documentation, examples and filing of issues that are broader than any one resource or tool. diff --git a/README.old.md b/README.old.md new file mode 100644 index 0000000..f464d79 --- /dev/null +++ b/README.old.md @@ -0,0 +1,130 @@ +PowerShell Community DSC Modules +=========== + +Desired State Configuration Modules to augment the initial offering in PowerShell V4 + +Check out my blog series on DSC at PowerShell.org: +- Overview () +- Configuring the Pull Server (REST version) () +- Creating Configurations (, ) +- Configuring Clients () +- Building Custom Resources () +- Packaging Custom Resources +- Advanced Client Targeting + + +ToDo +===== +- [x] Initial upload +- [x] Make New-MofFile handle more data types and complex data types +- [x] Improve the DSC Module creation documentation for General Availability +- [ ] Add samples of complete configurations +- [ ] Add samples of composite configurations +- [ ] MORE Modules! + +###Required Modules +In order to run some of the code in this pack some outside resources are needed. Make sure the following are installed on the dev system. + +* Pester () + + +Getting Started With DSC Modules +-------------------------------- + + +NOTE: + + +There are two sets of MOF (Managed Object Framework) files generated in this process. Each provider module has a MOF file defining a class representing the parameters to the functions in provider module. + +The second type of MOF file is created by running the configuration, with one generated per target node. This MOF file is the serialization of the configuration defined in MOF format. It references the MOF classes defined in the provider modules schema files and contains the values supplied in the configuration associated to the appropriate parameters. + +The general flow of Resource Processing in DSC (from Configuration MOF to Desired State) + +When you run the configuration function, a MOF file for each node is generated. This describes the state the machine should be in after processing the MOF file. The generated configuration MOF will note the resources used and their host module (see below). + +For each resource defined, the DSC engine uses the classes defined in the MOF to marshal parameters to call the PowerShell DSC resource (which is basically a PowerShell module). + +The DSC engine calls Test-TargetResource with the parameters defined in the MOF file (as mapped in the schema MOF). If Test-TargetResource returns $false, then Set-TargetResource is called with the same parameter set. + +###DSC Resources + +DSC Resources are nested in a module (which I'll call the host module). Resources are located in a subfolder in a host module called DscResources. One host module can contain zero or more DSC Resources. + +DSC Resources are modules as well, but by not being located directly on the PSModulePath, they won't clutter up your environment. + +####Versioning + +DSC Resources are versioned by the module version of their host module. + + +####Naming + +The module name will be the resource name when configurations are defined, unless you specify an alias name for the module in the MOF schema (detailed below). + + +####Functions + +- Set-TargetResource + - Set-TargetResource is called if Test-TargetResource (described in a bit) returns false. Test-TargetResource is called with the same parameters as Set-TargetResource. + - This function implements the change requested. You'll need to support both the case of Ensure = 'Present' and Ensure = 'Absent'. If this resource represents a multi-step process and that process needs to support suspend/resume or requires reboots, it may be an indication that you want to break it into several resources, otherwise you'll have to implement the stage checking in this function. + - Each parameter for this function will need to be modeled in the CIM schema in a CIM class named for the resource type, so if you expect structured objects, you'll need to define comprehensive schema documents. + - Logging for this function occurs in the form of verbose output (which is written to the DSC event log). + - While the DSC engine should only call this function if Test-TargetResource returns false, it would be prudent to write the system state changes in as idempotent a manner as possible. + +- Test-TargetResource + - Test-TargetResource validates whether a resource configuration is in the desired state. + - Test-TargetResource offers the same parameters as Set-TargetResource. + - Test-TargetResource evaluate the final state of the resource (not intermediate steps) and returns a $true if the configuration matches or $false if the configuration does not. + - This function needs to support both Ensure = 'Present' and Ensure = 'Absent' declarations. + +- Get-TargetResource + - This function inventories the resource based on the key values (mandatory parameters) for the CIM schema. + - Get-TargetResource returns a hashtable containing the values that match the current state of the resource configuration. + - Get-TargetResource only needs to support parameters that are noted as key values in the schema.mof file (mandatory parameters in the Set-TargetResource and Get-TargetResource functions). + + + +###The Schema + +The final bit of creating a provider module is the MOF schema file. The MOF schema file defines a CIM class used for serializing the parameter values from the configuration file and deserializing to apply as parameters to the call the above functions. + +Detailed documentation about MOF datatypes can be found here - [http://msdn.microsoft.com/en-us/library/cc250850.aspx](http://msdn.microsoft.com/en-us/library/cc250850.aspx) + + + +####In creating the MOF schema file, there are a couple of rules. + +- All resource classes (those that represent the parameters for the Set-TargetResource) must inherit from OMI_BaseResource. +- The file is named {resource}.schema.mof +- Classes are attributed with a version number which is currently meaningless + +- Classes can be attributed with a FriendlyName, which would be the name that the resource would use in the configuration declaration. The full class name is used in the generated configuration MOF. +- Mandatory parameters are annotated as [Key] values. +- Other parameters are annotated as [Write] values. + - If there is a ValidateSet or Enumeration, they are represented in a ValueMap and Values combination as part of the Write annotation. + +- The file encoding has to be Unicode or ASCII. UTF8 will fail validation. + + +Validation of the MOF file should be done by running: + +mofcomp.exe -check {path to your mof file}. + + + +####Example of a very basic schema.mof file: + +```` +[version("1.0.0"), FriendlyName("PowerPlan")] + +class PowerPlan : OMI_BaseResource + +{ + +[Key] string Name; + +[write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; + +}; +```` diff --git a/Resources/Craig-Martin/DSCResources/GlobalAssemblyCache/GlobalAssemblyCache.psm1 b/Resources/Craig-Martin/DSCResources/GlobalAssemblyCache/GlobalAssemblyCache.psm1 deleted file mode 100644 index 478e56a..0000000 --- a/Resources/Craig-Martin/DSCResources/GlobalAssemblyCache/GlobalAssemblyCache.psm1 +++ /dev/null @@ -1,145 +0,0 @@ -<# -.Synopsys -The Get-TargetResource cmdlet. -#> -function Get-TargetResource -{ - param - ( - [ValidateSet("Present", "Absent")] - [System.String] - $Ensure = "Present", - - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [System.String] - $Name, - - [System.String] - $Version - ) - - $gac = Get-GacAssembly -Name $Name -Version $Version - - if ($gac -ne $null) - { - return @{ - Ensure = "Present"; - Name = $gac.Name - Version = $gac.Version - } - } - else - { - return @{ - Ensure = "Absent"; - Name = $Name - Version = $Version - } - } -} - -<# -.Synopsys -The Set-TargetResource cmdlet. -#> -function Set-TargetResource -{ - param - ( - [ValidateSet("Present", "Absent")] - [System.String] - $Ensure = "Present", - - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [System.String] - $Name, - - [System.String] - $Version, - - [ValidateNotNullOrEmpty()] - [System.String] - $AssemblyFile - ) - - $gac = Get-GacAssembly -Name $Name -Version $Version - - if ($Ensure -eq 'Present') - { - Write-Verbose "Ensure -eq 'Present'" - if ($gac -eq $null) - { - Write-Verbose "GAC item is missing, so adding it: $AssemblyFile" - Add-GacAssembly -Path $AssemblyFile - } - } - elseif($Ensure -eq 'Absent') - { - Write-Verbose "Ensure -eq 'Absent'" - if ($gac -ne $null) - { - Write-Verbose "GAC item is present, so removing it: $Name" - $gac | Remove-GacAssembly - } - } -} - -<# -.Synopsys -The Test-TargetResource cmdlet is used to validate if the resource is in a state as expected in the instance document. -#> -function Test-TargetResource -{ - param - ( - [ValidateSet("Present", "Absent")] - [System.String] - $Ensure = "Present", - - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [System.String] - $Name, - - [System.String] - $Version, - - [ValidateNotNullOrEmpty()] - [System.String] - $AssemblyFile - ) - - $gac = Get-GacAssembly -Name $Name -Version $Version - - if ($Ensure -eq 'Present') - { - if ($gac -eq $null) - { - return $false - } - else - { - return $true - } - } - elseif($Ensure -eq 'Absent') - { - if ($gac -ne $null) - { - return $false - } - else - { - return $true - } - } - - if (Test-Path $AssemblyFile) - { - return $true - } -} - - diff --git a/Resources/Craig-Martin/DSCResources/GlobalAssemblyCache/GlobalAssemblyCache.schema.mof b/Resources/Craig-Martin/DSCResources/GlobalAssemblyCache/GlobalAssemblyCache.schema.mof deleted file mode 100644 index b6c7add..0000000 --- a/Resources/Craig-Martin/DSCResources/GlobalAssemblyCache/GlobalAssemblyCache.schema.mof +++ /dev/null @@ -1,9 +0,0 @@ -[ClassVersion("1.0.0"), FriendlyName("GlobalAssemblyCache")] -class GlobalAssemblyCache : OMI_BaseResource -{ - [Key] string Name; - [write] string Version; - [write] string AssemblyFile; - [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; -}; - diff --git a/Resources/Craig-Martin/DSCResources/GlobalAssemblyCache/GlobalAssemblyCacheSample.psm1 b/Resources/Craig-Martin/DSCResources/GlobalAssemblyCache/GlobalAssemblyCacheSample.psm1 deleted file mode 100644 index dbf0ed0..0000000 --- a/Resources/Craig-Martin/DSCResources/GlobalAssemblyCache/GlobalAssemblyCacheSample.psm1 +++ /dev/null @@ -1,28 +0,0 @@ -Configuration GlobalAssemlyCacheSample -{ - Node "CraigRegWeb1" - { - - ### Make sure the GAC has the PowerShell Workflow for FIM - GlobalAssemblyCache FimWorkflowLibrary - { - Ensure = "Present" - Name = "FimExtensions.FimActivityLibrary" - Version = "2.0.0.0" - AssemblyFile = "C:\tfs\Output\FimExtensions.FimActivityLibrary.dll" - } - } -} - -GlobalAssemlyCacheSample - -## Load the PowerShell GAC module (http://powershellgac.codeplex.com/) -# Import-Module gac - -## Add an assembly to the GAC - use this to test that DSC can validate it -# Add-GacAssembly -Path C:\tfs\Output\FimExtensions.FimActivityLibrary.dll - -### Remove the assembly from the GAC - use this to test that DSC can put it back -# Get-GacAssembly -Name FimExtensions.FimActivityLibrary | Remove-GacAssembly - - diff --git a/Resources/Craig-Martin/DSCResources/GlobalAssemblyCache/README.txt b/Resources/Craig-Martin/DSCResources/GlobalAssemblyCache/README.txt deleted file mode 100644 index 62b2f7a..0000000 --- a/Resources/Craig-Martin/DSCResources/GlobalAssemblyCache/README.txt +++ /dev/null @@ -1,4 +0,0 @@ -This custom DSC resource depends on the PowerShell GAC module from: http://powershellgac.codeplex.com/ - - - diff --git a/Resources/Craig-Martin/GlobalAssemblyCache.psd1 b/Resources/Craig-Martin/GlobalAssemblyCache.psd1 deleted file mode 100644 index d868dd8..0000000 --- a/Resources/Craig-Martin/GlobalAssemblyCache.psd1 +++ /dev/null @@ -1,42 +0,0 @@ -@{ - -# Version number of this module. -ModuleVersion = '1.0' - -# ID used to uniquely identify this module -GUID = '04418a65-782d-4a8f-a4e1-6a8ea078a880' - -# Author of this module -Author = 'Craig Martin' - -# Company or vendor of this module -CompanyName = 'PowerShell.org' - -# Copyright statement for this module -Copyright = '(c) 2013 PowerShell.org. All rights reserved.' - -# Description of the functionality provided by this module -Description = 'This Module is used to support the execution of query, install & uninstall functionalities on local global assembly cache items through Get, Set and Test API on the DSC managed nodes.' - -# Minimum version of the Windows PowerShell engine required by this module -PowerShellVersion = '3.0' - -# Minimum version of the common language runtime (CLR) required by this module -CLRVersion = '4.0' - -# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess -NestedModules = @("GlobalAssemblyCache.psm1") - -# Functions to export from this module -FunctionsToExport = @("Get-TargetResource", "Set-TargetResource", "Test-TargetResource") - -# HelpInfo URI of this module - -# HelpInfoURI = '' - -# Modules that must be imported into the global environment prior to importing this module -RequiredModules = @("gac") - -} - - diff --git a/Resources/PowerShellAccessControl/DSCResources/PowerShellAccessControl_cAccessControlEntry/PowerShellAccessControl_cAccessControlEntry.psm1 b/Resources/PowerShellAccessControl/DSCResources/PowerShellAccessControl_cAccessControlEntry/PowerShellAccessControl_cAccessControlEntry.psm1 deleted file mode 100644 index 95721f4..0000000 Binary files a/Resources/PowerShellAccessControl/DSCResources/PowerShellAccessControl_cAccessControlEntry/PowerShellAccessControl_cAccessControlEntry.psm1 and /dev/null differ diff --git a/Resources/PowerShellAccessControl/DSCResources/PowerShellAccessControl_cAccessControlEntry/PowerShellAccessControl_cAccessControlEntry.schema.mof b/Resources/PowerShellAccessControl/DSCResources/PowerShellAccessControl_cAccessControlEntry/PowerShellAccessControl_cAccessControlEntry.schema.mof deleted file mode 100644 index c3f5da4..0000000 Binary files a/Resources/PowerShellAccessControl/DSCResources/PowerShellAccessControl_cAccessControlEntry/PowerShellAccessControl_cAccessControlEntry.schema.mof and /dev/null differ diff --git a/Resources/PowerShellAccessControl/DSCResources/PowerShellAccessControl_cSecurityDescriptor/PowerShellAccessControl_cSecurityDescriptor.psm1 b/Resources/PowerShellAccessControl/DSCResources/PowerShellAccessControl_cSecurityDescriptor/PowerShellAccessControl_cSecurityDescriptor.psm1 deleted file mode 100644 index aa6d898..0000000 Binary files a/Resources/PowerShellAccessControl/DSCResources/PowerShellAccessControl_cSecurityDescriptor/PowerShellAccessControl_cSecurityDescriptor.psm1 and /dev/null differ diff --git a/Resources/PowerShellAccessControl/DSCResources/PowerShellAccessControl_cSecurityDescriptor/PowerShellAccessControl_cSecurityDescriptor.schema.mof b/Resources/PowerShellAccessControl/DSCResources/PowerShellAccessControl_cSecurityDescriptor/PowerShellAccessControl_cSecurityDescriptor.schema.mof deleted file mode 100644 index a3a65c0..0000000 Binary files a/Resources/PowerShellAccessControl/DSCResources/PowerShellAccessControl_cSecurityDescriptor/PowerShellAccessControl_cSecurityDescriptor.schema.mof and /dev/null differ diff --git a/Resources/PowerShellAccessControl/DSCResources/PowerShellAccessControl_cSecurityDescriptorSddl/PowerShellAccessControl_cSecurityDescriptorSddl.psm1 b/Resources/PowerShellAccessControl/DSCResources/PowerShellAccessControl_cSecurityDescriptorSddl/PowerShellAccessControl_cSecurityDescriptorSddl.psm1 deleted file mode 100644 index f5a4e96..0000000 Binary files a/Resources/PowerShellAccessControl/DSCResources/PowerShellAccessControl_cSecurityDescriptorSddl/PowerShellAccessControl_cSecurityDescriptorSddl.psm1 and /dev/null differ diff --git a/Resources/PowerShellAccessControl/DSCResources/PowerShellAccessControl_cSecurityDescriptorSddl/PowerShellAccessControl_cSecurityDescriptorSddl.schema.mof b/Resources/PowerShellAccessControl/DSCResources/PowerShellAccessControl_cSecurityDescriptorSddl/PowerShellAccessControl_cSecurityDescriptorSddl.schema.mof deleted file mode 100644 index c911961..0000000 Binary files a/Resources/PowerShellAccessControl/DSCResources/PowerShellAccessControl_cSecurityDescriptorSddl/PowerShellAccessControl_cSecurityDescriptorSddl.schema.mof and /dev/null differ diff --git a/Resources/PowerShellAccessControl/PowerShellAccessControl.format.ps1xml b/Resources/PowerShellAccessControl/PowerShellAccessControl.format.ps1xml deleted file mode 100644 index c4bd145..0000000 --- a/Resources/PowerShellAccessControl/PowerShellAccessControl.format.ps1xml +++ /dev/null @@ -1,415 +0,0 @@ - - - - EffectiveAccess-GroupingFormat - - - - - - 4 - - - - "Principal: {0}`nObject: {1}" -f $_.IdentityReference, $_.DisplayName - - - - - - - - - - - - ACE-GroupingFormat - - - - - - 4 - - - - "DisplayName: $($_.DisplayName)`n$($_.InheritanceString)" - - - - - - - - - - - - - - - PowerShellAccessControl.Types.AdaptedSecurityDescriptor - - PowerShellAccessControl.Types.AdaptedSecurityDescriptor - - - - - - - - - - - - - - - DisplayName - - - AccessToString - - - - - - - - PowerShellAccessControl.Types.AdaptedSecurityDescriptor - - PowerShellAccessControl.Types.AdaptedSecurityDescriptor - - - - - - - DisplayName - - - Path - - - ObjectType - - - Owner - - - Group - - - AreAccessRulesProtected - - - - AccessToString - - - AreAuditRulesProtected - - - - AuditToString - - - - - $MaxLength = 500 - - if ($_.Sddl.Length -gt $MaxLength) { - "{0}..." -f $_.Sddl.SubString(0,$MaxLength) - } - else { - $_.Sddl - } - - - - - - - - - PowerShellAccessControl.Types.AdaptedAce - - PowerShellAccessControl.Types.AdaptedAce - - - - DisplayName - ACE-GroupingFormat - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if ($_.AuditFlags.value__) { - "{0} ({1})" -f $_.AceType, $_.AuditFlags - } - else { - $_.AceType - } - - - - $_.Principal -replace "(BUILTIN|NT AUTHORITY)\\", "" - - - AccessMaskDisplay - - - - $MaxLength = 150 - if ($_.InheritedFrom.Length -gt $MaxLength) { - "{0}..." -f $_.InheritedFrom.Substring(0, $MaxLength) - } - else { - $_.InheritedFrom - } - - - - - if ($_.AppliesTo -is [enum]) { - $Flags = $_.AppliesTo - $AppliesToShort = "{0,2} {1,2} {2,2}" -f "$(if ([PowerShellAccessControl.AppliesTo]::Object -band $Flags) { 'O' })", - "$(if ([PowerShellAccessControl.AppliesTo]::ChildContainers -band $Flags) { 'CC' })", - "$(if ([PowerShellAccessControl.AppliesTo]::ChildObjects -band $Flags) { 'CO' })" - - if ($_.InheritedObjectAceTypeDisplayName) { - $AppliesToShort += " ({0})" -f $_.InheritedObjectAceTypeDisplayName - } - - $AppliesToShort - } - else { - $_.AppliesTo - } - - - - OnlyApplyToThisContainer - - - - - - - - PowerShellAccessControl.Types.AdaptedAce - - PowerShellAccessControl.Types.AdaptedAce - - - - DisplayName - ACE-GroupingFormat - - - - - - - - - - if ($_.AuditFlags.value__) { - "{0} ({1})" -f $_.AceType, $_.AuditFlags - } - else { - $_.AceType - } - - - - Principal - - - - AccessMaskDisplay - - - InheritedFrom - - - - - if ($_.InheritedObjectAceTypeDisplayName) { - "{0} ({1})" -f $_.AppliesTo, $_.InheritedObjectAceTypeDisplayName - } - else { - $_.AppliesTo - } - - - - - OnlyApplyToThisContainer - - - - - - - - PowerShellAccessControl.Types.EffectiveAccess - - PowerShellAccessControl.Types.EffectiveAccess - - - - - - - - - - - - - - - - IdentityReference - - - DisplayName - - - EffectiveAccess - - - - - - - - PowerShellAccessControl.Types.EffectiveAccess - - PowerShellAccessControl.Types.EffectiveAccess - - - - - - - - IdentityReference - - - DisplayName - - - EffectiveAccess - - - - - - - - PowerShellAccessControl.Types.EffectiveAccessListAllPermissions - - PowerShellAccessControl.Types.EffectiveAccessListAllPermissions - - - - "{0}{1}" -f $_.DisplayName, $_.IdentityReference - EffectiveAccess-GroupingFormat - - - - - - 12 - - - - - - - - - - - Allowed - - - Permission - - - LimitedBy - - - - - - - - PowerShellAccessControl.Types.EffectiveAccessListAllPermissions - - PowerShellAccessControl.Types.EffectiveAccessListAllPermissions - - - - "{0}{1}" -f $_.DisplayName, $_.IdentityReference - EffectiveAccess-GroupingFormat - - - - - - - - Permission - - - Allowed - - - LimitedBy - - - - - - - - diff --git a/Resources/PowerShellAccessControl/PowerShellAccessControl.psd1 b/Resources/PowerShellAccessControl/PowerShellAccessControl.psd1 deleted file mode 100644 index 2424d22..0000000 Binary files a/Resources/PowerShellAccessControl/PowerShellAccessControl.psd1 and /dev/null differ diff --git a/Resources/PowerShellAccessControl/PowerShellAccessControl.psm1 b/Resources/PowerShellAccessControl/PowerShellAccessControl.psm1 deleted file mode 100644 index fee301d..0000000 --- a/Resources/PowerShellAccessControl/PowerShellAccessControl.psm1 +++ /dev/null @@ -1,4109 +0,0 @@ -<# -Version 3.0 BETA notes: - - The help is not finished for the module - - There are some examples of the new functionality, but there will be mroe - - More will be added/fixed before 3.0 is released - -Version 3.1 (or later) features: - - Get-EffectiveAccess will allow additional groups, user claims, and device claims - - Get-EffectiveAccess will take CAP and share permissions into account - - DSC resources will allow CAP to be associated or cleared from an SD - - Set-MandatoryIntegrityLevel - - DSC resources will be able to set MILs - - New-AccessControlEntry will be able to create CallbackAce objects (-Condition parameter??) -#> -<# -New in 3.0: - - New-AdaptedAcl re-written. Now supports ObjectAces. Major changes, so other functions have been modified: - * Synthetic properties added to original CommonAce or ObjectAce. Check this in v2 - * This required changes to formatting, so now FT and FL show a Principal field instead - of an IdentityReference. There is a Principal and SecurityIdentifier property for each - ACE (this is potentially a breaking change) - * Original AccessMask is left untouched, but there is now an AccessMaskDisplay property - (not always true; generic mappings now modify access mask) - * ACEs with the same properties (except access mask) are now merged (like the ACL Editor does) - * Generic rights mapping (see Get-Acl vs Get-SD for C:\WINDOWS, C:\WINDOWS\tracing, HKLM:\SOFTWARE) - - New-AccessControlEntry (and any of the *-AccessControlEntry functions that depend on it) can now support - remote accounts. Just put the account in the '[COMPUTER]\[USER]' format. It can also take SIDs now, too - (string or SecurityIdentifier object) - - Removed -User and -Group aliases for New-Ace. Group alias was causing issues when SD was piped to Add/Remove-Ace (SDs have a - 'Group' property, so it was being bound to principal if the user forgot to add the -Principal (or one of its aliases) as - a named parameter - - If a SID can't be translated locally, the SDObjectType and SDPath are checked to see if it is an AD object, - in which case the domain is pulled from the SDPath and that is used as the remote computer name to attempt - translation, or if the SDPath is in the \\computername\path format, in which case the computer name is pulled - and that is used to attempt translation. If translation still can't happen, the SID object's ToString method - is overloaded and that is assigned to the principal. - - Get-AccessControlEntry: - * Can handle Native .NET SDs (from Get-Acl) - This is b/c Get-SecurityDescriptor will convert a native .NET - SD into an "adapted SD" - * Can work with ObjectAceTypes in GUID or string format - * Because Get-Acl inputs are now converted to PAC objects, New-AdaptedAcl is used directly instead of using the 'Access' property. Also, 'Access' property - will start using Get-AccessControlEntry - - New-AccessControlEntry creates AD rules - - Set-SD can now handle native .NET SDs - - Long file name support (over 260 characters) - - Callback ACEs partially work. Condition isn't current displayed, but that will be easy enough to get (just convert ACE to SDDL and - grab the conditional string from that) - - Get-Ace -AuditSuccess and -AuditFailure can't be used at the same time. To see only audits, use -AceType SystemAudit -#> - -<# -Dynamic parameters have been removed because of a bug in Get-Help displaying the syntax: https://connect.microsoft.com/PowerShell/feedback/details/397832/dynamicparam-not-returned-when-aliased -(Get/Add/Remove)-AccessControlEntry all shared the parameters of New-AccessControlEntry (which had some dynamic parameters of its own). This was -b/c in early versions of the module, the parameters were changing (and before 3.0, I knew that I wanted to add AD parameters). The param blocks -have reached a point to where they are pretty stable, so it's time to declare all of them as real params. -#> - -#region Helper files/types -# Read helper functions: -. "$PSScriptRoot\PowerShellAccessControlHelperFunctions.ps1" -. "$PSScriptRoot\PowerShellAccessControlPInvokeSignatures.ps1" -. "$PSScriptRoot\PowerShellAccessControlAccessMaskEnumerations.ps1" -#endregion - -#region Module-wide variables -# Store a list of access mask enumerations, which will be used for dynamic parameters (ignore ActiveDirectoryRights--it is special and has its own param set in New-AccessControlEntry): -$__AccessMaskEnumerations = [System.AppDomain]::CurrentDomain.GetAssemblies() | ? { $_.GlobalAssemblyCache -eq $false } | % { $_.GetTypes() } | ? { $_.FullName -match "^PowerShellAccessControl\..*(? -Get-AccessControlEntry <-FilteringParams> | Remove-AccessControlEntry - -AppliesTo and OnlyApplytoThisContainer can come from the pipeline now. AppliesTo will beat AceFlags if their values conflict. AceFlags -can be used to provide AuditFlags and Inheritance/Propagation flags (WMI ACE objects use AceFlags) - -#> - - [CmdletBinding(DefaultParameterSetName="FileRights")] - param( - # - [Parameter(Position=0, ValueFromPipelineByPropertyName=$true)] - [ValidateSet( - "AccessAllowed", - "AccessDenied", - "SystemAudit" - )] - [string] $AceType = "AccessAllowed", - [Parameter(Mandatory=$true, Position=1, ValueFromPipelineByPropertyName=$true)] - [Alias('IdentityReference','SecurityIdentifier')] - $Principal, - [Parameter(Mandatory=$true, ParameterSetName='FileRights')] - [Alias('FileSystemRights')] - [System.Security.AccessControl.FileSystemRights] $FileRights, - [Parameter(Mandatory=$true, ParameterSetName='FolderRights')] - [System.Security.AccessControl.FileSystemRights] $FolderRights, - [Parameter(Mandatory=$true, ParameterSetName='RegistryRights')] - [System.Security.AccessControl.RegistryRights] $RegistryRights, - [Parameter(Mandatory=$true, ParameterSetName='ActiveDirectoryRights')] - [PowerShellAccessControl.ActiveDirectoryRights] $ActiveDirectoryRights, - [Parameter(Mandatory=$true, ParameterSetName='GenericAccessMask', ValueFromPipelineByPropertyName=$true)] - [int] $AccessMask, - [Parameter(ValueFromPipelineByPropertyName=$true)] - [PowerShellAccessControl.AppliesTo] $AppliesTo = "Object", - [Parameter(ValueFromPipelineByPropertyName=$true)] - [switch] $OnlyApplyToThisContainer, - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRights')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRightsObjectAceType')] - [Parameter(ParameterSetName='GenericAccessMask', ValueFromPipelineByPropertyName=$true)] - $ObjectAceType, - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRightsObjectAceType')] - [Parameter(ParameterSetName='GenericAccessMask', ValueFromPipelineByPropertyName=$true)] - $InheritedObjectAceType, - [Parameter(ParameterSetName='GenericAccessMask', ValueFromPipelineByPropertyName=$true)] - [System.Security.AccessControl.AceFlags] $AceFlags, - [Parameter(ParameterSetName='GenericAccessMask')] - [Parameter(ParameterSetName='FileRights')] - [Parameter(ParameterSetName='FolderRights')] - [Parameter(ParameterSetName='RegistryRights')] - [Parameter(ParameterSetName='ActiveDirectoryRights')] - [switch] $GenericAce - ) - - dynamicparam { - - # Two sets of dynamic parameters are created: - # 1. Create a dynamic parameter for each of the access mask enumerations contained in the $__AccessMaskEnumerations - # variable - # 2. If -AceType is SystemAudit, create -AuditSuccess and -AuditFailure parameters - - - # Create the dictionary that this scriptblock will return: - $DynParamDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary - - foreach ($Enumeration in $__AccessMaskEnumerations) { - - $ParamAttributes = New-Object System.Management.Automation.ParameterAttribute - $ParamAttributes.ParameterSetName = "Generic{0}" -f $Enumeration.Name - $ParamAttributes.Mandatory = $true - #$ParamAttributes.ValueFromPipelineByPropertyName = $true - - # Create the attribute collection (PSv3 allows you to simply cast a single attribute - # to this type, but that doesn't work in PSv2) - $AttribColl = New-Object System.Collections.ObjectModel.Collection[System.Attribute] # needed for v2 - $AttribColl.Add($ParamAttributes) - - $DynamicParameter = New-Object System.Management.Automation.RuntimeDefinedParameter ( - $Enumeration.Name, - $Enumeration, - $AttribColl #[System.Collections.ObjectModel.Collection[System.Attribute]] $ParamAttributes - ) - $DynParamDictionary.Add($Enumeration.Name, $DynamicParameter) - } - - if ($PSBoundParameters.AceType -eq "SystemAudit") { - - foreach ($ParameterName in "AuditSuccess","AuditFailure") { - $ParamAttributes = New-Object System.Management.Automation.ParameterAttribute - - # Create the attribute collection (PSv3 allows you to simply cast a single attribute - # to this type, but that doesn't work in PSv2) - $AttribColl = New-Object System.Collections.ObjectModel.Collection[System.Attribute] # needed for v2 - $AttribColl.Add($ParamAttributes) - $AttribColl.Add([System.Management.Automation.AliasAttribute] [string[]] ($ParameterName -replace "Audit")) - - $DynamicParameter = New-Object System.Management.Automation.RuntimeDefinedParameter ( - $ParameterName, - [switch], - $AttribColl - ) - $DynParamDictionary.Add($ParameterName, $DynamicParameter) - } - } - - # Return the dynamic parameters - $DynParamDictionary - } - - process { - - $AceType = [System.Security.AccessControl.AceQualifier] $AceType - $AccessRightsParamName = $PSCmdlet.ParameterSetName -replace "^Generic", "" - $AccessRightsParamName = $AccessRightsParamName -replace "ObjectAceType$", "" # Special paramset so that AccessMask isn't required - - if ($AccessRightsParamName -eq "ActiveDirectoryRights") { - $AccessMaskEnumeration = [PowerShellAccessControl.ActiveDirectoryRights] - } - else { - $AccessMaskEnumeration = $PSBoundParameters[$AccessRightsParamName].GetType() - } - - #region Get Inheritance and Propagation flags - if (-not $PSBoundParameters.ContainsKey("AppliesTo")) { - if ($PSBoundParameters.ContainsKey("AceFlags") -and $AceFlags -band [System.Security.AccessControl.AceFlags]::InheritanceFlags) { - # AceFlags contains inheritance/propagation info, so get the AppliesTo from that - $InheritanceFlags = $PropagationFlags = 0 - foreach ($CurrentFlag in "ContainerInherit", "ObjectInherit") { - if ($AceFlags -band [System.Security.AccessControl.AceFlags]::$CurrentFlag) { - $InheritanceFlags = $InheritanceFlags -bor [System.Security.AccessControl.InheritanceFlags]::$CurrentFlag - } - } - foreach ($CurrentFlag in "NoPropagateInherit","InheritOnly") { - if ($AceFlags -band [System.Security.AccessControl.AceFlags]::$CurrentFlag) { - $PropagationFlags = $PropagationFlags -bor [System.Security.AccessControl.PropagationFlags]::$CurrentFlag - } - } - - # This is extra work b/c inheritance and propagation flags will be obtained from $AppliesTo again in a minute, - # but AceFlags coming in is actually pretty rare, so I don't mind the wasted work on the function's part - $AppliesTo = GetAppliesToMapping -InheritanceFlags $InheritanceFlags -PropagationFlags $PropagationFlags - $OnlyApplyToThisContainer = [bool] ($PropagationFlags -band [System.Security.AccessControl.PropagationFlags]::NoPropagateInherit) - } - else { - # ACEs for different types of objects have different default "AppliesTo". If -AppliesTo param wasn't specified, - # then figure out the default. Function needs to know the access mask enumeration and whether or not the ACE - # will belong to an SD that is a container. We can't know that for sure, but we can make assumptions based on - # the parameter set name: - $DefaultAppliesToParams = @{ - AccessMaskEnumeration = $AccessMaskEnumeration - } - if ("RegistryRights", "GenericWmiNamespaceRights", "ActiveDirectoryRights", "ActiveDirectoryRightsObjectAceType", "FolderRights" -contains $PSCmdlet.ParameterSetName) { - $DefaultAppliesToParams.IsContainer = $true - } - - $AppliesTo = GetDefaultAppliesTo @DefaultAppliesToParams - } - } - - # Convert $AppliesTo and $OnlyAppliesToThisContainer to separate - # inheritance flags and propagation flags enums: - $AppliesToFlags = GetAppliesToMapping -AppliesTo $AppliesTo - $InheritanceFlags = $AppliesToFlags.InheritanceFlags - $PropagationFlags = $AppliesToFlags.PropagationFlags - - if ($OnlyApplyToThisContainer) { - [System.Security.AccessControl.PropagationFlags] $PropagationFlags = $PropagationFlags -bor [System.Security.AccessControl.PropagationFlags]::NoPropagateInherit - } - - #endregion - - # Make sure -Principal parameter is an identity reference (NTAccount or SID) - $Principal = $Principal | ConvertToIdentityReference -ErrorAction Stop -ReturnSid - - #region Get Audit flags - # Check to see if this should be an audit ACE. If so, set up the AuditFlags (these will be used - # as is when File or Registry SACL ACEs are used, and will be used to build the proper flags for - # a generic ACE) - if ($AceType -eq [System.Security.AccessControl.AceQualifier]::SystemAudit) { - $AuditFlags = @() - - # Success/Failure audits may have been specified through parameters (interactive use) - if ($PSBoundParameters.AuditSuccess) { $AuditFlags += "Success" } - if ($PSBoundParameters.AuditFailure) { $AuditFlags += "Failure" } - - - # Or Success/Failure audits may have been specified through AceFlags (usually happens - # when another ACE is fed to New-AccessControlEntry through pipeline. - if ($PSBoundParameters.AceFlags -band [System.Security.AccessControl.AceFlags]::SuccessfulAccess) { $AuditFlags += "Success" } - if ($PSBoundParameters.AceFlags -band [System.Security.AccessControl.AceFlags]::FailedAccess) { $AuditFlags += "Failure" } - - if ($AuditFlags) { - $AuditFlags = $AuditFlags -as [System.Security.AccessControl.AuditFlags] - } - else { - # You've got to have some audit flags - throw "You must specify audit flags when AceType is SystemAudit. Please use one or more of the following parameters: -AuditSuccess, -AuditFailure" - } - } - else { - # If this ACE will be a native .NET class ACE, then no need to worry about this variable. If this - # is going to be a generic ACE, though, the $AuditFlags, $InheritanceFlags, and $PropagationFlags - # will all be combined into a single $AceType variable, so we need to define $AuditFlags: - $AuditFlags = 0 - } - #endregion - - # Assign numeric access rights - $AccessRights = [int] $PSBoundParameters[$AccessRightsParamName] - - # Finalize parameters to the New-Object call after switch statement: - switch -Regex ($PSCmdlet.ParameterSetName) { - "^(File|Folder)Rights$" { - $AccessControlObject = "System.Security.AccessControl.FileSystem{0}Rule" - } - - "^RegistryRights$" { - $AccessControlObject = "System.Security.AccessControl.Registry{0}Rule" - } - - "^ActiveDirectoryRights" { - $AccessControlObject = "System.DirectoryServices.ActiveDirectory{0}Rule" - - # These actions are shared between both AD rule and GenericAce rule creations: - - # We need GUIDs for ObjectAceType and InheritedObjectAceType. The parameters can come - # in as a GUID, a string (string form of GUID, or a string to search on), or a PSObject - # returned from Get-ADObjectAceGuid. The code to fix both are the same, except the variable - # name changes. For that reason, we just use Get/Set variable cmdlets to do the same thing - # for both: - foreach ($AceTypeName in "ObjectAceType", "InheritedObjectAceType") { - $AceTypeValue = Get-Variable -Name $AceTypeName -ValueOnly -Scope 0 -ErrorAction SilentlyContinue - - if ($AceTypeValue -is [array]) { - Write-Error "$AceTypeName parameter takes a single value" - return - } - - if ($AceTypeValue) { - # If this isn't a GUID, then do a lookup using Get-AdObjectAceGuid helper function. If it is a GUID, no - # lookup necessary (assume user or ConvertToCommonAce knows what it wants when GUID was specified) - - $AceTypeObject = if ($AceTypeValue -is [PSObject] -and $AceTypeValue.Guid -is [guid]) { - New-Object PSObject -Property @{ - Guid = $AceTypeValue.Guid - } - } - else { - try { - # Attempt to convert to a GUID (since string GUID may have been passed): - New-Object PSObject -Property @{ - Guid = [guid] $AceTypeValue - } - } - catch { - # Conversion failed, so attempt lookup via name - $Params = @{} - $Params.Name = "^{0}$" -f $AceTypeValue - if ($AceTypeName -eq "InheritedObjectAceType") { - # This should be limited to ClassObjects (I think) - $Params.TypesToSearch = "ClassObject" - } - - try { - Get-ADObjectAceGuid -ErrorAction Stop @Params | Select-SingleObject - } - catch { - Write-Error $_ - return - } - } - } - - $AceTypeValue = $AceTypeObject | select -ExpandProperty Guid - - # If ObjectAceType was specified, this next check will make sure that the access mask contains the right access depending on the - # object type: - - if ($AceTypeName -eq "ObjectAceType") { - # Find out what the access mask must contain ($ValidAccessMask) and what to - # set it to if no access mask was provided ($DefaultAccessMask) - switch -regex ($AceTypeObject.Type) { - - "Property(Set)?" { - $ValidAccessMask = [PowerShellAccessControl.ActiveDirectoryRights] "ReadProperty, WriteProperty" - $DefaultAccessMask = [PowerShellAccessControl.ActiveDirectoryRights]::ReadProperty - break - } - - "ExtendedRight" { - $DefaultAccessMask = $ValidAccessMask = [System.DirectoryServices.ActiveDirectoryRights]::ExtendedRight - break - } - - "ValidatedWrite" { - $DefaultAccessMask = $ValidAccessMask = [System.DirectoryServices.ActiveDirectoryRights]::Self - break - } - - "ClassObject" { - $ValidAccessMask = [System.DirectoryServices.ActiveDirectoryRights] "CreateChild, DeleteChild" - $DefaultAccessMask = [System.DirectoryServices.ActiveDirectoryRights]::CreateChild - break - } - - default { - # Don't do anything - $ValidAccessMask = $ActiveDirectoryRights - $DefaultAccessMask = $ActiveDirectoryRights - } - } - - if (-not ($AccessRights -band $ValidAccessMask)) { - if (-not $ValidAccessMask) { - Write-Error "Please provide access rights to the -ActiveDirectoryRights parameter." - return - } - elseif ($ValidAccessMask -ne $DefaultAccessMask) { - # If this happens, that means there's more than one access right implied - # by the ObjectAceType. Let the user know that we made a choice for them, - # and that they can fix that choice if they like - Write-Warning ("Valid access rights for {0} {1} are {2}. Since neither was supplied to the -ActiveDirectoryRights parameter, the {3} right was added to the access mask. If this is incorrect, please use the -ActiveDirectoryRights parameter." -f $AceTypeObject.Name, $AceTypeObject.Type, $ValidAccessMask, $DefaultAccessMask) - } - - $AccessRights = $AccessRights -bor $DefaultAccessMask - } - } - } - else { - $AceTypeValue = [guid]::Empty - } - - Set-Variable -Name $AceTypeName -Value $AceTypeValue -Scope 0 - } - } - - #region Build constructor array for non-generic ACEs - { ("Filerights", "FolderRights", "RegistryRights", "ActiveDirectoryRights", "ActiveDirectoryRightsObjectAceType" -contains $_) -and - (-not $GenericAce) } { - - # These three scenarios use the exact same actions for the ACE type/flags, so - # might as well handle them together. Constructing the rule is also identical - # besides changing the object type. all of that was handled in the previous - # two blocks, though. - if ($AceType -eq [System.Security.AccessControl.AceQualifier]::SystemAudit) { - $Flags = $AuditFlags - } - elseif ($AceType -eq [System.Security.AccessControl.AceQualifier]::AccessAllowed) { - $Flags = [System.Security.AccessControl.AccessControlType]::Allow - } - elseif ($AceType -eq [System.Security.AccessControl.AceQualifier]::AccessDenied) { - $Flags = [System.Security.AccessControl.AccessControlType]::Deny - } - else { - # Only other enum option is SystemAlarm, and that was checked on earlier, so this - # shouldn't ever happen: - throw "Unknown ACE qualifier" - } - - if ($_ -match "ActiveDirectoryRights") { - # AD rule constructors are slightly different than the other rule types: - $AdSecurityInheritance = GetAppliesToMapping -ADAppliesTo $AppliesTo -OnlyApplyToThisADContainer:$OnlyApplyToThisContainer - - $Arguments = @( - $Principal - $AccessRights - $Flags - $ObjectAceType - $AdSecurityInheritance - $InheritedObjectAceType - ) - } - else { - # All other rule types share the same constructor - $Arguments = @( - $Principal # System.String - $AccessRights # System.Security.AccessControl.RegistryRights or FileSystemRights - $InheritanceFlags # System.Security.AccessControl.InheritanceFlags - $PropagationFlags # System.Security.AccessControl.PropagationFlags - $Flags # System.Security.AccessControl.AccessControlType or AuditFlags - ) - } - } - #endregion - - #region Build constructor array for generic ACEs - { $_ -like "Generic*" -or $GenericAce } { - - # Always a CommonAce, no matter if it is for DACL or SACL (AceQualifier distinguishes this) - $AccessControlObject = "System.Security.AccessControl.CommonAce" - - # Instead of inheritance, propagation, and audit flags being specified separately to the constructor, - # all flags are combined into the AceFlags enumeration. - # Start with $InheritanceFlags and $PropagationFlags first: - [int] $AceFlags = [System.Security.AccessControl.AceFlags] (($InheritanceFlags.ToString() -split ", ") + ($PropagationFlags.ToString() -split ", ")) - - # And finish with the $AuditFlags: - if ($AuditFlags) { - # Convert the audit flag only enumeration into the right values for AceType enumeration - if ($AuditFlags -band [System.Security.AccessControl.AuditFlags]::Success) { - $AceFlags += [System.Security.AccessControl.AceFlags]::SuccessfulAccess.value__ - } - if ($AuditFlags -band [System.Security.AccessControl.AuditFlags]::Failure) { - $AceFlags += [System.Security.AccessControl.AceFlags]::FailedAccess.value__ - } - } - - # These params are common between an ObjectAce and a CommonAce - $Arguments = @( $AceFlags # System.Security.AccessControl.AceFlags - $AceType # System.Security.AccessControl.AceQualifier - $AccessRights - $Principal - ) - - - # If Object ACE guids were specified, we're going to create an ObjectAce instead - # of a CommonAce - if ($PSBoundParameters.ContainsKey("ObjectAceType") -or $PSBoundParameters.ContainsKey("InheritedObjectAceType")) { - $AccessControlObject = "System.Security.AccessControl.ObjectAce" - - $ObjectAceFlags = 0 - if ($PSBoundParameters.ContainsKey("ObjectAceType") -and $ObjectAceType -ne [guid]::Empty) { - $ObjectAceFlags = $ObjectAceFlags -bor [System.Security.AccessControl.ObjectAceFlags]::ObjectAceTypePresent - } - else { - $ObjectAceType = [guid]::Empty - } - - if ($PSBoundParameters.ContainsKey("InheritedObjectAceType") -and $InheritedObjectAceType -ne [guid]::Empty) { - $ObjectAceFlags = $ObjectAceFlags -bor [System.Security.AccessControl.ObjectAceFlags]::InheritedObjectAceTypePresent - # $ObjectAceType guid already defined from parameters - } - else { - $InheritedObjectAceType = [guid]::Empty - } - - $Arguments += $ObjectAceFlags - $Arguments += $ObjectAceType - $Arguments += $InheritedObjectAceType - } - - # These params are common between an ObjectAce and a CommonAce; they are currently not used, but may - # be in the future - $Arguments += $false # isCallback? - $Arguments += $null # opaque data - } - #endregion - - default { - Write-Error "Unknown ParameterSetName" - return - } - - } - - # Create the ACE object - if ($AuditFlags) { - $AuditOrAccess = "Audit" - } - else { - $AuditOrAccess = "Access" - } - $AccessControlObject = $AccessControlObject -f $AuditOrAccess - New-Object -TypeName $AccessControlObject -ArgumentList $Arguments - } -} - -# Since dynamic parameters have been removed, get a list of New-Ace parameters for the functions -# that need to call New-Ace internally (they need to have a list of valid params to build hash -# tables for splatting -$__CommonParameterNames = [System.Runtime.Serialization.FormatterServices]::GetUninitializedObject([type] [System.Management.Automation.Internal.CommonParameters]) | - Get-Member -MemberType Properties | - Select-Object -ExpandProperty Name -$__NewAceParameterNames = Get-Command New-AccessControlEntry -ArgumentList SystemAudit | select -exp Parameters | select -exp Keys | where { $__CommonParameterNames -notcontains $_ } - -#.ExternalHelp PowerShellAccessControl.Help.xml -function Get-AccessControlEntry { - - [CmdletBinding(DefaultParameterSetName='__AllParameterSets')] - param( - [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)] - [Alias('Path')] - # An object that contains a security descriptor - $InputObject, - [switch] $Audit, - [switch] $Inherited, - [switch] $NotInherited, - [switch] $Specific, - [object[]] $ObjectAceType, - [object[]] $InheritedObjectAceType, - [System.Security.AccessControl.AuditFlags] $AuditFlags, -# Old dynamic params start here: - [ValidateSet( - "AccessAllowed", - "AccessDenied", - "SystemAudit" - )] - [string[]] $AceType = "AccessAllowed", - [Alias('IdentityReference','SecurityIdentifier')] - [string[]] $Principal, - [Alias('FileSystemRights')] - [System.Security.AccessControl.FileSystemRights] $FileRights, - [System.Security.AccessControl.FileSystemRights] $FolderRights, - [System.Security.AccessControl.RegistryRights] $RegistryRights, - [PowerShellAccessControl.ActiveDirectoryRights] $ActiveDirectoryRights, - [PowerShellAccessControl.LogicalShareRights] $LogicalShareRights, - [PowerShellAccessControl.PrinterRights] $PrinterRights, - [PowerShellAccessControl.WmiNamespaceRights] $WmiNameSpaceRights, - [PowerShellAccessControl.ServiceAccessRights] $ServiceAccessRights, - [PowerShellAccessControl.ProcessAccessRights] $ProcessAccessRights, - [int] $AccessMask, - [PowerShellAccessControl.AppliesTo] $AppliesTo, - [switch] $OnlyApplyToThisContainer - ) - -<# - dynamicparam { - $DynamicParams = GetNewAceParams -RemoveMandatoryAttribute -ConvertTypesToArrays - - # These params have their own parameter sets that shouldn't be enforced on this - # function. They've been added to the param block, so they need to be removed - # from the dynamic param dictionary. - foreach ($ParamToRemove in "ObjectAceType", "InheritedObjectAceType") { - [void] $DynamicParams.Remove($ParamToRemove) - } - - $DynamicParams - - } -#> - - begin { - # This function is going to call New-AdaptedAcl on a security descriptor object. New-AdaptedAcl - # takes switch parameters for -Dacl and -Sacl (or both). Build a hash table based on -AceType - # sent to this function that can be splatted to New-AdaptedAcl (since that can save work that - # New-AdaptedAcl might have to do otherwise) - $AdaptedAclParams = @{ - GetInheritanceSource = $__GetInheritanceSource - DontTranslateGenericRights = $__DontTranslateGenericRights - } - - if (-not $PSBoundParameters.AceType) { - # No AceType specified, so show both DACL and SACL - $AdaptedAclParams.Dacl = $true - $AdaptedAclParams.Sacl = $true - } - else { - if ($PSBoundParameters.AceType -match "^Access") { - $AdaptedAclParams.Dacl = $true - } - - if ($PSBoundParameters.AceType -match "^SystemAudit") { - $AdaptedAclParams.Sacl = $true - } - } - - #region Build the filter array - # Any parameter that New-AccessControlEntry has can be used to build the ACE filter, - # so get each of the parameter names: -# $NewAceParamNames = (GetNewAceParams).GetEnumerator() | select -exp Key - $NewAceParamNames = $__NewAceParameterNames - $NewAceParamNames += "Inherited", "NotInherited", "AuditFlags" # Add params defined for the function but not in New-AccessControlEntry - - $Filter = @() - foreach ($ParamName in $NewAceParamNames) { - $CurrentFilter = @() - foreach ($Object in $PSBoundParameters.$ParamName) { - if ($Object -eq $null) { continue } # Ignore nulls - - switch -regex ($ParamName) { - Principal { - # Add Principal condition to the Where-Object SB; using regular expression to search - # "^(.*\\)?" and "$" are added to string to allow for an optional domain before the - # username. - # - # There is no need for different behavior when -Specific is used because the ^ and $ - # achors are already being used. User can still use * wildcard. - # - # Two replace operations: - # 1. Replaces a * with a .* so that regex will behave the way that * does with the - # -like operator - # 2. Escape any single backslashes with double backslashes - $CurrentFilter += '$_.Principal -match "^(.*\\)?{0}$"' -f (($Object | ModifySearchRegex) -replace "(? - - [CmdletBinding()] - param( - [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0)] - # The WMI object/CIM instance to get the security descriptor from - $InputObject, - [Parameter(Mandatory=$true)] - $Win32SecurityDescriptor - ) - - process { - switch ($InputObject.GetType().FullName) { - "Microsoft.Management.Infrastructure.CimInstance" { - # Cim instance, so use Invoke-CimMethod: - $InvokeMethodCmdlet = "Invoke-CimMethod" - $MethodNameParamName = "MethodName" - $ClassNameParamName = "ClassName" - $ArgumentsParamName = "Arguments" - $Arguments = @{ Descriptor = $Win32SecurityDescriptor } - } - "System.Management.ManagementObject" { - # Old gwmi object, so use Invoke-WmiMethod: - $InvokeMethodCmdlet = "Invoke-WmiMethod" - $MethodNameParamName = "Name" - $ClassNameParamName = "Class" - $ArgumentsParamName = "ArgumentList" - $Arguments = $Win32SecurityDescriptor - - } - default { - throw "Unknown object type passed to `$InputObject: $_" - } - } - - # Parameters that will be passed to the Invoke-(WMI|Cim)Method cmdlet - $InvokeMethodParams = @{ - ErrorAction = "Stop" - $ArgumentsParamName = $Arguments - $MethodNameParamName = "SetSecurityDescriptor" - } - - try { - $Results = $InputObject | & $InvokeMethodCmdlet @InvokeMethodParams - CheckExitCode $Results.ReturnValue -Action "Setting Win32 security descriptor" - } - catch { - Write-Error ("Error invoking the WMI method '{0}' on the input object '{2}': {1}" -f $InvokeMethodParams.$MethodNameParamName, $_.Exception.Message, $WmiPath) -ErrorId $_.Exception.HResult - return - } - } -} - -#.ExternalHelp PowerShellAccessControl.Help.xml -function Get-Win32SecurityDescriptor { - - [CmdletBinding()] - param( - [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0)] - $InputObject, - [switch] $Sddl, - [switch] $BinarySD, - [switch] $SddlOld, - [switch] $BinarySDOld - ) - - process { - - switch ($InputObject.GetType().FullName) { - "Microsoft.Management.Infrastructure.CimInstance" { - # Cim instance, so use Invoke-CimMethod: - $InvokeMethodCmdlet = "Invoke-CimMethod" - $MethodNameParamName = "MethodName" - $ClassNameParamName = "ClassName" - - # We want to attach a path to the object that is returned. That information - # will be very useful if multiple objects are fed into the function at one - # time. Unfortunately, it seems that CimInstance objects don't have a path - # string already made. B/c of this, I'm attempting to create my own - $WmiPath = $InputObject | Get-CimPathFromInstance - $WmiClass = $InputObject.CimClass.CimClassName - } - "System.Management.ManagementObject" { - # Old gwmi object, so use Invoke-WmiMethod: - $InvokeMethodCmdlet = "Invoke-WmiMethod" - $MethodNameParamName = "Name" - $ClassNameParamName = "Class" - - # See how much easier this is than the CimInstance? - $WmiPath = $InputObject.__PATH - $WmiClass = $InputObject.__CLASS - } - default { - Write-Error "Unknown object type passed to `$InputObject: $_" - return - } - } - - # Parameters that will be passed to the Invoke-(WMI|Cim)Method cmdlet - $InvokeMethodParams = @{ - WhatIf = $false - Confirm = $false - ErrorAction = "Stop" - $MethodNameParamName = "GetSecurityDescriptor" - } - - try { - $Results = $InputObject | & $InvokeMethodCmdlet @InvokeMethodParams - } - catch { - Write-Error ("Error invoking the WMI method '{0}' on the input object '{2}': {1}" -f $InvokeMethodParams.$MethodNameParamName, $_.Exception.Message, $WmiPath) -ErrorId $_.Exception.HResult - return - } - - try { - $Results.ReturnValue | CheckExitCode -Action ("Invoking WMI method '{0}'" -f $InvokeMethodParams.$MethodNameParamName) -ErrorAction Stop - } - catch { - Write-Error $_.Exception.Message - return - } - - $ReturnObjectProperties = @{ - Path = $WmiPath - Class = $WmiClass - InputObject = $InputObject - } - - $InvokeMethodParams.$ClassNameParamName = "Win32_SecurityDescriptorHelper" - - #Arguments/ArgumentList Parameters are very different for the two cmdlets: - switch ($InvokeMethodCmdlet) { - "Invoke-CimMethod" { - $InvokeMethodParams.Arguments = @{ Descriptor = $Results.Descriptor } - } - "Invoke-WmiMethod" { - $InvokeMethodParams.ArgumentList = @($Results.Descriptor) - } - default { - throw "How in the world did you get this far into the function??" - } - } - - # Add the Win32SD to the return object: - $ReturnObjectProperties.Add("Win32SD", $Results.Descriptor) - - if ($PSBoundParameters.ContainsKey("SDDL") -or $PSBoundParameters.ContainsKey("BinarySD")) { - # Because of bug in Win32_SecurityDescriptorHelper class' conversion of Win32SD to SDDL - # and/or binary, we're going to manually do conversion by building the SD from scratch - - $RawSD = New-Object System.Security.AccessControl.RawSecurityDescriptor( - $Results.Descriptor.ControlFlags, - $Results.Descriptor.Owner.SIDString, - $Results.Descriptor.Group.SIDString, - (New-Object System.Security.AccessControl.RawAcl (0,0)), # Blank SACL - (New-Object System.Security.AccessControl.RawAcl (0,0)) # Blank DACL - ) - - # Add discretionary DACL: - $Results.Descriptor.DACL | ConvertToCommonAce -KeepInheritedFlag | ForEach-Object { - $RawSD.DiscretionaryAcl.InsertAce($RawSD.DiscretionaryAcl.Count, $_) - } - - # Add system ACEs to SACL - $Results.Descriptor.SACL | ConvertToCommonAce -KeepInheritedFlag | ForEach-Object { - $RawSD.SystemAcl.InsertAce($RawSD.SystemAcl.Count, $_) - } - - if ($PSBoundParameters.ContainsKey("SDDL")) { - $ReturnObjectProperties.Add("SDDL", $RawSD.GetSddlForm("All")) - } - - if ($PSBoundParameters.ContainsKey("BinarySD")) { - $BinarySdBytes = New-Object byte[] $RawSD.BinaryLength - $RawSD.GetBinaryForm($BinarySdBytes, 0) - $ReturnObjectProperties.Add("BinarySD", $BinarySdBytes) - } - } - - # Original creation of SDDL and/or BinarySD: - - # Function can return the Win32SD in SDDL or Binary form - # NOTE: There is a bug in the helper functions that prevents inheritance from being - # properly represented. (see Notes section in the help for this function) - "SDDL","BinarySD" | ForEach-Object { - if ($PSBoundParameters["$($_)Old"]) { - $InvokeMethodParams.$MethodNameParamName = "Win32SDTo$_" - - try { - $ConvertResults = & $InvokeMethodCmdlet @InvokeMethodParams - } - catch { - throw ("Error invoking the WMI method '{0}' on the input object: {1}" -f $InvokeMethodParams.$MethodNameParamName, $_.Exception.Message) - } - - if ($ConvertResults.ReturnValue -ne 0) { - Write-Error ("Error converting Win32_SecurityDescriptor to $_; return code from WMI method = {0}" -f $ConvertResults.ReturnValue) - $FinalResults = "[ERROR]" - } - else { - $FinalResults = $ConvertResults.$_ - } - - $ReturnObjectProperties.Add("$($_)Old", $FinalResults) - - } - } - - $ReturnObject = New-Object PSObject -Property $ReturnObjectProperties - - $ReturnObject # Output object - } -} - -#.ExternalHelp PowerShellAccessControl.Help.xml -function ConvertTo-Win32SecurityDescriptor { - - [CmdletBinding()] - param( - [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName="Sddl")] - # SDDL representation of a security descriptor - [string] $Sddl, - [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName="BinarySD")] - # Binary representation of a security descriptor - [byte[]] $BinarySD, - # Return just the Win32_SecurityDescriptor (by default, an object that contains both the original input - # and the Win32_SecurityDescriptor object are returned - [switch] $ValueOnly, - # Return a System.ManagementObject istance of the Win32SD instead of a CimInstance. - [switch] $LegacyWmiObject - ) - - process { - - if ($PSVersionTable.PSVersion -lt "3.0") { - $LegacyWmiObject = $true - } - - $InputSD = (Get-Variable -Name ($PSCmdlet.ParameterSetName) -ValueOnly) - - <# - The quicker way to do this is to just use Class, Name, and Argument - as the parameter names. Class and Name params are aliased for the Cim - cmdlets, and Argument is enough to work for both cmdlets, but I decided - to use the full param names in the hash table. - #> - if ($LegacyWmiObject) { - if ($PSCmdlet.ParameterSetName -eq "BinarySD") { - $InputSD = [byte[]] $InputSD - } - - # ManagementObject - $MethodName = "Invoke-WmiMethod" - $ClassNameParam = "Class" - $MethodNameParam = "Name" - $ArgumentsParam = "ArgumentList" - $ArgumentsValue = ,$InputSD - } - else { - # CimInstance param names: - $MethodName = "Invoke-CimMethod" - $ClassNameParam = "ClassName" - $MethodNameParam = "MethodName" - $ArgumentsParam = "Arguments" - $ArgumentsValue = @{ - $PSCmdlet.ParameterSetName = $InputSD - } - } - - $InvokeMethodParams = @{ - $ClassNameParam = "Win32_SecurityDescriptorHelper" - ErrorAction = "Stop" - $MethodNameParam = "{0}ToWin32SD" -f $PSCmdlet.ParameterSetName - $ArgumentsParam = $ArgumentsValue - } - - try { - $Results = & $MethodName @InvokeMethodParams - } - catch { - Write-Error ("Error invoking the WMI method '{0}' on the input object: {1}" -f $InvokeMethodParams.$MethodName, $_.Exception.Message) - return - } - - try { - CheckExitCode -ExitCode $Results.ReturnValue -Action "Converting security descriptor into Win32_SecurityDescriptor" -ErrorAction Stop - } - catch { - Write-Error $_ - return - } - - $ReturnObject = New-Object PSObject -Property @{ - $PSCmdlet.ParameterSetName = $InputSD - Descriptor = $Results.Descriptor - } - - if ($ValueOnly) { - $ReturnObject | Select-Object -ExpandProperty Descriptor - } - else { - $ReturnObject - } - } -} - -function ConvertFrom-Win32SecurityDescriptor { - [CmdletBinding()] - param( - [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0)] - $InputObject, - [switch] $Sddl, - [switch] $BinarySD, - [switch] $SddlOld, - [switch] $BinarySDOld - ) - - begin { - if (-not ($PSBoundParameters.Keys | where { $_ -ne "InputObject" })) { - # No swiches provided, so return Sddl and BinarySd forms by default - $null = $PSBoundParameters.Add("Sddl", $true) - $null = $PSBoundParameters.Add("BinarySD", $true) - } - } - - process { - # Create common variables to store the differences b/w the different input object types: - switch ($InputObject.GetType().FullName) { - "Microsoft.Management.Infrastructure.CimInstance" { - # Cim instance, so use Invoke-CimMethod: - $InvokeMethodCmdlet = "Invoke-CimMethod" - $MethodNameParamName = "MethodName" - $ClassNameParamName = "ClassName" - - # We want to attach a path to the object that is returned. That information - # will be very useful if multiple objects are fed into the function at one - # time. Unfortunately, it seems that CimInstance objects don't have a path - # string already made. B/c of this, I'm attempting to create my own - $WmiPath = $InputObject | Get-CimPathFromInstance - $WmiClass = $InputObject.CimClass.CimClassName - } - "System.Management.ManagementBaseObject" { - # Old gwmi object, so use Invoke-WmiMethod: - $InvokeMethodCmdlet = "Invoke-WmiMethod" - $MethodNameParamName = "Name" - $ClassNameParamName = "Class" - - # See how much easier this is than the CimInstance? - $WmiPath = $InputObject.__PATH - $WmiClass = $InputObject.__CLASS - } - default { - Write-Error "Unknown object type passed to `$InputObject: $_" - return - } - } - - if ("__SecurityDescriptor", "Win32_SecurityDescriptor" -notcontains $WmiClass) { - Write-Error "`$InputObject must be an instance of the Win32_SecurityDescriptor class. Instead, it is an instance of '$WmiClass'" - return - } - - $ReturnObjectProperties = @{ - - } - - if ($PSBoundParameters.ContainsKey("SDDL") -or $PSBoundParameters.ContainsKey("BinarySD")) { - # Because of bug in Win32_SecurityDescriptorHelper class' conversion of Win32SD to SDDL - # and/or binary, we're going to manually do conversion by building the SD from scratch - - $RawSD = New-Object System.Security.AccessControl.RawSecurityDescriptor( - $InputObject.ControlFlags, - $InputObject.Owner.SIDString, - $InputObject.Group.SIDString, - (New-Object System.Security.AccessControl.RawAcl (0,0)), # Blank SACL - (New-Object System.Security.AccessControl.RawAcl (0,0)) # Blank DACL - ) - - # Add discretionary DACL: - $InputObject.DACL | ConvertToCommonAce -KeepInheritedFlag | ForEach-Object { - $RawSD.DiscretionaryAcl.InsertAce($RawSD.DiscretionaryAcl.Count, $_) - } - - # Add system ACEs to SACL - $InputObject.SACL | ConvertToCommonAce -KeepInheritedFlag | ForEach-Object { - $RawSD.SystemAcl.InsertAce($RawSD.SystemAcl.Count, $_) - } - - if ($PSBoundParameters.ContainsKey("SDDL")) { - $ReturnObjectProperties."SDDL" = $RawSD.GetSddlForm("All") - } - - if ($PSBoundParameters.ContainsKey("BinarySD")) { - $BinarySdBytes = New-Object byte[] $RawSD.BinaryLength - $RawSD.GetBinaryForm($BinarySdBytes, 0) - $ReturnObjectProperties."BinarySD" = $BinarySdBytes - } - } - - # Original creation of SDDL and/or BinarySD: - - # Function can return the Win32SD in SDDL or Binary form - # NOTE: There is a bug in the helper functions that prevents inheritance from being - # properly represented. (see Notes section in the help for this function) - - $InvokeMethodParams = @{ - $ClassNameParamName = "Win32_SecurityDescriptorHelper" - } - - switch ($InvokeMethodCmdlet) { - "Invoke-CimMethod" { - $InvokeMethodParams.Arguments = @{ Descriptor = $InputObject } - } - "Invoke-WmiMethod" { - $InvokeMethodParams.ArgumentList = @($InputObject) - } - default { - throw "How in the world did you get this far into the function??" - } - } - - "SDDL","BinarySD" | ForEach-Object { - if ($PSBoundParameters["$($_)Old"]) { - $InvokeMethodParams.$MethodNameParamName = "Win32SDTo$_" - - try { - $ConvertResults = & $InvokeMethodCmdlet @InvokeMethodParams - } - catch { - throw ("Error invoking the WMI method '{0}' on the input object: {1}" -f $InvokeMethodParams.$MethodNameParamName, $_.Exception.Message) - } - - if ($ConvertResults.ReturnValue -ne 0) { - Write-Error ("Error converting Win32_SecurityDescriptor to $_; return code from WMI method = {0}" -f $ConvertResults.ReturnValue) - $FinalResults = "[ERROR]" - } - else { - $FinalResults = $ConvertResults.$_ - } - - $ReturnObjectProperties."$($_)Old" = $FinalResults - - } - } - - New-Object PSObject -Property $ReturnObjectProperties - - } -} - -#.ExternalHelp PowerShellAccessControl.Help.xml -function Get-SecurityDescriptor { - - [CmdletBinding(DefaultParameterSetName='Path')] - param( - [Parameter(Mandatory=$true, ParameterSetName='InputObject', ValueFromPipeline=$true)] - $InputObject, - [Parameter(ParameterSetName='DirectPath', Position=0, ValueFromPipelineByPropertyName=$true)] - [Parameter(ParameterSetName='Path', Position=0, ValueFromPipelineByPropertyName=$true)] - [string[]] $Path = ".", - [Parameter(Mandatory=$true, ParameterSetName='LiteralPath', ValueFromPipelineByPropertyName=$true)] - [string[]] $LiteralPath, - [Parameter(ParameterSetName='DirectPath')] - [System.Security.AccessControl.ResourceType] $ObjectType, - [switch] $Audit, - [Parameter(ParameterSetName='DirectPath')] - [switch] $IsContainer = $false - ) - - process { - - if ($PSCmdlet.ParameterSetName -eq "Path" -and (-not $PSBoundParameters.ContainsKey("Path"))) { - # GetPathInformation uses PSBoundParameters, so set it up as if the default path was passed - # as a bound parameter: - $null = $PSBoundParameters.Add("Path", $Path) - } - - foreach ($ObjectInfo in (GetPathInformation @PSBoundParameters)) { - if ($ObjectInfo.Sddl) { - # If GetPathInformation returned SDDL, that means the InputObject was already a security - # descriptor object (one of native .NET ones that this module works with: File, Folder, Registry - # key, or AD object as of v3.0) - # - # In that case, don't do anything since this section handles retrieving that information - } - elseif ($ObjectInfo.ObjectType -eq $__PowerShellAccessControlResourceTypeName) { - # We've got to do something special here - switch ($ObjectInfo.InputObject.GetType().FullName) { - { $_ -eq "System.Management.ManagementObject" -or - $_ -eq "Microsoft.Management.Infrastructure.CimInstance" } { - - # This is a WMI object, so attempt to get Win32SD (other properties should - # have already been handled - try { - $Win32SD = $ObjectInfo.InputObject | Get-Win32SecurityDescriptor -Sddl -ErrorAction Stop - } - catch { - # Catching error lets user decide error action - Write-Error $_ - return - } - - $ObjectInfo.Sddl = $Win32SD.Sddl - } - - "Microsoft.WSMan.Management.WSManConfigLeafElement" { - $ObjectInfo.Sddl = $ObjectInfo.InputObject.Value - } - } - } - else { - - if ($Audit) { - $SecurityInfo = [PowerShellAccessControl.PInvoke.SecurityInformation]::All - } - else { - $SecurityInfo = [PowerShellAccessControl.PInvoke.SecurityInformation] "Owner, Group, Dacl" - } - - try { - $SecInfoParams = @{ - ObjectType = $ObjectInfo.ObjectType - } - - if ($ObjectInfo.Handle) { - $SecInfoParams.Handle = $ObjectInfo.SdPath = $ObjectInfo.Handle - } - else { - $SecInfoParams.Path = $ObjectInfo.SdPath - } - - $BinSD = GetSecurityInfo -SecurityInformation $SecurityInfo -ErrorAction Stop @SecInfoParams - $ObjectInfo.BinarySD = $BinSD - } - catch { - # Catching error and re-writing it makes it so user can decide the error action - Write-Error $_ - continue - } - } - - # There are a few properties that may exist in the hashtable that can't be passed to - # New-AdaptedSecurityDescriptor. Remove those: - foreach ($PropToRemove in "Handle", "InputObject") { - if ($ObjectInfo.$PropToRemove) { - $ObjectInfo.Remove($PropToRemove) - } - } - - # Now we can splat $ObjectInfo to New-AdaptedSecurityDescriptor - try { - New-AdaptedSecurityDescriptor -ErrorAction Stop @ObjectInfo - } - catch { - Write-Error $_ - continue - } - } # end foreach() - } -} - -#.ExternalHelp PowerShellAccessControl.Help.xml -function Set-SecurityDescriptor { - - [CmdletBinding(DefaultParameterSetName = '__AllParameterSets', SupportsShouldProcess=$true, ConfirmImpact='High')] - param( - [Parameter(Mandatory=$true, ValueFromPipeline=$true)] - [ValidateScript({ $_ -isnot [array] })] - $SDObject, - [Parameter(Mandatory=$true, ParameterSetName='InputObject')] - $InputObject, - [Parameter(Mandatory=$true, ParameterSetName='Path')] - [string[]] $Path, - [Parameter(Mandatory=$true, ParameterSetName='LiteralPath')] - [string[]] $LiteralPath, - [switch] $Force, - [System.Security.AccessControl.AccessControlSections] $Sections = "Access, Audit" - - ) - - process { - - # SDObject must be an "adapted" SD (from this module). If it's a native .NET SD (like from Get-Acl), - # that's OK, but we must convert it. Thankfully, Get-SD can do that: - if ($SDObject.GetType().FullName -match "System\.(Security\.AccessControl|DirectoryServices)\.(\w+)Security") { - $SDObject = $SDObject | Get-SecurityDescriptor -ErrorAction Stop - } - elseif ($SDObject.pstypenames -notcontains $__AdaptedSecurityDescriptorTypeName) { - # Invalid SD Object! - Write-Error ("Unknown SDObject type: {0}" -f $SDObject.GetType().FullName) - } - - # If Path, LiteralPath, or InputObject are passed, that means user wants SD from $SDObject - # put onto the item described by one of those parameters: - if ($PSCmdlet.ParameterSetName -eq [System.Management.Automation.ParameterAttribute]::AllParameterSets) { - # The path and object type used for SetSecurityInfo will come straight from the SD - $ObjectsToSet = @{ - SdPath = $SDObject.SdPath - ObjectType = $SDObject.ObjectType - } - } - else { - $ObjectsToSet = GetPathInformation @PSBoundParameters - } - - # The key to this whole thing is the [SecurityInformation] that is passed to - # the SetSecurityDescriptor function. We'll build that based on the [ControlFlags] - # that is attached to the security descriptor object. - $ControlFlags = $SDObject.SecurityDescriptor.ControlFlags - [PowerShellAccessControl.PInvoke.SecurityInformation] $SecurityInformation = 0 - $SdParts = @{} # This will hold the actual SD parts (Owner, Group, DACL, SACL) - - # If $Sections wasn't specified and the owner is different, go ahead and enable it as well. - if ((-not $PSBoundParameters.ContainsKey("Sections")) -and $SDObject.HasOwnerChanged) { - $Sections = $Sections -bxor [System.Security.AccessControl.AccessControlSections]::Owner - } - - # Same as above, except for Group - if ((-not $PSBoundParameters.ContainsKey("Sections")) -and $SDObject.HasGroupChanged) { - $Sections = $Sections -bxor [System.Security.AccessControl.AccessControlSections]::Group - } - - # Check to make sure owner section specified and that owner on SD isn't null - if ($Sections -band [System.Security.AccessControl.AccessControlSections]::Owner -and $SDObject.SecurityDescriptor.Owner) { - # Owner should be set - $SecurityInformation = $SecurityInformation -bxor [PowerShellAccessControl.PInvoke.SecurityInformation]::Owner - $SdParts.Owner = $SDObject.SecurityDescriptor.Owner - } - # Do the same thing for group as owner - if ($Sections -band [System.Security.AccessControl.AccessControlSections]::Group -and $SDObject.SecurityDescriptor.Group) { - $SecurityInformation = $SecurityInformation -bxor [PowerShellAccessControl.PInvoke.SecurityInformation]::Group - $SdParts.Group = $SDObject.SecurityDescriptor.Group - } - - if ($Sections -band [System.Security.AccessControl.AccessControlSections]::Access) { - # Two checks: - # 1. Function must have been called with 'Access' as one of the sections (it is by default) - # 2. The SD control flags must show that the SD actually has a DACL - if ($ControlFlags -band [System.Security.AccessControl.ControlFlags]::DiscretionaryAclPresent) { - $SecurityInformation = $SecurityInformation -bxor [PowerShellAccessControl.PInvoke.SecurityInformation]::Dacl - } - if ($ControlFlags -band [System.Security.AccessControl.ControlFlags]::DiscretionaryAclProtected) { - $SecurityInformation = $SecurityInformation -bxor [PowerShellAccessControl.PInvoke.SecurityInformation]::ProtectedDacl - } - elseif ($ControlFlags -band [System.Security.AccessControl.ControlFlags]::DiscretionaryAclPresent) { - # Not protected, and DACL is present; set UnprotectedDacl flag - $SecurityInformation = $SecurityInformation -bxor [PowerShellAccessControl.PInvoke.SecurityInformation]::UnprotectedDacl - } - - $SdParts.DiscretionaryAcl = $SDObject.SecurityDescriptor.DiscretionaryAcl - } - - # Do the exact same thing for the SACL - if ($Sections -band [System.Security.AccessControl.AccessControlSections]::Audit) { - if ($ControlFlags -band [System.Security.AccessControl.ControlFlags]::SystemAclPresent) { - $SecurityInformation = $SecurityInformation -bxor [PowerShellAccessControl.PInvoke.SecurityInformation]::Sacl - } - if ($ControlFlags -band [System.Security.AccessControl.ControlFlags]::SystemAclProtected) { - $SecurityInformation = $SecurityInformation -bxor [PowerShellAccessControl.PInvoke.SecurityInformation]::ProtectedSacl - } - elseif ($ControlFlags -band [System.Security.AccessControl.ControlFlags]::SystemAclPresent) { - # Not protected, and SACL is present; set UnprotectedSacl flag - $SecurityInformation = $SecurityInformation -bxor [PowerShellAccessControl.PInvoke.SecurityInformation]::UnprotectedSacl - } - - $SdParts.SystemAcl = $SDObject.SecurityDescriptor.SystemAcl - } - - foreach ($Object in $ObjectsToSet) { - - $SetSdParams = @{ - ObjectType = $Object.ObjectType - SecurityInfo = $SecurityInformation - } - switch ($Object.SdPath.GetType().FullName) { - { $_ -eq "System.IntPtr" -or $_ -eq "System.Runtime.InteropServices.HandleRef" } { - # Handle - $SetSdParams.Handle = $Object.SdPath - } - "System.String" { - # Text path - $SetSdParams.Path = $Object.SdPath - } - - default { - Write-Error "Unknown security descriptor path for object with type '$ObjectType'" - return - } - } - - $ShouldProcessTarget = "{0} ({1})" -f $Object.SdPath, $Object.ObjectType - $ShouldProcessAction = GetSdString -SDObject $SDObject -SecurityInformation $SecurityInformation - - if ($Force -and (-not $WhatIf)) { - $ShouldProcessResult = $true - } - else { - $ShouldProcessResult = $PSCmdlet.ShouldProcess($ShouldProcessTarget, $ShouldProcessAction) - } - - if ($ShouldProcessResult) { - - if ($Object.ObjectType -eq $__PowerShellAccessControlResourceTypeName) { - try { - $PathInfo = New-Object PSObject -Property @{ - Path = $Object.SdPath - ObjectType = $__PowerShellAccessControlResourceTypeName - } | GetPathInformation - - # We've got to do something special here - switch ($PathInfo.InputObject.GetType().FullName) { - { $_ -eq "System.Management.ManagementObject" -or - $_ -eq "Microsoft.Management.Infrastructure.CimInstance" } { - - $UseLegacyWmi = $false - if ($_ -eq "System.Management.ManagementObject") { - $UseLegacyWmi = $true - } - - # This is a WMI object, so attempt to get Win32SD - $Win32SD = ConvertTo-Win32SecurityDescriptor -Sddl $SDObject.Sddl -LegacyWmiObject:$UseLegacyWmi -ErrorAction Stop - - $PathInfo.InputObject | Set-Win32SecurityDescriptor -Win32SecurityDescriptor $Win32SD.Descriptor - - } - - "Microsoft.WSMan.Management.WSManConfigLeafElement" { - Set-Item -Path $SDObject.SdPath -Value $SDObject.Sddl -Force:$Force -ErrorAction Stop - } - } - } - catch { - # Catching error lets user decide error action - Write-Error $_ - continue - } - } - else { - SetSecurityInfo @SetSdParams @SdParts - } - } - } - } -} - -#.ExternalHelp PowerShellAccessControl.Help.xml -function Enable-AclInheritance { - [CmdletBinding(SupportsShouldProcess=$true)] - param( - [Parameter(Mandatory=$true, ParameterSetName='InputObject', ValueFromPipeline=$true)] - [Alias("SDObject")] - $InputObject, - [Parameter(ParameterSetName='Path', Position=0, ValueFromPipelineByPropertyName=$true)] - [string[]] $Path = ".", - [Parameter(Mandatory=$true, ParameterSetName='LiteralPath', ValueFromPipelineByPropertyName=$true)] - [string[]] $LiteralPath, - [Alias("DACL","Access")] - [switch] $DiscretionaryAcl, - [Alias("SACL","Audit")] - [switch] $SystemAcl, - [switch] $Apply, - [switch] $PassThru, - [switch] $Force - ) - - begin { - <# - See the note at the beginning of the CustomShouldProcess function for more info about why I've (hopefully temporarily) - implemented my own ShouldProcess function inside the SD modification functions. - #> - - if ($Force) { - $__CustomConfirmImpact = [System.Management.Automation.ConfirmImpact]::None - $__DefaultReturn = $true - } - else { - $__CustomConfirmImpact = $__ConfirmImpactForApplySdModification - $__DefaultReturn = $false - } - - if (-not $PSBoundParameters.ContainsKey("DiscretionaryAcl") -and - -not $PSBoundParameters.ContainsKey("SystemAcl")) { - # Neither Acl was specified. This will actually happen - # a lot; just set it up like they passed Dacl switch: - $DiscretionaryAcl = $true - } - - $ActionTextSecInfo = 0 - if ($DiscretionaryAcl) { $ActionTextSecInfo = $ActionTextSecInfo -bor [PowerShellAccessControl.PInvoke.SecurityInformation]::UnprotectedDacl } - if ($SystemAcl) { $ActionTextSecInfo = $ActionTextSecInfo -bor [PowerShellAccessControl.PInvoke.SecurityInformation]::UnprotectedSacl } - - } - - process { - - # Determine which methods to call for each SD - $MethodsToInvoke = @() - if ($DiscretionaryAcl) { $MethodsToInvoke += "SetAccessRuleProtection" } - if ($SystemAcl) { $MethodsToInvoke += "SetAuditRuleProtection" } - - - if ($PSCmdlet.ParameterSetName -ne "InputObject") { - # If a path was passed and the -SystemAcl switch was also passed, Get-SD will need - # to get the SACL: - if ($SystemAcl) { $Audit = $true } - else { $Audit = $false } - - $Params = @{ - $PSCmdlet.ParameterSetName = $PSBoundParameters[$PSCmdlet.ParameterSetName] - Audit = $Audit - } - - $InputObject = Get-SecurityDescriptor @Params -ErrorAction Stop - - # SD object wasn't passed, so assume user wants immediate results - # Change the PSBoundParameters b/c loop through InputObject checks that. User - # shouldn't be able to call function with an InputObject while a path was passed - # b/c they are different parameter sets - $PSBoundParameters.Apply = (-not $PassThru) -or $Apply # If -PassThru was specified, don't set apply (unless it was already set) - } - - foreach ($CurrentSDObject in $InputObject) { - # This can get set later if $SDObject isn't a security descriptor; reset it at the beginning - # of the loop to prevent unwanted apply actions - $Apply = $PsBoundParameters.Apply - - $ShouldProcessTarget = "{0} (in memory SD)" -f $CurrentSDObject.Path - - $TypeName = $CurrentSDObject.GetType().FullName - - if ($TypeName -eq "System.Security.AccessControl.RegistrySecurity" -or - $TypeName -match "System.Security.AccessControl.(File|Directory)Security") { - - # The SDObject is a .NET file or registry security object from Get-Acl - # This is fine, and no extra work should be necessary b/c the methods that - # will be called are the same for Get-Acl objects and Get-SD objects - } - elseif (-not ($CurrentSDObject.pstypenames -contains $__AdaptedSecurityDescriptorTypeName)) { - - try { - # Not an object from Get-SecurityDescriptor, so see if it can be converted: - $CurrentSDObject = Get-SecurityDescriptor -InputObject $CurrentSDObject -ErrorAction Stop - $ShouldProcessTarget = "{0} (in memory SD)" -f $CurrentSDObject.Path - } - catch { - Write-Error $_ - return - } - - # If -PassThru was specified, don't set apply (unless it was already set) - $Apply = (-not $PassThru) -or $Apply - } - - foreach ($MethodName in $MethodsToInvoke) { - if ($PSCmdlet.ShouldProcess($ShouldProcessTarget, "Invoke $MethodName method")) { - $CurrentSDObject.$MethodName.Invoke($false, $false) # Second param doesn't matter - } - } - - if ($Apply) { - Write-Verbose "$($MyInvocation.InvocationName): Apply set, so SD is being applied" - - $Params = @{ - __CustomConfirmImpact = [ref] $__CustomConfirmImpact - __DefaultReturn = [ref] $__DefaultReturn - Action = GetSdString -SDObject $CurrentSDObject -SecurityInformation $ActionTextSecInfo - Target = $CurrentSDObject.Path - } - if (CustomShouldProcess @Params) { - Set-SecurityDescriptor -SDObject $CurrentSDObject -Confirm:$false -WhatIf:$false - } - } - if ($PassThru) { - $CurrentSDObject - Write-Warning ("Please apply the security descriptor for '{0}' and get it again to reflect any inherited entries" -f $CurrentSDObject.Path) - } - } - } -} - -#.ExternalHelp PowerShellAccessControl.Help.xml -function Disable-AclInheritance { - - [CmdletBinding(SupportsShouldProcess=$true)] - param( - [Parameter(Mandatory=$true, ParameterSetName='InputObject', ValueFromPipeline=$true)] - [Alias("SDObject")] - $InputObject, - [Parameter(ParameterSetName='Path', Position=0, ValueFromPipelineByPropertyName=$true)] - [string[]] $Path = ".", - [Parameter(Mandatory=$true, ParameterSetName='LiteralPath', ValueFromPipelineByPropertyName=$true)] - [string[]] $LiteralPath, - [Alias("DACL", "Access")] - [switch] $DiscretionaryAcl, - [Alias("SACL", "Audit")] - [switch] $SystemAcl, - [switch] $Apply, - [switch] $PassThru, - [switch] $Force, - [switch] $PreserveExistingAces - ) - - begin { - - # If user doesn't specify which ACL to perform this on, assume they want to do it to the DACL only - if (-not $PSBoundParameters.ContainsKey("DiscretionaryAcl") -and - -not $PSBoundParameters.ContainsKey("SystemAcl")) { - # Neither Acl was specified. This will actually happen - # a lot; just set it up like they passed Dacl switch: - $DiscretionaryAcl = $true - } - - <# - See the note at the beginning of the CustomShouldProcess function for more info about why I've (hopefully temporarily) - implemented my own ShouldProcess function inside the SD modification functions. - #> - - if ($Force) { - $__CustomConfirmImpact = [System.Management.Automation.ConfirmImpact]::None - $__DefaultReturn = $true - } - else { - $__CustomConfirmImpact = $__ConfirmImpactForApplySdModification - $__DefaultReturn = $false - - # Force wasn't provided, so also check to see if $PreserveExistingAces was provided, - # and if not, prompt user - if (-not $PSBoundParameters.ContainsKey("PreserveExistingAces")) { - $AclsToModify = @() - if ($DiscretionaryAcl) { $AclsToModify += "discretionary ACL" } - if ($SystemAcl) { $AclsToModify += "system ACL" } - - $PreservePromptText = @" -Warning: If you proceed, inheritable parent permissions will no longer -propagate to the object's {0}. - -- Select Add to convert and add inherited parent permissions as explicit -permissions. - -- Select Remove to remove inherited parent permissions. - -- Select Cancel if you do not want to modify inheritance settings at this time. - -To avoid this prompt in the future, please use either the -PreserveExistingAces -or -Force flags with the {1} command. -"@ -f ($AclsToModify -join " and "), $MyInvocation.MyCommand - - switch (echo Add, Remove, Cancel | Select-SingleObject -PromptMode PromptForChoice -Title $PreservePromptText -PromptForChoiceTitle $MyInvocation.MyCommand) { - Add { - $PreserveExistingAces = $true - } - - Remove { - $PreserveExistingAces = $false - } - - default { - throw ("Modification of {0} cancelled by user" -f ($AclsToModify -join " and ")) - } - } - } - - $ActionTextSecInfo = 0 - if ($DiscretionaryAcl) { $ActionTextSecInfo = $ActionTextSecInfo -bor [PowerShellAccessControl.PInvoke.SecurityInformation]::ProtectedDacl } - if ($SystemAcl) { $ActionTextSecInfo = $ActionTextSecInfo -bor [PowerShellAccessControl.PInvoke.SecurityInformation]::ProtectedSacl } - } - } - - process { - - # Determine which methods to call for each SD - $MethodsToInvoke = @() - - if ($DiscretionaryAcl) { $MethodsToInvoke += "SetAccessRuleProtection" } - if ($SystemAcl) { $MethodsToInvoke += "SetAuditRuleProtection" } - - - if ($PSCmdlet.ParameterSetName -ne "InputObject") { - # If a path was passed and the -SystemAcl switch was also passed, Get-SD will need - # to get the SACL: - if ($SystemAcl) { $Audit = $true } - else { $Audit = $false } - - $Params = @{ - $PSCmdlet.ParameterSetName = $PSBoundParameters[$PSCmdlet.ParameterSetName] - Audit = $Audit - } - $InputObject = Get-SecurityDescriptor @Params -ErrorAction Stop - - # SD object wasn't passed, so assume user wants immediate results - # Change the PSBoundParameters b/c loop through InputObject checks that. User - # shouldn't be able to call function with an InputObject while a path was passed - # b/c they are different parameter sets - $PSBoundParameters.Apply = (-not $PassThru) -or $Apply # If -PassThru was specified, don't set apply (unless it was already set) - } - - foreach ($CurrentSDObject in $InputObject) { - # This can get set later if $SDObject isn't a security descriptor; reset it at the beginning - # of the loop to prevent unwanted apply actions - $Apply = $PsBoundParameters.Apply - - $ShouldProcessTarget = "{0} (in memory SD)" -f $CurrentSDObject.Path - - $TypeName = $CurrentSDObject.GetType().FullName - if ($TypeName -eq "System.Security.AccessControl.RegistrySecurity" -or - $TypeName -match "System.Security.AccessControl.(File|Directory)Security") { - - # The SDObject is a .NET file or registry security object from Get-Acl - # This is fine, and no extra work should be necessary b/c the methods that - # will be called are the same for Get-Acl objects and Get-SD objects - } - elseif (-not ($CurrentSDObject.pstypenames -contains $__AdaptedSecurityDescriptorTypeName)) { - - try { - # Not an object from Get-SecurityDescriptor, so see if it can be converted: - $CurrentSDObject = Get-SecurityDescriptor -InputObject $CurrentSDObject -ErrorAction Stop - $ShouldProcessTarget = "{0} (in memory SD)" -f $CurrentSDObject.Path - } - catch { - Write-Error $_ - return - } - - # If -PassThru was specified, don't set apply (unless it was already set) - $Apply = (-not $PassThru) -or $Apply - } - - foreach ($MethodName in $MethodsToInvoke) { - if ($PSCmdlet.ShouldProcess($ShouldProcessTarget, "Invoke $MethodName method; preserve existing entries: $PreserveExistingAces")) { - $CurrentSDObject.$MethodName.Invoke($true, $PreserveExistingAces) - } - } - - if ($Apply) { - Write-Verbose "$($MyInvocation.InvocationName): Apply set, so SD is being applied" - - $Params = @{ - __CustomConfirmImpact = [ref] $__CustomConfirmImpact - __DefaultReturn = [ref] $__DefaultReturn - Action = GetSdString -SDObject $CurrentSDObject -SecurityInformation $ActionTextSecInfo - Target = $CurrentSDObject.Path - } - if (CustomShouldProcess @Params) { - Set-SecurityDescriptor -SDObject $CurrentSDObject -Confirm:$false -WhatIf:$false - } - } - if ($PassThru) { - $CurrentSDObject - Write-Warning ("Please apply the security descriptor for '{0}' and get it again to reflect any inherited entries" -f $CurrentSDObject.Path) - } - } - } -} - -#.ExternalHelp PowerShellAccessControl.Help.xml -function Repair-AclCanonicalOrder { - - [CmdletBinding(SupportsShouldProcess=$true)] - param( - [Parameter(Mandatory=$true, ParameterSetName='InputObject', ValueFromPipeline=$true)] - [Alias("SDObject")] - $InputObject, - [Parameter(ParameterSetName='Path', Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] - [string[]] $Path = ".", - [Parameter(Mandatory=$true, ParameterSetName='LiteralPath', ValueFromPipelineByPropertyName=$true)] - [string[]] $LiteralPath, - [Alias("DACL", "Access")] - [switch] $DiscretionaryAcl, - [Alias("SACL", "Audit")] - [switch] $SystemAcl, - [switch] $Apply, - [switch] $PassThru, - [switch] $Force - ) - - begin { - <# - See the note at the beginning of the CustomShouldProcess function for more info about why I've (hopefully temporarily) - implemented my own ShouldProcess function inside the SD modification functions. - #> - - if ($Force) { - $__CustomConfirmImpact = [System.Management.Automation.ConfirmImpact]::None - $__DefaultReturn = $true - } - else { - $__CustomConfirmImpact = $__ConfirmImpactForApplySdModification - $__DefaultReturn = $false - } - } - - process { - - if (-not $PSBoundParameters.ContainsKey("DiscretionaryAcl") -and - -not $PSBoundParameters.ContainsKey("SystemAcl")) { - # Neither Acl was specified. This will actually happen - # a lot; just set it up like they passed Dacl switch: - $DiscretionaryAcl = $true - } - - # Determine which ACLs will be checked later: - $PropertyNames = @() - if ($DiscretionaryAcl) { $PropertyNames += "Access" } - if ($SystemAcl) { $PropertyNames += "Audit" } - - if ($PSCmdlet.ParameterSetName -ne "InputObject") { - # If a path was passed and the -SystemAcl switch was also passed, Get-SD will need - # to get the SACL: - if ($SystemAcl) { $Audit = $true } - else { $Audit = $false } - - $Params = @{ - $PSCmdlet.ParameterSetName = $PSBoundParameters[$PSCmdlet.ParameterSetName] - Audit = $Audit - } - - $InputObject = Get-SecurityDescriptor @Params -ErrorAction Stop - - # SD object wasn't passed, so assume user wants immediate results - # Change the PSBoundParameters b/c loop through InputObject checks that. User - # shouldn't be able to call function with an InputObject while a path was passed - # b/c they are different parameter sets - $PSBoundParameters.Apply = (-not $PassThru) -or $Apply # If -PassThru was specified, don't set apply (unless it was already set) - } - - foreach ($CurrentSDObject in $InputObject) { - # This can get set later if $SDObject isn't a security descriptor; reset it at the beginning - # of the loop to prevent unwanted apply actions - $Apply = $PsBoundParameters.Apply - - $ShouldProcessTarget = "{0} (in memory SD)" -f $CurrentSDObject.Path - - $TypeName = $CurrentSDObject.GetType().FullName - - - if ($TypeName -eq "System.Security.AccessControl.RegistrySecurity" -or - $TypeName -match "System.Security.AccessControl.(File|Directory)Security") { - - # For now, only Get-SecurityDescriptor objects are supported - Write-Warning "'$($MyInvocation.InvocationName)' only supports objects returned from Get-SecurityDescriptor" - continue - } - elseif (-not ($CurrentSDObject.pstypenames -contains $__AdaptedSecurityDescriptorTypeName)) { - - try { - # Not an object from Get-SecurityDescriptor, so see if it can be converted: - $CurrentSDObject = Get-SecurityDescriptor -InputObject $CurrentSDObject -ErrorAction Stop - $ShouldProcessTarget = "{0} (in memory SD)" -f $CurrentSDObject.Path - } - catch { - Write-Error $_ - return - } - - # If -PassThru was specified, don't set apply (unless it was already set) - $Apply = (-not $PassThru) -or $Apply - } - - foreach ($PropertyName in $PropertyNames) { - if ($CurrentSDObject."Are${PropertyName}RulesCanonical" -eq $false) { - # Create a temporary SD with a blank ACL: - if ($PropertyName -eq "Access") { - $TempSd = New-AdaptedSecurityDescriptor -Sddl "D:" -IsContainer:$CurrentSDObject.SecurityDescriptor.IsContainer - $AclType = "Discretionary" - } - else { - $TempSd = New-AdaptedSecurityDescriptor -Sddl "S:" -IsContainer:$CurrentSDObject.SecurityDescriptor.IsContainer - $AclType = "System" - } - - Add-AccessControlEntry -SDObject $TempSd -AceObject ($CurrentSDObject.Access | where { -not $_.IsInherited }) - - if ($PSCmdlet.ShouldProcess($ShouldProcessTarget, "Replace $AclType ACL with ordered ACL")) { - $CurrentSDObject.SecurityDescriptor."${AclType}Acl" = $TempSd.SecurityDescriptor."${AclType}Acl" - } - - if ($Apply) { - Write-Verbose "$($MyInvocation.InvocationName): Apply set, so SD is being applied" - - $Params = @{ - __CustomConfirmImpact = [ref] $__CustomConfirmImpact - __DefaultReturn = [ref] $__DefaultReturn - Action = GetSdString -SDObject $CurrentSDObject - Target = $CurrentSDObject.Path - } - if (CustomShouldProcess @Params) { - Set-SecurityDescriptor -SDObject $CurrentSDObject -Confirm:$false -WhatIf:$false - } - } - if ($PassThru) { - $CurrentSDObject - } - } - else { - # No re-ordering necessary - } - } - } - } -} - -#.ExternalHelp PowerShellAccessControl.Help.xml -function Add-AccessControlEntry { - - [CmdletBinding(SupportsShouldProcess=$true)] - param( - [Parameter(Mandatory=$true, ValueFromPipeline=$true)] - [Alias('Path')] - $SDObject, - [Parameter(Mandatory=$true, ParameterSetName="AceObject", Position=0)] - [object[]] $AceObject, - [switch] $AddEvenIfAclDoesntExist, - [switch] $Apply, - [switch] $Force, - [switch] $PassThru, - [Parameter(ParameterSetName='AceObject')] - [Parameter(ParameterSetName='GenericAccessMask')] - [Parameter(ParameterSetName='FileRights')] - [Parameter(ParameterSetName='FolderRights')] - [Parameter(ParameterSetName='RegistryRights')] - [Parameter(ParameterSetName='ActiveDirectoryRights')] - [Parameter(ParameterSetName='ActiveDirectoryRightsObjectAceType')] - [Parameter(ParameterSetName='LogicalShareRights')] - [Parameter(ParameterSetName='PrinterRights')] - [Parameter(ParameterSetName='WmiNameSpaceRights')] - [Parameter(ParameterSetName='ServiceAccessRights')] - [Parameter(ParameterSetName='ProcessAccessRights')] - [Alias('Set')] - [switch] $Overwrite, -# Old dynamic params start here: - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='GenericAccessMask')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='FileRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='FolderRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='RegistryRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRightsObjectAceType')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='LogicalShareRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='PrinterRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='WmiNameSpaceRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ServiceAccessRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ProcessAccessRights')] - [ValidateSet( - "AccessAllowed", - "AccessDenied", - "SystemAudit" - )] - [string] $AceType = "AccessAllowed", - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='GenericAccessMask')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='FileRights')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='FolderRights')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='RegistryRights')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRights')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRightsObjectAceType')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='LogicalShareRights')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='PrinterRights')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='WmiNameSpaceRights')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='ServiceAccessRights')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='ProcessAccessRights')] - [Alias('IdentityReference','SecurityIdentifier')] - $Principal, - [Parameter(Mandatory=$true, ParameterSetName='FileRights')] - [Alias('FileSystemRights')] - [System.Security.AccessControl.FileSystemRights] $FileRights, - [Parameter(Mandatory=$true, ParameterSetName='FolderRights')] - [System.Security.AccessControl.FileSystemRights] $FolderRights, - [Parameter(Mandatory=$true, ParameterSetName='RegistryRights')] - [System.Security.AccessControl.RegistryRights] $RegistryRights, - [Parameter(Mandatory=$true, ParameterSetName='ActiveDirectoryRights')] - [PowerShellAccessControl.ActiveDirectoryRights] $ActiveDirectoryRights, - [Parameter(Mandatory=$true, ParameterSetName='GenericAccessMask', ValueFromPipelineByPropertyName=$true)] - [int] $AccessMask, - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='GenericAccessMask')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='FileRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='FolderRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='RegistryRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRightsObjectAceType')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='LogicalShareRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='PrinterRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='WmiNameSpaceRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ServiceAccessRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ProcessAccessRights')] - [PowerShellAccessControl.AppliesTo] $AppliesTo = "Object", - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='GenericAccessMask')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='FileRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='FolderRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='RegistryRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRightsObjectAceType')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='LogicalShareRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='PrinterRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='WmiNameSpaceRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ServiceAccessRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ProcessAccessRights')] - [switch] $OnlyApplyToThisContainer, - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRights')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRightsObjectAceType')] - [Parameter(ParameterSetName='GenericAccessMask', ValueFromPipelineByPropertyName=$true)] - $ObjectAceType, - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRightsObjectAceType')] - [Parameter(ParameterSetName='GenericAccessMask', ValueFromPipelineByPropertyName=$true)] - $InheritedObjectAceType, - [Parameter(Mandatory=$true, ParameterSetName='LogicalShareRights')] - [PowerShellAccessControl.LogicalShareRights] $LogicalShareRights, - [Parameter(Mandatory=$true, ParameterSetName='PrinterRights')] - [PowerShellAccessControl.PrinterRights] $PrinterRights, - [Parameter(Mandatory=$true, ParameterSetName='WmiNameSpaceRights')] - [PowerShellAccessControl.WmiNamespaceRights] $WmiNameSpaceRights, - [Parameter(Mandatory=$true, ParameterSetName='ServiceAccessRights')] - [PowerShellAccessControl.ServiceAccessRights] $ServiceAccessRights, - [Parameter(Mandatory=$true, ParameterSetName='ProcessAccessRights')] - [PowerShellAccessControl.ProcessAccessRights] $ProcessAccessRights - ) - -<# - dynamicparam { - $DynamicParams = GetNewAceParams -ReplaceAllParameterSets -AllowAliases - - $DynamicParamNames = $DynamicParams.GetEnumerator() | select -exp Key - - $DynamicParams - } -#> - dynamicparam { - - # If -AceType is SystemAudit, create -AuditSuccess and -AuditFailure parameters - - # Create the dictionary that this scriptblock will return: - $DynParamDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary - - if ($PSBoundParameters.AceType -eq "SystemAudit") { - - foreach ($ParameterName in "AuditSuccess","AuditFailure") { - $ParamAttributes = New-Object System.Management.Automation.ParameterAttribute - - # Create the attribute collection (PSv3 allows you to simply cast a single attribute - # to this type, but that doesn't work in PSv2) - $AttribColl = New-Object System.Collections.ObjectModel.Collection[System.Attribute] # needed for v2 - $AttribColl.Add($ParamAttributes) - $AttribColl.Add([System.Management.Automation.AliasAttribute] [string[]] ($ParameterName -replace "Audit")) - - $DynamicParameter = New-Object System.Management.Automation.RuntimeDefinedParameter ( - $ParameterName, - [switch], - $AttribColl - ) - $DynParamDictionary.Add($ParameterName, $DynamicParameter) - } - } - - # Return the dynamic parameters - $DynParamDictionary - } - - begin { - <# - See the note at the beginning of the CustomShouldProcess function for more info about why I've (hopefully temporarily) - implemented my own ShouldProcess function inside the SD modification functions. - #> - - if ($Force) { - $__CustomConfirmImpact = [System.Management.Automation.ConfirmImpact]::None - $__DefaultReturn = $true - } - else { - $__CustomConfirmImpact = $__ConfirmImpactForApplySdModification - $__DefaultReturn = $false - } - } - - process { - - foreach ($CurrentSDObject in $SDObject) { - - # This can get set later if $SDObject isn't a security descriptor; reset it at the beginning - # of the loop to prevent unwanted apply actions - $Apply = $PsBoundParameters.Apply - - # If $CurrentSDObject isn't an SD yet, this will get re-assigned later when the SD is obtained - $ShouldProcessTarget = "{0} (in memory SD)" -f $CurrentSDObject.Path - - if ($PSCmdlet.ParameterSetName -ne "AceObject") { - # User didn't pass an ACE, so they must have provided the parameters to create one. - - try { - $PsBoundParameters.GetEnumerator() | - where { $__NewAceParameterNames -contains $_.Key } | - foreach -Begin { $NewAceParams = @{} } -Process { $NewAceParams[$_.Key] = $_.Value } - - $AceObject = New-AccessControlEntry @NewAceParams -ErrorAction Stop - } - catch { - Write-Error ("You must provide an ACE object to add. Please see the help for Add-AccessControlEntry (Error from New-AccessControlEntry: {0})" -f $_) - return - } - Write-Verbose "$($MyInvocation.InvocationName): AceObject came through dynamic parameters" - } - else { - Write-Verbose "$($MyInvocation.InvocationName): AceObject came via -AceObject parameter" - } - - # We've got a collection of AceObjects and the SDObject to apply them to. Go through each - # ACE now: - $TypeName = $CurrentSDObject.GetType().FullName - - if ($Overwrite) { - $AddOrSetMethod = "Set" - } - else { - $AddOrSetMethod = "Add" - } - $MethodPartialName = "${AddOrSetMethod}{0}Rule" - - $SdIsDotNetClass = ($TypeName -match "System\.(Security\.AccessControl|DirectoryServices)\.(\w+)Security") - # Make sure the object is a security descriptor (Get-Acl .NET type SD is fine) - if (-not ($CurrentSDObject.pstypenames -contains $__AdaptedSecurityDescriptorTypeName) -and - -not $SdIsDotNetClass) { - - Write-Verbose "$($MyInvocation.InvocationName): SDObject isn't a security descriptor. Attempting to get one from object" - - try { - # Not an object from Get-SecurityDescriptor, so see if it can be converted: - $CurrentSDObject = Get-SecurityDescriptor -InputObject $CurrentSDObject -ErrorAction Stop - $ShouldProcessTarget = "{0} (in memory SD)" -f $CurrentSDObject.Path - } - catch { - Write-Error $_ - return - } - - # If -PassThru was specified, don't set apply (unless it was already set) - $Apply = (-not $PassThru) -or $Apply - - Write-Verbose "$($MyInvocation.InvocationName): -> Conversion succeeded; apply set to $Apply" - } - - foreach ($Ace in $AceObject) { - # Is this an audit or an access rule? This if statements should determine that: - if ($Ace.AuditFlags -is [System.Security.AccessControl.AuditFlags] -and $Ace.AuditFlags -ne "None") { - $RuleKind = "Audit" - $AclType = "SystemAcl" - } - else { - $RuleKind = "Access" - $AclType = "DiscretionaryAcl" - } - - $MethodName = $MethodPartialName -f $RuleKind - Write-Verbose "$($MyInvocation.InvocationName): AceType: $RuleKind; Method to invoke: $MethodName" - - - try { - if ($SdIsDotNetClass) { - # If SD is native .NET class, the ACE must be in the proper format - $Ace = ConvertToSpecificAce -Rules $Ace -AclType $CurrentSDObject.GetType() -ErrorAction Stop - } - else { - # Otherwise, ACE must be CommonAce or ObjectAce - $Ace = ConvertToCommonAce $Ace -ErrorAction Stop - } - } - catch { - Write-Error ("{0} (ACE: {1} - {2})" -f $_, $Ace.IdentityReference, $Ace.AccessMask) - continue - } - - # Now we know the method to invoke, and we have a rule that the method can handle: - $AceDescription = $Ace | GetAceString - $ShouldProcessAction = "Add ACE: $AceDescription" - - # Make sure the SD contains this type of ACL (this is not actually necessary, but adding an entry to a SD that - # doesn't contain that type of ACL could overwrite the real ACL. Imagine an elevated user gets an SD w/o the - # SACL. Then they add an audit rule and apply the changes. If the SACL already had rules, they'll be gone now. - # For that reason, a user has to specify a special switch to add to a non-existent ACL): - if (($SdIsDotNetClass -and (($CurrentSDObject | Get-Member -MemberType CodeProperty -Name $RuleKind) -eq $null)) -or - ((-not $SdIsDotNetClass) -and ($CurrentSDObject."${RuleKind}Present" -eq $false))) { - - if (-not $AddEvenIfAclDoesntExist) { # Could be added to if() condition above... - Write-Warning "Security descriptor ($($CurrentSDObject.Path)) doesn't contain $AclType section. Make sure the security descriptor was obtained using the -Audit switch, or specify the -AddEvenIfAclDoesntExist switch." - continue - } - } - - if ($PSCmdlet.ShouldProcess($ShouldProcessTarget, $ShouldProcessAction)) { - try { - $CurrentSDObject.$MethodName.Invoke($Ace) - } - catch { - Write-Error $_ - continue - } - } - - } # end ACE foreach loop - - if ($Apply) { - Write-Verbose "$($MyInvocation.InvocationName): Apply set, so SD is being applied" - - $Params = @{ - __CustomConfirmImpact = [ref] $__CustomConfirmImpact - __DefaultReturn = [ref] $__DefaultReturn - Action = GetSdString -SDObject $CurrentSDObject - Target = $CurrentSDObject.Path - } - if (CustomShouldProcess @Params) { - Set-SecurityDescriptor -SDObject $CurrentSDObject -Confirm:$false -WhatIf:$false - } - } - if ($PassThru) { - $CurrentSDObject - } - } - } - -} - -#.ExternalHelp PowerShellAccessControl.Help.xml -function Remove-AccessControlEntry { - [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Medium')] - param( - [Parameter(Mandatory=$true, ValueFromPipeline=$true)] - [Alias('Path')] - $SDObject, - [Parameter(Mandatory=$true, ParameterSetName='AceObject')] - [object[]] $AceObject, - [Parameter(ParameterSetName='RemoveAllEntries')] - [switch] $RemoveAllAccessEntries, - [Parameter(ParameterSetName='RemoveAllEntries')] - [switch] $RemoveAllAuditEntries, - [Parameter(ParameterSetName='PurgePrincipal')] - [switch] $PurgeAccessRules, - [Parameter(ParameterSetName='PurgePrincipal')] - [switch] $PurgeAuditRules, - [switch] $Apply, - [switch] $Force, - [switch] $PassThru, - [Parameter(ParameterSetName='AceObject')] - [Parameter(ParameterSetName='GenericAccessMask')] - [Parameter(ParameterSetName='FileRights')] - [Parameter(ParameterSetName='FolderRights')] - [Parameter(ParameterSetName='RegistryRights')] - [Parameter(ParameterSetName='ActiveDirectoryRights')] - [Parameter(ParameterSetName='ActiveDirectoryRightsObjectAceType')] - [Parameter(ParameterSetName='LogicalShareRights')] - [Parameter(ParameterSetName='PrinterRights')] - [Parameter(ParameterSetName='WmiNameSpaceRights')] - [Parameter(ParameterSetName='ServiceAccessRights')] - [Parameter(ParameterSetName='ProcessAccessRights')] - [switch] $Specific, -# Old dynamic params start here: - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='GenericAccessMask')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='FileRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='FolderRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='RegistryRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRightsObjectAceType')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='LogicalShareRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='PrinterRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='WmiNameSpaceRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ServiceAccessRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ProcessAccessRights')] - [ValidateSet( - "AccessAllowed", - "AccessDenied", - "SystemAudit" - )] - [string] $AceType = "AccessAllowed", - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='GenericAccessMask')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='FileRights')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='FolderRights')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='RegistryRights')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRights')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRightsObjectAceType')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='LogicalShareRights')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='PrinterRights')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='WmiNameSpaceRights')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='ServiceAccessRights')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='ProcessAccessRights')] - [Parameter(Mandatory=$true, ParameterSetName='PurgePrincipal')] - [Alias('IdentityReference','SecurityIdentifier')] - $Principal, - [Parameter(Mandatory=$true, ParameterSetName='FileRights')] - [Alias('FileSystemRights')] - [System.Security.AccessControl.FileSystemRights] $FileRights, - [Parameter(Mandatory=$true, ParameterSetName='FolderRights')] - [System.Security.AccessControl.FileSystemRights] $FolderRights, - [Parameter(Mandatory=$true, ParameterSetName='RegistryRights')] - [System.Security.AccessControl.RegistryRights] $RegistryRights, - [Parameter(Mandatory=$true, ParameterSetName='ActiveDirectoryRights')] - [PowerShellAccessControl.ActiveDirectoryRights] $ActiveDirectoryRights, - [Parameter(Mandatory=$true, ParameterSetName='GenericAccessMask', ValueFromPipelineByPropertyName=$true)] - [int] $AccessMask, - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='GenericAccessMask')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='FileRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='FolderRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='RegistryRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRightsObjectAceType')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='LogicalShareRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='PrinterRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='WmiNameSpaceRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ServiceAccessRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ProcessAccessRights')] - [PowerShellAccessControl.AppliesTo] $AppliesTo = "Object", - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='GenericAccessMask')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='FileRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='FolderRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='RegistryRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRightsObjectAceType')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='LogicalShareRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='PrinterRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='WmiNameSpaceRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ServiceAccessRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ProcessAccessRights')] - [switch] $OnlyApplyToThisContainer, - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRights')] - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRightsObjectAceType')] - [Parameter(ParameterSetName='GenericAccessMask', ValueFromPipelineByPropertyName=$true)] - $ObjectAceType, - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRights')] - [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='ActiveDirectoryRightsObjectAceType')] - [Parameter(ParameterSetName='GenericAccessMask', ValueFromPipelineByPropertyName=$true)] - $InheritedObjectAceType, - [Parameter(Mandatory=$true, ParameterSetName='LogicalShareRights')] - [PowerShellAccessControl.LogicalShareRights] $LogicalShareRights, - [Parameter(Mandatory=$true, ParameterSetName='PrinterRights')] - [PowerShellAccessControl.PrinterRights] $PrinterRights, - [Parameter(Mandatory=$true, ParameterSetName='WmiNameSpaceRights')] - [PowerShellAccessControl.WmiNamespaceRights] $WmiNameSpaceRights, - [Parameter(Mandatory=$true, ParameterSetName='ServiceAccessRights')] - [PowerShellAccessControl.ServiceAccessRights] $ServiceAccessRights, - [Parameter(Mandatory=$true, ParameterSetName='ProcessAccessRights')] - [PowerShellAccessControl.ProcessAccessRights] $ProcessAccessRights - ) - -<# - dynamicparam { - $DynamicParams = GetNewAceParams -ReplaceAllParameterSets - - $DynamicParamNames = $DynamicParams.GetEnumerator() | select -exp Key - - $DynamicParams - } -#> - dynamicparam { - - # If -AceType is SystemAudit, create -AuditSuccess and -AuditFailure parameters - - # Create the dictionary that this scriptblock will return: - $DynParamDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary - - if ($PSBoundParameters.AceType -eq "SystemAudit") { - - foreach ($ParameterName in "AuditSuccess","AuditFailure") { - $ParamAttributes = New-Object System.Management.Automation.ParameterAttribute - - # Create the attribute collection (PSv3 allows you to simply cast a single attribute - # to this type, but that doesn't work in PSv2) - $AttribColl = New-Object System.Collections.ObjectModel.Collection[System.Attribute] # needed for v2 - $AttribColl.Add($ParamAttributes) - $AttribColl.Add([System.Management.Automation.AliasAttribute] [string[]] ($ParameterName -replace "Audit")) - - $DynamicParameter = New-Object System.Management.Automation.RuntimeDefinedParameter ( - $ParameterName, - [switch], - $AttribColl - ) - $DynParamDictionary.Add($ParameterName, $DynamicParameter) - } - } - - # Return the dynamic parameters - $DynParamDictionary - } - - begin { - <# - See the note at the beginning of the CustomShouldProcess function for more info about why I've (hopefully temporarily) - implemented my own ShouldProcess function inside the SD modification functions. - #> - - if ($Force) { - $__CustomConfirmImpact = [System.Management.Automation.ConfirmImpact]::None - $__DefaultReturn = $true - } - else { - $__CustomConfirmImpact = $__ConfirmImpactForApplySdModification - $__DefaultReturn = $false - } - } - - process { - foreach ($CurrentSDObject in $SDObject) { - # This can get set later if $SDObject isn't a security descriptor; reset it at the beginning - # of the loop to prevent unwanted apply actions - $Apply = $PsBoundParameters.Apply - - $ShouldProcessTarget = "{0} (in memory SD)" -f $CurrentSDObject.Path - - if ("AceObject","RemoveAllEntries", "PurgePrincipal" -notcontains $PSCmdlet.ParameterSetName) { - # If the param set isn't one of these, that means ACE object params were provided - # through the dynamic parameters. Call AceObject w/ the bound parameters: - - try { - $PsBoundParameters.GetEnumerator() | - where { $__NewAceParameterNames -contains $_.Key } | - foreach -Begin { $NewAceParams = @{} } -Process { $NewAceParams[$_.Key] = $_.Value } - - $AceObject = New-AccessControlEntry @NewAceParams -ErrorAction Stop - } - catch { - Write-Error "You must provide an ACE object to remove. Please see the help for Remove-AccessControlEntry" - return - } - } - - # We've got a collection of AceObjects and the SDObject to apply them to. Go through each - # ACE now: - $TypeName = $CurrentSDObject.GetType().FullName - - $MethodPartialName = "Remove{0}Rule" - - $SdIsDotNetClass = ($TypeName -match "System\.(Security\.AccessControl|DirectoryServices)\.(\w+)Security") - # Make sure the object is a security descriptor (Get-Acl .NET type SD is fine) - if (-not ($CurrentSDObject.pstypenames -contains $__AdaptedSecurityDescriptorTypeName) -and - -not $SdIsDotNetClass) { - - Write-Verbose "$($MyInvocation.InvocationName): SDObject isn't a security descriptor. Attempting to get one from object" - - try { - # Not an object from Get-SecurityDescriptor, so see if it can be converted: - $CurrentSDObject = Get-SecurityDescriptor -InputObject $CurrentSDObject -ErrorAction Stop - $ShouldProcessTarget = "{0} (in memory SD)" -f $CurrentSDObject.Path - } - catch { - Write-Error $_ - return - } - - # If -PassThru was specified, don't set apply (unless it was already set) - $Apply = (-not $PassThru) -or $Apply - - Write-Verbose "$($MyInvocation.InvocationName): -> Conversion succeeded; apply set to $Apply" - } - - if ($PSCmdlet.ParameterSetName -eq "PurgePrincipal") { - # Call purge method on each object: - $MethodsToCall = @() - if ($PurgeAuditRules) { - $MethodsToCall += "PurgeAuditRules" - } - if ($PurgeAccessRules -or (-not $MethodsToCall)) { - # If -PurgeAuditRules wasn't passed, we'll have to run as - # though -PurgeAccessRules was passed - $MethodsToCall += "PurgeAccessRules" - } - - foreach ($Method in $MethodsToCall) { - if ($PSCmdlet.ShouldProcess($ShouldProcessTarget, "Invoke $Method for $Principal principal")) { - $CurrentSDObject.$Method.Invoke(($Principal | ConvertToIdentityReference)) - } - } - } - else { - - if ($PSCmdlet.ParameterSetName -eq "RemoveAllEntries") { - # Just make the $AceObject collection every ACL entry. Alternative would be to create - # blank ACL objects, but then there would have to be more logic. If this ends up being - # really slow, I'll investigate the alternate method - $AceObject = @() - if ($RemoveAllAccessEntries) { - $AceObject += $CurrentSDObject.Access - } - - if ($RemoveAllAuditEntries) { - $AceObject += $CurrentSDObject.Audit - } - } - - foreach ($Ace in $AceObject) { - # Is this an audit or an access rule? These if statements should determine that: - if ($Ace.AuditFlags -is [System.Security.AccessControl.AuditFlags] -and $Ace.AuditFlags -ne "None") { - $RuleKind = "Audit" - $AclType = "SystemAcl" - } - else { - $RuleKind = "Access" - $AclType = "DiscretionaryAcl" - } - - $MethodName = $MethodPartialName -f $RuleKind - - # If -Specific switch was supplied, append 'Specific' to the MethodName - if ($Specific) { - $MethodName = "${MethodName}Specific" - } - - try { - if ($SdIsDotNetClass) { - # If SD is native .NET class, the ACE must be in the proper format - $Ace = ConvertToSpecificAce -Rules $Ace -AclType $CurrentSDObject.GetType() -ErrorAction Stop - } - else { - # Otherwise, ACE must be CommonAce or ObjectAce - $Ace = ConvertToCommonAce $Ace -ErrorAction Stop - } - } - catch { - Write-Error ("{0} (ACE: {1} - {2})" -f $_, $Ace.IdentityReference, $Ace.AccessMask) - continue - } - - # Now we know the method to invoke, and we have a rule that the method can handle: - - $AceDescription = $Ace | GetAceString - $ShouldProcessAction = "Remove ACE: $AceDescription" - - if ($PSCmdlet.ShouldProcess($ShouldProcessTarget, $ShouldProcessAction)) { - try { - [void] $CurrentSDObject.$MethodName.Invoke($Ace) - } - catch { - Write-Error $_ - continue - } - } - - } # end ACE foreach loop - } # end else (after check for purge param set) - - if ($Apply) { - Write-Verbose "$($MyInvocation.InvocationName): Apply set, so SD is being applied" - - $Params = @{ - __CustomConfirmImpact = [ref] $__CustomConfirmImpact - __DefaultReturn = [ref] $__DefaultReturn - Action = GetSdString -SDObject $CurrentSDObject - Target = $CurrentSDObject.Path - } - if (CustomShouldProcess @Params) { - Set-SecurityDescriptor -SDObject $CurrentSDObject -Confirm:$false -WhatIf:$false - } - } - if ($PassThru) { - $CurrentSDObject - } - } # end SDObject foreach loop - } -} - -#.ExternalHelp PowerShellAccessControl.Help.xml -function Set-Owner { - - [CmdletBinding(DefaultParameterSetName='Path', SupportsShouldProcess=$true)] - param( - [Parameter(Position=0)] - [Alias('User','Group','IdentityReference')] - # The object that this ACE will apply to. This can be a string representing a user, group, - # or SID. It can also be a [System.Security.Principal.NTAccount] or a - # [System.Security.Principal.SecurityIdentifier] object. - $Principal = $env:USERNAME, - [Parameter(Mandatory=$true, ParameterSetName='InputObject', ValueFromPipeline=$true)] - [Alias('SDObject')] - $InputObject, - [Parameter(Mandatory=$true, ParameterSetName='Path', ValueFromPipelineByPropertyName=$true)] - [Parameter(Mandatory=$true, ParameterSetName='DirectPath', ValueFromPipelineByPropertyName=$true)] - [string[]] $Path, - [Parameter(Mandatory=$true, ParameterSetName='DirectPath')] - [System.Security.AccessControl.ResourceType] $ObjectType, - [Parameter(ParameterSetName='DirectPath')] - [switch] $IsContainer = $false, - [Parameter(Mandatory=$true, ParameterSetName='LiteralPath', ValueFromPipelineByPropertyName=$true)] - [string[]] $LiteralPath, - [switch] $Apply, - [switch] $Force, - [switch] $PassThru - ) - - begin { - <# - See the note at the beginning of the CustomShouldProcess function for more info about why I've (hopefully temporarily) - implemented my own ShouldProcess function inside the SD modification functions. - #> - - if ($Force) { - $__CustomConfirmImpact = [System.Management.Automation.ConfirmImpact]::None - $__DefaultReturn = $true - } - else { - $__CustomConfirmImpact = $__ConfirmImpactForApplySdModification - $__DefaultReturn = $false - } - } - process { - $Principal = $Principal | ConvertToIdentityReference -ReturnAccount -ErrorAction Stop - - try { - $TranslatedPrincipal = $Principal | ConvertToIdentityReference -ReturnSid -ErrorAction Stop - } - catch { - Write-Error $_ - return - } - - $ShouldProcessAction = "Set owner to '$Principal'" - switch ($PSCmdlet.ParameterSetName) { - "InputObject" { - # An object was passed to the function. After a little param validation, do the - # same thing that .SetOwner() method would do on a Get-Acl object, i.e., simply - # change the owner on the in memory SD object: - - $MethodName = "SetOwner" # The method that will be invoked on SD objects - - foreach ($CurrentSDObject in $InputObject) { - # This can get set later if $SDObject isn't a security descriptor; reset it at the beginning - # of the loop to prevent unwanted apply actions - $Apply = $PsBoundParameters.Apply - - $ShouldProcessTarget = "{0} (in memory SD)" -f $CurrentSDObject.Path - - $TypeName = $CurrentSDObject.GetType().FullName - if ($TypeName -eq "System.Security.AccessControl.RegistrySecurity" -or - $TypeName -match "System.Security.AccessControl.(File|Directory)Security") { - - # The SDObject is a .NET file or registry security object from Get-Acl - # This is fine, and no extra work should be necessary b/c the methods that - # will be called are the same for Get-Acl objects and Get-SD objects - } - elseif (-not ($CurrentSDObject.pstypenames -contains $__AdaptedSecurityDescriptorTypeName)) { - - try { - # Not an object from Get-SecurityDescriptor, so see if it can be converted: - $CurrentSDObject = Get-SecurityDescriptor -InputObject $CurrentSDObject -ErrorAction Stop - $ShouldProcessTarget = "{0} (in memory SD)" -f $CurrentSDObject.Path - } - catch { - Write-Error $_ - return - } - - # If -PassThru was specified, don't set apply (unless it was already set) - $Apply = (-not $PassThru) -or $Apply - } - - if ($PSCmdlet.ShouldProcess($ShouldProcessTarget, "Invoke $MethodName method")) { - $CurrentSDObject.$MethodName.Invoke($TranslatedPrincipal) - } - - if ($Apply) { - Write-Verbose "$($MyInvocation.InvocationName): Apply set, so SD is being applied" - - $Params = @{ - __CustomConfirmImpact = [ref] $__CustomConfirmImpact - __DefaultReturn = [ref] $__DefaultReturn - Action = GetSdString -SDObject $CurrentSDObject -SecurityInformation Owner - Target = $CurrentSDObject.Path - } - if (CustomShouldProcess @Params) { - Set-SecurityDescriptor -SDObject $CurrentSDObject -Confirm:$false -WhatIf:$false -Sections Owner - } - } - if ($PassThru) { - $CurrentSDObject - Write-Warning ("Please apply the security descriptor for '{0}' and get it again to reflect any inherited entries" -f $CurrentSDObject.Path) - } - } - } - - { $_ -eq "Path" -or $_ -eq "LiteralPath" -or $_ -eq "DirectPath" } { - - # This looks a little weird, but what's happening is simple: - # We're going to create a temporary SD that only has an owner. To do that, we need - # to get the path information (including object type, etc), then feed that into the - # New-Adapted.... function, and then we'll call Set-Owner on that. We want the same - # parameters passed to it (except we're adding an -Apply parameter), but we can't pass - # the Path (or LiteralPath) back to it. For that reason, we remove the *Path property, - # then splat $PSboundParameters to Set-Owner. - $PathPropertyName = $PSCmdlet.ParameterSetName -replace "^Direct" - $ExtraParam = @{ $PathPropertyName = $PSBoundParameters.$PathPropertyName } - $null = $PSBoundParameters.Remove($PathPropertyName) - - $PSBoundParameters.Apply = (-not $PassThru) -or ($Apply) - # Create a SD with an owner and a blank DACL (don't worry, Set-Owner only sets the owner; the blank DACL is - # there to prevent having an ACE that gives everyone allow permissions [which still wouldn't matter, but - # who cares?]) - $PathInfo = GetPathInformation @PSBoundParameters @ExtraParam - $null = $PathInfo.Remove("InputObject") - New-AdaptedSecurityDescriptor -Sddl "O:${TranslatedPrincipal}D:" @PathInfo| Set-Owner @PSBoundParameters - return - } - } - } -} - -#.ExternalHelp PowerShellAccessControl.Help.xml -function Get-EffectiveAccess { - [CmdletBinding()] - param( - [Parameter(Mandatory=$true, ParameterSetName='InputObject', ValueFromPipeline=$true)] - [Alias("SDObject")] - $InputObject, - [Parameter(ParameterSetName='Path', Position=0, ValueFromPipelineByPropertyName=$true)] - [string[]] $Path = ".", - [Parameter(Mandatory=$true, ParameterSetName='LiteralPath', ValueFromPipelineByPropertyName=$true)] - [string[]] $LiteralPath, - [Alias('User', 'Group', 'IdentityReference')] - [string[]] $Principal = $env:USERNAME, - [switch] $ListAllRights, - # Used for AD objects - $ObjectAceTypes - ) - - - process { - if ($PSCmdlet.ParameterSetName -eq "Path" -and (-not $PSBoundParameters.ContainsKey("Path"))) { - # GetPathInformation uses PSBoundParameters, so set it up as if the default path was passed - # as a bound parameter: - $null = $PSBoundParameters.Add("Path", $Path) - } - - if ($PSCmdlet.ParameterSetName -ne "InputObject") { - $Params = @{ - $PSCmdlet.ParameterSetName = $PSBoundParameters[$PSCmdlet.ParameterSetName] - } - - $InputObject = Get-SecurityDescriptor @Params -ErrorAction Stop - } - - foreach ($CurrentSDObject in $InputObject) { - if ($CurrentSDObject.pstypenames -notcontains $__AdaptedSecurityDescriptorTypeName) { - - try { - # Not an object from Get-SecurityDescriptor, so see if it can be converted: - $CurrentSDObject = Get-SecurityDescriptor -InputObject $CurrentSDObject -ErrorAction Stop - } - catch { - Write-Error $_ - return - } - } - - $AccessMaskEnumeration = $CurrentSDObject.GetAccessMaskEnumeration() - - if ($AccessMaskEnumeration -eq $null) { - $AccessMaskEnumeration = [int] - } - - # The AuthZ AccessCheck takes a requested access and returns the actual access. There is a special - # requested access that means check for the maximum allowed: 0x02000000 - # For now, use that (in the future, maybe the functionc an take this as a parameter - $DesiredAccess = 0x02000000 # MAX ALLOWED - $TypeName = $__EffectiveAccessTypeName - - # AuthzAccessCheck is called against a binary security descriptor. File and folder objects can - # have multiple SDs (NTFS permissions, share permissions, and any number of central access - # rules). Store each of those in a hash table (the key allows us to show where each right is - # being limited), and call AuthzAccessCheck on each one. - if ($CurrentSDObject.ObjectType -eq 'FileObject' -and (-not $ListAllRights) -and ($__OsVersion -gt "6.2")) { - # If -ListAllRights isn't specified, AuthzAccessCheck will show true effective rights if - # Attribute and Scope are in the SD - $SdBytes = GetSecurityInfo -Path $CurrentSDObject.SdPath -ObjectType $CurrentSDObject.ObjectType -SecurityInformation Owner, Group, Dacl, Attribute, Scope - - # Windows 8 or higher supports CAP and object attributes, so get that information and add it to $SdBytes. - # - # NOTE: The correct way to do this is get the binary form of the extra info and pass it into the OptionalSecurityDescriptorArray - # argument, but that's not currently working. I suspect that more manual memory allocation and layout is required, so I'm - # taking the easy way out for now and simply modifying the entire SD - } - else { - $SdBytes = $CurrentSDObject.GetSecurityDescriptorBinaryForm() - } - - # AuthzAccessCheck is going to be called against all security descriptors in this hash table. For now, - # files/folders should be the only objects that have multiple security descriptors, so most objects - # will only have the "Object Permissions" security descriptor. - # - # Files and folders can have multiple layers of security: - # - Object Permissions - # - Share Permissions - # - Central Access Policy - # - Central Access Rules (more than one) - # - # Naming the SD in this hash table allows the -ListAllRights option to show the user why a right - # is denied/limited. - $SecurityDescriptorsToCheck = @{ - "Object Permissions" = $SdBytes - } - - if ($CurrentSDObject.ObjectType -eq 'FileObject') { - # Check to see if this is a share: - if ($CurrentSDObject.SdPath -match "(?\\\\[^\\]+\\[^\\]+)") { - try { - $ShareSd = Get-SecurityDescriptor -Path $Matches.sharepath -ObjectType LMShare -ErrorAction Stop - $NewSd = New-AdaptedSecurityDescriptor -Sddl "D:" -IsContainer - $NewSd.SecurityDescriptor.Owner = $ShareSd.Owner | ConvertToIdentityReference -ReturnSid - $NewSd.SecurityDescriptor.Group = $ShareSd.Group | ConvertToIdentityReference -ReturnSid - - $ShareSd.Access | ForEach-Object { - $TranslatedFolderRights = $_.AccessMaskDisplay -replace "Change", "Modify" - - $NewSd | Add-AccessControlEntry -Principal $_.Principal -FolderRights $TranslatedFolderRights -ErrorAction Stop - } - - $SecurityDescriptorsToCheck."Share Permissions" = $NewSd.GetSecurityDescriptorBinaryForm() - } - catch { - Write-Debug ("{0}: Failed to get share permissions for {1}" -f $MyInvocation.MyCommand, $Matches.sharepath) - } - } - -#$SecurityDescriptorsToCheck."Test Alternate SD" = (Get-SecurityDescriptor C:\windows).GetSecurityDescriptorBinaryForm() - - <# - Check for Central Access Policies here: - - If there is a CAP, go through each central access rule - - For each rule, check to see if there is a condition that must be met and evaluate it - - If condition is met, add a security descriptor to the hash table that includes the DACL - - Get OptionalSecurityDescriptor working in the AuthzAccessCheck() call, or manually add - attribute information to the SACL of the SD being added to the hash table (attribute info - must be passed to AuthzAccessCheck) - #> - } - - foreach ($CurrentIdentityReference in $Principal) { - $CurrentIdentityReference = $CurrentIdentityReference | ConvertToIdentityReference -ReturnAccount -DontVerifyNtAccount - - try { - $Sid = $CurrentIdentityReference | ConvertToIdentityReference -ReturnSid -ErrorAction Stop - $SidBytes = New-Object byte[] $Sid.BinaryLength - $Sid.GetBinaryForm($SidBytes, 0) - } - catch { - Write-Error "Error translating '$CurrentIdentityReference' to SID: $_" - continue - } - - # Build the request object - $Request = New-Object PowerShellAccessControl.PInvoke.authz+AUTHZ_ACCESS_REQUEST - $Request.DesiredAccess = $DesiredAccess - - #region DSObject Request object - if ($CurrentSDObject.ObjectType -match "^DSObject") { - # SD belongs to an AD object. AD objects can have much more complicated request objects - # if we're going to check at the property level. - - [PowerShellAccessControl.PInvoke.authz+OBJECT_TYPE_LIST[]] $ObjectTypeListArray = @() - $ObjectTypeList = New-Object PowerShellAccessControl.PInvoke.authz+OBJECT_TYPE_LIST - - # The object's type GUID always goes at level 0 (I think this is so the API will be - # able to check an ACE's InheritedObjectAceType to see when an ACE applies to this - # object) - $ObjectTypeList.Level = 0 - $ObjectType = (Get-ADObjectAceGuid -Name $CurrentSDObject.DsObjectClass -TypesToSearch ClassObject | select -first 1 -exp guid).ToByteArray() - $Ptr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($ObjectType.Count) - [System.Runtime.InteropServices.Marshal]::Copy($ObjectType, 0, $Ptr, $ObjectType.Count) - $ObjectTypeList.ObjectType = $Ptr - $ObjectTypeListArray += $ObjectTypeList - - - Write-Verbose "$(Get-Date): Grouping requested properties by PropertySet" - $GroupedProperties = $ObjectAceTypes | Where-Object { $_ } | ForEach-Object { - - # User passed something to the -ObjectAceTypes function. Wildcards are allowed in strings passed, so it's - # possible that the list of ObjectAceTypes is going to get HUGE (especially if the * string is passed, - # which would mean show effective access for ALL ObjectAceTypes. - # - # The longest part of doing that is figuring out the Property and PropertySet relationships, so those are - # cached if the list of objects grows large enough (an arbitrary number below) - if ($__GroupedPropertyCache.ContainsKey($_)) { - Write-Verbose "$($MyInvocation.MyCommand): ObjectAceType '$_' results have been previously cached" - $__GroupedPropertyCache.$_ - } - else { - # Not cached, so get the information - $Params = @{ - TypesToSearch = "Property" - } - - if ($_ -is [PSObject] -and $_.Guid -is [guid]) { - $Params.Guid = $_.Guid - } - else { - $Guid = $_ -as [guid] - if ($Guid) { - $Params.Guid = $Guid - } - else { - $Params.Name = "^{0}$" -f $_.ToString() - } - - $Properties = Get-ADObjectAceGuid @Params - - $CurrentGroupedProperties = $Properties | ForEach-Object -Begin { $Count = 0 } -Process { - Write-Progress -Activity "Building property list" -Status ("Current property: {0}" -f $_.Name) -PercentComplete (($Count++/$Properties.Count) * 100) - New-Object PSObject -Property @{ - Property = $_.Guid - PropertySet = (LookupPropertySet -Property $_.Guid | select -exp Value -ErrorAction SilentlyContinue) - } - } -End { Write-Progress -Completed -Activity "Building property list" -Status "" } | Group-Object PropertySet - - $__PropertyCountToCache = 1000 - if ($Properties.Count -gt $__PropertyCountToCache) { - Write-Verbose "$($MyInvocation.MyCommand): Property count for ObjectAceType '$_' is $($Properties.Count); adding to cache" - $__GroupedPropertyCache.$_ = $CurrentGroupedProperties - } - - $CurrentGroupedProperties - } - } - } - - # This next part adds each property (and its propery set) to the $ObjectTypeListArray. - # The .Level property will be 1 for properties w/o a property set, and 2 for properties - # w/ a property set (the property set will be at level 1). This will output any encountered - # property sets so any property sets that we can compare that list with all requested - # property sets in a little bit. - $RequestedPropertiesPropertySets = $GroupedProperties | ForEach-Object { - - # Name property contains the PropertySet guid and the group property contains - # the property guids - if ($_.Name -eq "") { - # Properties with a null PropertySet don't belong to one. They will be at - # level 1 in the tree - $Level = 1 - } - else { - # Set up the property set first, then go through all properties - $ObjectTypeList.Level = 1 - $ObjectType = ([guid] $_.Name).ToByteArray() - $Ptr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($ObjectType.Count) - [System.Runtime.InteropServices.Marshal]::Copy($ObjectType, 0, $Ptr, $ObjectType.Count) - $ObjectTypeList.ObjectType = $Ptr - $ObjectTypeListArray += $ObjectTypeList - - # Properties will be at this level: - $Level = 2 - - # Output this so that a list of used PropertySets can be maintained. If the $RequestedPropertySets - # contains GUIDs that aren't encountered while building the properties, then they will be added - # to the tree later - $_.Name - } - - $_.Group | Select-Object -exp Property | ForEach-Object { - $ObjectTypeList.Level = $Level - $ObjectType = ([guid] $_).ToByteArray() - $Ptr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($ObjectType.Count) - [System.Runtime.InteropServices.Marshal]::Copy($ObjectType, 0, $Ptr, $ObjectType.Count) - $ObjectTypeList.ObjectType = $Ptr - $ObjectTypeListArray += $ObjectTypeList - } - } - - # We've got a list of all of the properties that the user is after, and they are now grouped - # by their property set (properties with no property set show a $null property set). Now get - # any other object types requested: - Write-Verbose "$(Get-Date): Getting non-property object types" - $NonPropertyObjectAceTypes = $ObjectAceTypes | Where-Object { $_ } | ForEach-Object { - $Params = @{ - TypesToSearch = "ClassObject", "ExtendedRight", "ValidatedWrite", "PropertySet" - } - - if ($_ -is [PSObject] -and $_.Guid -is [guid]) { - $Params.Guid = $_.Guid - } - else { - $Guid = $_ -as [guid] - if ($Guid) { - $Params.Guid = $Guid - } - else { - $Params.Name = $_.ToString() - } - } - - Get-ADObjectAceGuid @Params - } - - # Now it's time to add any PropertySets that were requested that haven't been added yet - Write-Verbose "$(Get-Date): Getting any property sets that weren't already found" - $RefObject = $NonPropertyObjectAceTypes | Where-Object { $_.Type -eq "PropertySet" } | select -ExpandProperty Guid - - # These next two variables should be null b/c of compare-object call - if (-not $RefObject) { $RefObject = @() } - if (-not $RequestedPropertiesPropertySets) { $RequestedPropertiesPropertySets = @() } - Write-Verbose "$(Get-Date): Getting any property sets that weren't already found (using compare-object)" - Compare-Object -ReferenceObject $RefObject -DifferenceObject $RequestedPropertiesPropertySets | - Where-Object { $_.SideIndicator -eq "<=" } | ForEach-Object { - $ObjectTypeList.Level = 1 - $ObjectType = ([guid] $_.InputObject).ToByteArray() - $Ptr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($ObjectType.Count) - [System.Runtime.InteropServices.Marshal]::Copy($ObjectType, 0, $Ptr, $ObjectType.Count) - $ObjectTypeList.ObjectType = $Ptr - $ObjectTypeListArray += $ObjectTypeList - } - - # Finally, add any object types that have been requested that are not properties or property sets: - Write-Verbose "$(Get-Date): Getting non-property objects" - $NonPropertyObjectAceTypes | Where-Object { $_.Type -notmatch "^Property" } | ForEach-Object { - $ObjectTypeList.Level = 1 - $ObjectType = ([guid] $_.Guid).ToByteArray() - $Ptr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($ObjectType.Count) - [System.Runtime.InteropServices.Marshal]::Copy($ObjectType, 0, $Ptr, $ObjectType.Count) - $ObjectTypeList.ObjectType = $Ptr - $ObjectTypeListArray += $ObjectTypeList - } - - # Now, unfortunately, we've got to manually allocate the memory for the OBJECT_TYPE_LIST: - $SizeOfStruct = [System.Runtime.InteropServices.Marshal]::SizeOf([type][PowerShellAccessControl.PInvoke.authz+OBJECT_TYPE_LIST]) - $ptrObjectTypeListArray = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($SizeOfStruct * $ObjectTypeListArray.Count) - for ($i = 0; $i -lt $ObjectTypeListArray.Count; $i++) { - $ptrObjectTypeList = $ptrObjectTypeListArray.ToInt64() + ($SizeOfStruct * $i) - [System.Runtime.InteropServices.Marshal]::StructureToPtr($ObjectTypeListArray[$i], $ptrObjectTypeList, $false) - } - - $Request.ObjectTypeList = $ptrObjectTypeListArray - $Request.ObjectTypeListLength = $ObjectTypeListArray.Count - } - #endregion - - # Build the reply object. The ResultListLength property depends on the ObjectTypeListLength - # in the request object (if it's not a AD object and it is 0, then the ResultListLength - # is 1) - $ResultListLength = $Request.ObjectTypeListLength - if ($ResultListLength -eq 0) { $ResultListLength = 1 } - - $Reply = New-Object PowerShellAccessControl.PInvoke.authz+AUTHZ_ACCESS_REPLY - $Reply.ResultListLength = $ResultListLength - $Reply.Error = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($Reply.ResultListLength * [System.Runtime.InteropServices.Marshal]::SizeOf([type] [UInt32])) - $Reply.GrantedAccessMask = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($Reply.ResultListLength * [System.Runtime.InteropServices.Marshal]::SizeOf([type] [UInt32])) - $Reply.SaclEvaluationResults = [System.IntPtr]::Zero #[System.Runtime.InteropServices.Marshal]::AllocHGlobal($Reply.ResultListLength * [System.Runtime.InteropServices.Marshal]::SizeOf([type] [UInt32])) - - try { - # Get a resource manager handle. This isn't the best place for this b/c it causes the - # handle to be opened and freed for each principal and for each security descriptor. This - # belongs in the begin block. That will happen one day when the function is restructured. - $hResourceManager = [System.IntPtr]::Zero - [PowerShellAccessControl.PInvoke.authz]::AuthzInitializeResourceManager( - [PowerShellAccessControl.PInvoke.AuthZEnums.AuthzResourceManagerFlags]::NoAudit, # Flags - [System.IntPtr]::Zero, # Access check callback function (Not used here) - [System.IntPtr]::Zero, # Dynamic groups callback function (Not used here) - [System.IntPtr]::Zero, # Callback function to free memory from previous callback (Not used here) - "", # Resource manager name - [ref] $hResourceManager # Resource manager handle that we're after :) - ) | CheckExitCode -ErrorAction Stop -Action "Initializing resource manager" - - - # Get a client context handle - $hClientContext = [System.IntPtr]::Zero - $UnusedId = New-Object PowerShellAccessControl.PInvoke.authz+LUID - [PowerShellAccessControl.PInvoke.authz]::AuthzInitializeContextFromSid( - [PowerShellAccessControl.PInvoke.AuthZEnums.AuthzContextFlags]::None, # Flags; none for now. If S4U logon not available, some groups are omitted. See http://msdn.microsoft.com/en-us/library/windows/desktop/aa376309(v=vs.85).aspx - $SidBytes, # Sid to create the context for - $hResourceManager, # Resource manager handle - [System.IntPtr]::Zero, # Expiration time (not enforced, so not using; if ever use, need to update PInvoke signature) - $UnusedId, # This param isn't currently used; can probably update PInvoke signature to not require LUID signature and creation - [System.IntPtr]::Zero, # Dynamic groups callback arguments (Not used here) - [ref] $hClientContext # The returned handle - ) | CheckExitCode -ErrorAction Stop -Action "Initializing context from SID" - - - # Build a script block to do the AuthzAccessCheck. SB is used instead of directly calling it b/c - # sometimes a Group-Object call is added between calling AuthzAccessCheck() and crafting the - # output objects. That would introduce a significant delay for AD objects w/ large request objects. - $SecurityDescriptorsToCheck.GetEnumerator() | ForEach-Object { - $CurrentSdEntry = $_ - - Write-Debug "Calling AuthzAccessCheck" - [PowerShellAccessControl.PInvoke.authz]::AuthzAccessCheck( - [PowerShellAccessControl.PInvoke.AuthZEnums.AuthzAccessCheckFlags]::None, # Flags - $hClientContext, # Client context handle - [ref] $Request, - [System.IntPtr]::Zero, # Audit event (not used here) - $CurrentSdEntry.Value, # Binary form of SD - $null, # Optional security descriptors - 0, # Optional SD count (see previous argument) - [ref] $Reply, # - [ref] [System.IntPtr]::Zero # Check results (Used for caching??) - ) | CheckExitCode -ErrorAction Stop -Action "Performing access check" - -<# -# GrantedMask and ErrorCode are returned as pointers, so read the Int32 value from where they point: -$GrantedMask = [System.Runtime.InteropServices.Marshal]::ReadInt32($Reply.GrantedAccessMask) -$ErrorCode = [System.Runtime.InteropServices.Marshal]::ReadInt32($Reply.Error) -$ErrorMessage = ([System.ComponentModel.Win32Exception] $ErrorCode).Message -#> - $OutputProperties = @{ - DisplayName = $CurrentSDObject.DisplayName - IdentityReference = $CurrentIdentityReference - #MessageDebug = $ErrorMessage - } - - # Go through each reply (if the object wasn't an AD object or there were no -ObjectAceTypes provided, there - # will only be one reply) - $SizeOfInt = [System.Runtime.InteropServices.Marshal]::SizeOf([type] [UInt32]) - for ($i = 0; $i -lt $Reply.ResultListLength; $i++) { - - # GrantedMask and ErrorCode are returned as pointers, so read the Int32 value from where they point: - $GrantedMask = [System.Runtime.InteropServices.Marshal]::ReadInt32($Reply.GrantedAccessMask.ToInt64() + ($i * $SizeOfInt)) - $ErrorCode = [System.Runtime.InteropServices.Marshal]::ReadInt32($Reply.Error.ToInt64() + ($i * $SizeOfInt)) - $ErrorMessage = ([System.ComponentModel.Win32Exception] $ErrorCode).Message - - -<# - # If there was no granted access for this ObjectType (only ObjectTypes should be affected b/c $i - # must be greater than 0) and -ListAllRights wasn't specified, then don't even output an object - if ($GrantedMask -eq 0 -and $i -gt 0) { - continue - } -#> - - # Only look at replies after the first one (so only AD objects) - if ($ObjectTypeListArray -and ($i -gt 0)) { - $Guid = [System.Runtime.InteropServices.Marshal]::PtrToStructure($ObjectTypeListArray[$i].ObjectType, [type][guid]) - } - else { - $Guid = [guid]::Empty - } - - $OutputProperties = @{ - Guid = $Guid - Permission = $GrantedMask - LimitedBy = $CurrentSdEntry.Name - } - - New-Object PSObject -Property $OutputProperties - } - } | Group-Object Guid | ForEach-Object { - $Group = @($_.Group) - - $OutputProperties = @{ - DisplayName = $CurrentSDObject.DisplayName - IdentityReference = $CurrentIdentityReference - } - - $GetPermissionParams = @{ - AccessMaskEnumeration = $AccessMaskEnumeration - } - - if (-not $ListAllRights) { - $TypeName = $__EffectiveAccessTypeName - - $CombinedEffectiveAccess = [int32]::MaxValue - foreach ($GroupItem in $Group) { - $CombinedEffectiveAccess = $CombinedEffectiveAccess -band $GroupItem.Permission - } - $GetPermissionParams.AccessMask = $CombinedEffectiveAccess - $GetPermissionParams.ObjectAceType = $Group[0].Guid - $OutputProperties.EffectiveAccess = GetPermissionString @GetPermissionParams - - if ($OutputProperties.EffectiveAccess -eq "None") { - return - } - - $ReturnObject = New-Object PSObject -Property $OutputProperties - $ReturnObject.pstypenames.Insert(0, $TypeName) - $ReturnObject - } - else { - $TypeName = $__EffectiveAccessListAllTypeName - - $LimitedBy = @() - $AccessAllowed = $true - $GetPermissionParams.ObjectAceType = $Group[0].Guid - $GetPermissionParams.ListEffectivePermissionMode = $true - $Group | Where-Object { $_ } | ForEach-Object { - $GroupItem = $_ - - $GetPermissionParams.AccessMask = $GroupItem.Permission - GetPermissionString @GetPermissionParams | - Add-Member -MemberType NoteProperty -Name LimitedBy -Value $GroupItem.LimitedBy -PassThru | - Add-Member -MemberType NoteProperty -Name AccessMask -Value $GroupItem.Permission -PassThru - } | Group-Object Permission | ForEach-Object { - $Allowed = $true - $LimitedBy = @() - foreach ($PermissionGroup in $_.Group) { - if (-not $PermissionGroup.Allowed) { - $Allowed = $false - $LimitedBy += $PermissionGroup.LimitedBy - } - } - - $OutputProperties.Allowed = $Allowed - $OutputProperties.Permission = $_.Name - $OutputProperties.LimitedBy = $LimitedBy -join ", " - - $ReturnObject = New-Object PSObject -Property $OutputProperties - $ReturnObject.pstypenames.Insert(0, $TypeName) - $ReturnObject - - } - } - - } - - } - catch { - Write-Error $_ - continue - } - finally { -Write-Verbose "Freeing effective access stuff" - [System.Runtime.InteropServices.Marshal]::FreeHGlobal($Reply.Error) - [System.Runtime.InteropServices.Marshal]::FreeHGlobal($Reply.GrantedAccessMask) - - $ObjectTypeListArray | Where-Object { $_ } | ForEach-Object { - [System.Runtime.InteropServices.Marshal]::FreeHGlobal($_.ObjectType) - } - - if ($Request.ObjectTypeList -ne [System.IntPtr]::Zero) { - [System.Runtime.InteropServices.Marshal]::FreeHGlobal($Request.ObjectTypeList) - } - - if ($hClientContext -ne [System.IntPtr]::Zero) { - [PowerShellAccessControl.PInvoke.authz]::AuthzFreeContext($hClientContext) | CheckExitCode -Action "Freeing AuthZ client context" - } - if ($hResourceManager -ne [System.IntPtr]::Zero) { - [PowerShellAccessControl.PInvoke.authz]::AuthzFreeResourceManager($hResourceManager) | CheckExitCode -Action "Freeing AuthZ resource manager" - } - } - } - } - } -} - -#.ExternalHelp PowerShellAccessControl.Help.xml -function Get-MandatoryIntegrityLabel { - - [CmdletBinding(DefaultParameterSetName='Path')] - param( - [Parameter(Mandatory=$true, ParameterSetName='InputObject', ValueFromPipeline=$true)] - $InputObject, - [Parameter(ParameterSetName='DirectPath', Position=0, ValueFromPipelineByPropertyName=$true)] - [Parameter(ParameterSetName='Path', Position=0, ValueFromPipelineByPropertyName=$true)] - [string[]] $Path = ".", - [Parameter(Mandatory=$true, ParameterSetName='LiteralPath', ValueFromPipelineByPropertyName=$true)] - [string[]] $LiteralPath, - [Parameter(ParameterSetName='DirectPath')] - [System.Security.AccessControl.ResourceType] $ObjectType - ) - - process { - foreach ($PathInfo in GetPathInformation @PSBoundParameters) { - - # See this link for background on what's about to happen: - # http://msdn.microsoft.com/en-us/library/windows/desktop/aa965848(v=vs.85).aspx - - # Call GetSecurityInfo, but only asking for Label information. This should give an SD that has a SACL with a special - # ACE (or an empty SACL if there is no MIL): - $SecInfoParams = @{ - ObjectType = $PathInfo.ObjectType - SecurityInformation = "Label" - ErrorAction = "Stop" - } - if ($PathInfo.Handle -ne $null) { - $SecInfoParams.Handle = $PathInfo.Handle - } - else { - $SecInfoParams.Path = $PathInfo.SdPath - } - - try { - $BinLabelInfo = GetSecurityInfo @SecInfoParams - } - catch { - Write-Error $_ - continue - } - - # This could go through the New-AdaptedSecurityDescriptor, but that's just going to add lots of extra work, and - # it wouldn't be able to view the SACL's ACE anyway (not from the .Audit property). For that reason, just make it - # a RawSecurityDescriptor object - $SD = New-Object System.Security.AccessControl.RawSecurityDescriptor (([byte[]] $BinLabelInfo), 0) - - # AceType of 17 is what holds the info we want: - $SD.SystemAcl | - where { [int] $_.AceType -eq 17 } | - ForEach-Object { - - $Data = $_.GetOpaque() - $AccessMask = [System.BitConverter]::ToInt32($Data, 0) - $Sid = New-Object System.Security.Principal.SecurityIdentifier ($Data, 4) - - $NewAceParams = @{ - Principal = $Sid - AccessMask = $AccessMask - AppliesTo = $_ | GetAppliesToMapping - OnlyApplyToThisContainer = $_ | GetAppliesToMapping -CheckForNoPropagateInherit - } - $Ace = New-AccessControlEntry @NewAceParams - - # There are a few things that still need fixing - $Ace | - Add-Member -MemberType NoteProperty -Name AceType -Force -Value IntegrityLevel -PassThru | - Add-Member -MemberType NoteProperty -Name IsInherited -Force -Value ($_.IsInherited) - - New-AdaptedAcl -Ace $Ace -AccessMaskEnum ([PowerShellAccessControl.NonAccessMaskEnums.SystemMandatoryLabelMask]) | - Add-Member -MemberType NoteProperty -Name DisplayName -Force -Value $PathInfo.DisplayName -PassThru | - Add-Member -MemberType NoteProperty -Name Path -Force -Value $PathInfo.Path -PassThru - - - } - - # What happens when a MIL doesn't exist? Return null, or return default (which would be Medium, but I don't know about flags) - } - } -} - -#.ExternalHelp PowerShellAccessControl.Help.xml -function Get-ADObjectAceGuid { - [CmdletBinding(DefaultParameterSetName="SearchAllByName")] - param( - [Parameter(ParameterSetName="SearchAllByGuid", Mandatory=$true)] - [guid] $Guid, - [Parameter(ParameterSetName="ExtendedRight")] - [switch] $ExtendedRight, - [Parameter(ParameterSetName="ValidatedWrite")] - [switch] $ValidatedWrite, - [Parameter(ParameterSetName="Property")] - [switch] $Property, - [Parameter(ParameterSetName="PropertySet")] - [switch] $PropertySet, - [Parameter(ParameterSetName="ClassObject")] - [switch] $ClassObject, - [Parameter(ParameterSetName="SearchAllByName")] - [Parameter(ParameterSetName="SearchAllByGuid")] - [ValidateSet("ExtendedRight", "ValidatedWrite", "Property", "PropertySet", "ClassObject")] - [string[]] $TypesToSearch - ) - - dynamicparam { - - # No dynamic param if Guid was supplied - if ($PSCmdlet.ParameterSetName -eq "SearchAllByGuid") { return } - - # This creates the 'Name' parameter. If none of the switches are provided, the function will - # search all of the different types - $ParamName = "Name" - $ParamAliases = @() - - # Create the dictionary that this scriptblock will return: - $DynParamDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary - $AttribColl = New-Object System.Collections.ObjectModel.Collection[System.Attribute] - - $ParamAttributes = New-Object System.Management.Automation.ParameterAttribute - $ParamAttributes.Mandatory = $true - $ParamAttributes.Position = 0 - $AttribColl.Add($ParamAttributes) - - # Not sure if I'm going to change param name and add aliases, so this will check each time - if ($ParamAliases) { - $ParamAliasAttribute = New-Object System.Management.Automation.AliasAttribute $ParamAliases - $AttribColl.Add($ParamAliasAttribute) - } - - $ParamSetName = $PSCmdlet.ParameterSetName - if ($ParamSetName -like "SearchAll*") { - # ValidateSet attribute isn't needed, so don't do anything extra - } - else { - # Searching AD for the different types of objects can be very expensive. For that reason, - # script scope variables hold the different ValidateSet objects. Here we check to - # see if the variable has been set for this type of object (depending on the switch). If - # it hasn't, this code block will populate that variable. Then the ValidateSet object is - # always added: - - - $ValidateSetVariableName = "__${ParamSetName}ValidateSet" - $ValidateSet = Get-Variable -Scope Script -Name $ValidateSetVariableName -ValueOnly -ErrorAction Stop - - if ($ValidateSet -eq $null) { - # Hasn't been populated, so populate it: - Write-Verbose "Getting list of values for '$ParamSetName' ValidateSet attribute..." - try { - $ValidateSet = New-Object System.Management.Automation.ValidateSetAttribute (ConvertGuidToName -Type $ParamSetName -ListAll | select -exp DisplayName) - Set-Variable -Scope Script -Name $ValidateSetVariableName -Value $ValidateSet - } - catch { - # Error looking up values - throw $_ - } - } - - $AttribColl.Add($ValidateSet) - } - - $DynamicParameter = New-Object System.Management.Automation.RuntimeDefinedParameter ( - $ParamName, - [string], - $AttribColl #[System.Collections.ObjectModel.Collection[System.Attribute]] $ParamAttributes - ) - $DynParamDictionary.Add($ParamName, $DynamicParameter) - - # Return the param dictionary - $DynParamDictionary - } - - process { - # Get the dynamic param. Just get the first one in case someone slipped more than one in somehow - $Name = $PSBoundParameters.Name | select -First 1 - - if ($PSCmdlet.ParameterSetName -like "SearchAll*") { - # We have to do some actual work. User didn't know (or didn't specify) - # what the type was. If they had (using one of the switches), the work - # would already be done. See the else block below. - - switch ($PSCmdlet.ParameterSetName) { - "SearchAllByName" { - # Replace * with .* (unless a backtick preceeds it, which is how the user can tell the function that the regex needs an actual asterisk there) - $NameRegex = $Name | ModifySearchRegex - - $FunctionName = "ConvertNameToGuid" - $FunctionParams = @{ - Name = $NameRegex - } - } - - "SearchAllByGuid" { - $FunctionName = "ConvertGuidToName" - $FunctionParams = @{ - Guid = $Guid - } - - # If empty GUID is supplied, simply exit w/o returing anything. Get-Ace will search - # for empty GUIDs if -ObjectAceType or -InheritedObjectAceType are supplied. Even thought - # the SB says to pass -EA SilentlyContinue to this function, errors seem to be caught if - # the function has to call Get-SD first (it works fine when an SD object is passed as the - # -InputObject - if ($Guid -eq [guid]::Empty) { return } - } - - default { - throw "Unknown parameter set" - } - } - # Since we don't know what the type is, search through them all: - $PossibleObjects = foreach ($Type in "ValidatedWrite", "ExtendedRight", "PropertySet", "Property", "ClassObject") { - if ($PSBoundParameters.ContainsKey("TypesToSearch") -and $TypesToSearch -notcontains $Type) { - continue - } - - & $FunctionName @FunctionParams -Type $Type -ErrorAction SilentlyContinue - } - - if ($PossibleObjects -eq $null) { - $Enumerator = $FunctionParams.GetEnumerator() | select -first 1 - Write-Error ("Unable to find any objects with {0} '{1}'" -f $Enumerator.Name, $Enumerator.Value) - return - } - else { - $PossibleObjects - } - - } - else { - # Because of the dynamic params, anything passed through $Name should - # be a valid attribute/class: - $Type = $PSCmdlet.ParameterSetName - ConvertNameToGuid -Name "^$Name$" -Type $Type - } - } -} diff --git a/Resources/PowerShellAccessControl/PowerShellAccessControl.types.ps1xml b/Resources/PowerShellAccessControl/PowerShellAccessControl.types.ps1xml deleted file mode 100644 index 3a578c6..0000000 --- a/Resources/PowerShellAccessControl/PowerShellAccessControl.types.ps1xml +++ /dev/null @@ -1,7 +0,0 @@ - - - PowerShellAccessControl.Types.AdaptedSecurityDescriptor - - - - \ No newline at end of file diff --git a/Resources/PowerShellAccessControl/PowerShellAccessControlAccessMaskEnumerations.ps1 b/Resources/PowerShellAccessControl/PowerShellAccessControlAccessMaskEnumerations.ps1 deleted file mode 100644 index f643ab4..0000000 --- a/Resources/PowerShellAccessControl/PowerShellAccessControlAccessMaskEnumerations.ps1 +++ /dev/null @@ -1,221 +0,0 @@ -# See after Add-Type for generic rights mapping -Add-Type @" -using System; -namespace PowerShellAccessControl { - - // Share enumeration from: http://blogs.msdn.com/b/helloworld/archive/2008/06/10/common-accessmask-value-when-configuring-share-permission-programmatically.aspx - [Flags] - public enum LogicalShareRights { - FullControl = 0x001f01ff, - Read = 0x001200a9, - Change = 0x001301bf - } - - // Enum info from here: http://msdn.microsoft.com/en-us/library/cc244650.aspx - // Generic mappings (used in a future release): - // - Read: Server object: ReadServer; Printer object: ReadPrinter; job object: ReadJob - // - Write: Server object: WriteServer; Printer object: WritePrinter; job object: WriteJob - // - Execute: look at previous two, and you get the picture :) - // - All: Same as above, but using 'AllAccess' - [Flags] - public enum PrinterRights { - AdministerJob = 0x00010, - ReadSpoolFile = 0x00020, - ExecuteJob = ReadPermissions | AdministerJob, - ReadJob = ReadPermissions | ReadSpoolFile, - WriteJob = ReadPermissions | AdministerJob, - JobAllAccess = Synchronize | RightsRequired | ReadSpoolFile, - UsePrinter = 0x00008, - AdministerPrinter = 0x00004, - ManagePrinterLimited = 0x00040, // PrinterAllAccess - ExecutePrinter = ReadPermissions | UsePrinter, - Print = ExecutePrinter, - ReadPrinter = ExecutePrinter, - WritePrinter = ExecutePrinter, - ManagePrinter = TakeOwnership | ChangePermissions | ReadPermissions | StandardDelete | AdministerPrinter | UsePrinter, - PrinterAllAccess = ManagePrinter, - //ManageDocuments = 0xf0030, - AdministerServer = 0x000001, - EnumerateServer = 0x000002, - ServerAllAccess = TakeOwnership | ChangePermissions | ReadPermissions | StandardDelete | AdministerServer | EnumerateServer, - ExecuteServer = ReadPermissions | EnumerateServer, - ReadServer = ExecuteServer, - WriteServer = ExecuteServer | AdministerServer, - SpecificFullControl = 0xffff, - StandardDelete = 0x010000, // Standard rights below - ReadPermissions = 0x020000, - ChangePermissions = 0x040000, - TakeOwnership = 0x080000, - RightsRequired = 0x0d0000, - Synchronize = 0x100000 - } - - [Flags] - public enum WmiNamespaceRights { - EnableAccount = 0x000001, - ExecuteMethods = 0x000002, - FullWrite = 0x000004, - PartialWrite = 0x000008, - ProviderWrite = 0x000010, - RemoteEnable = 0x000020, - ReadSecurity = 0x020000, - EditSecurity = 0x040000 - } - - // Just Generic rights (see below) - [Flags] - public enum WsManAccessRights { - Full = 0x10000000, - Read = -2147483648, // 0x80000000 - Write = 0x40000000, - Execute = 0x20000000 - } - - [Flags] - public enum ServiceAccessRights { - QueryConfig = 0x0001, - ChangeConfig = 0x0002, - QueryStatus = 0x0004, - EnumerateDependents = 0x0008, - Start = 0x0010, - Stop = 0x0020, - PauseResume = 0x0040, - Interrogate = 0x0080, - UserDefinedControl = 0x0100, - Delete = 0x010000, // StandardDelete - ReadPermissions = 0x020000, // StandardReadPermissions/StandardWrite - Write = ReadPermissions | ChangeConfig, - Read = ReadPermissions | QueryConfig | QueryStatus | Interrogate | EnumerateDependents, - ChangePermissions = 0x040000, // StandardChangePermissions - ChangeOwner = 0x080000, // StandardChangeOwner -// Execute = ReadPermissions | Start | Stop | PauseResume | UserDefinedControl, - FullControl = QueryConfig | ChangeConfig | QueryStatus | EnumerateDependents | Start | Stop | PauseResume | Interrogate | UserDefinedControl | Delete | ReadPermissions | ChangePermissions | ChangeOwner - } - - // http://msdn.microsoft.com/en-us/library/windows/desktop/aa446632%28v=vs.85%29.aspx - [Flags] - public enum GenericAceRights { - GenericAll = 0x10000000, - GenericExecute = 0x20000000, - GenericWrite = 0x40000000, - GenericRead = -2147483648 // 0x80000000 - } - - // http://msdn.microsoft.com/en-us/library/windows/desktop/aa379607%28v=vs.85%29.aspx - [Flags] - public enum StandardAccessRights { - StandardDelete = 0x010000, - StandardReadPermissions = 0x020000, - StandardSynchronize = 0x100000, - StandardChangePermissions = 0x040000, - StandardChangeOwner = 0x080000, - StandardAll = 0x1f0000, - //StandardExecute = 0x020000, - //StandardRead = 0x020000, - //StandardWrite = 0x020000 - StandardRequired = 0x0d0000, - } - - [Flags] - public enum ProcessAccessRights { - Terminate = 0x000001, - CreateThread = 0x000002, - SetSessionId = 0x000004, - MemoryOperations = 0x000008, - ReadMemory = 0x000010, - WriteMemory = 0x000020, - DuplicateHandle = 0x000040, - CreateProcess = 0x000080, - SetQuota = 0x000100, - SetInformation = 0x000200, - QueryInformation = 0x000400, - SuspendResume = 0x000800, - QueryLimitedInfo = 0x001000, // Since this bit is new to Vista+, new AllAccess was created - AllAccessLegacy = 0x1f0fff, - AllAccess = 0x1fffff, // Top three bits of object specific rights appear to be unused - Delete = 0x010000, - ReadPermissions = 0x020000, - ChangePermissions= 0x040000, - TakeOwnership = 0x080000, - Synchronize = 0x100000 - } - - [Flags] - // Not using [System.DirectoryServices.ActiveDirectoryRights] b/c generic rights are mixed in. The way New-AdaptedAcl - // handles generic rights mapping doesn't work if the enum contains the generic rights enum. - public enum ActiveDirectoryRights { - CreateChild = 0x000001, - DeleteChild = 0x000002, - ListChildren = 0x000004, - Self = 0x000008, - ReadProperty = 0x000010, - WriteProperty = 0x000020, - DeleteSubtree = 0x000040, - ListContents = 0x000080, - ExtendedRight = 0x000100, - Delete = 0x010000, - ReadPermissions = 0x020000, - ChangePermissions = 0x040000, - TakeOwnership = 0x080000, - Synchronize = 0x100000, - //Read = ListChildren | ReadProperty | ListObject | ReadPermissions, - //Write = Self | WriteProperty | ReadPermissions, - //Execute = ListChildren | ReadPermissions, - FullControl = CreateChild | DeleteChild | ListChildren | Self | ReadProperty | WriteProperty | DeleteSubtree | ListContents | ExtendedRight | Delete | ReadPermissions | ChangePermissions | TakeOwnership - } - - [Flags] - public enum AppliesTo { - Object = 1, - ChildContainers = 2, - ChildObjects = 4 - } - - namespace NonAccessMaskEnums { - [Flags] - public enum SystemMandatoryLabelMask { - NoWriteUp = 1, - NoReadUp = 2, - NoExecuteUp = 4 - } - } -} -"@ - -$FileSystemGenericMapping = New-Object PowerShellAccessControl.PInvoke.GenericMapping -$FileSystemGenericMapping.GenericRead = [System.Security.AccessControl.FileSystemRights] "Read, Synchronize" -$FileSystemGenericMapping.GenericWrite = [System.Security.AccessControl.FileSystemRights] "Write, ReadPermissions, Synchronize" -$FileSystemGenericMapping.GenericExecute = [System.Security.AccessControl.FileSystemRights] "ExecuteFile, ReadAttributes, ReadPermissions, Synchronize" -$FileSystemGenericMapping.GenericAll = [System.Security.AccessControl.FileSystemRights] "FullControl" - -$RegistryGenericMapping = New-Object PowerShellAccessControl.PInvoke.GenericMapping -$RegistryGenericMapping.GenericRead = [System.Security.AccessControl.RegistryRights] "ReadKey" -$RegistryGenericMapping.GenericWrite = [System.Security.AccessControl.RegistryRights] "WriteKey" -$RegistryGenericMapping.GenericExecute = [System.Security.AccessControl.RegistryRights] "CreateLink, ReadKey" -$RegistryGenericMapping.GenericAll = [System.Security.AccessControl.RegistryRights] "FullControl" - -$PrinterGenericMapping = New-Object PowerShellAccessControl.PInvoke.GenericMapping -$PrinterGenericMapping.GenericRead = [PowerShellAccessControl.PrinterRights] "ExecutePrinter" -$PrinterGenericMapping.GenericWrite = [PowerShellAccessControl.PrinterRights] "ExecutePrinter" -$PrinterGenericMapping.GenericExecute = [PowerShellAccessControl.PrinterRights] "ExecutePrinter" -$PrinterGenericMapping.GenericAll = [PowerShellAccessControl.PrinterRights] "PrinterAllAccess" - -$AdGenericMapping = New-Object PowerShellAccessControl.PInvoke.GenericMapping -$AdGenericMapping.GenericRead = [PowerShellAccessControl.ActiveDirectoryRights] "ListChildren, ReadProperty, ListContents, ReadPermissions" -$AdGenericMapping.GenericWrite = [PowerShellAccessControl.ActiveDirectoryRights] "Self, WriteProperty, ReadPermissions" -$AdGenericMapping.GenericExecute = [PowerShellAccessControl.ActiveDirectoryRights] "ListChildren, ReadPermissions" -$AdGenericMapping.GenericAll = [PowerShellAccessControl.ActiveDirectoryRights] "CreateChild, DeleteChild, ListChildren, Self, ReadProperty, WriteProperty, DeleteSubtree, ListContents, ExtendedRight, Delete, ReadPermissions, ChangePermissions, TakeOwnership" - -$WsManMapping = New-Object PowerShellAccessControl.PInvoke.GenericMapping -$WsManMapping.GenericRead = [PowerShellAccessControl.WsManAccessRights]::Read -$WsManMapping.GenericWrite = [PowerShellAccessControl.WsManAccessRights]::Write -$WsManMapping.GenericExecute = [PowerShellAccessControl.WsManAccessRights]::Execute -$WsManMapping.GenericAll = [PowerShellAccessControl.WsManAccessRights]::Full - -$__GenericRightsMapping = @{ - [PowerShellAccessControl.PrinterRights] = $PrinterGenericMapping - [System.Security.AccessControl.RegistryRights] = $RegistryGenericMapping - [System.Security.AccessControl.FileSystemRights] = $FileSystemGenericMapping - [PowerShellAccessControl.ActiveDirectoryRights] = $AdGenericMapping - [PowerShellAccessControl.WsManAccessRights] = $WsManMapping -} \ No newline at end of file diff --git a/Resources/PowerShellAccessControl/PowerShellAccessControlHelperFunctions.ps1 b/Resources/PowerShellAccessControl/PowerShellAccessControlHelperFunctions.ps1 deleted file mode 100644 index def1a40..0000000 --- a/Resources/PowerShellAccessControl/PowerShellAccessControlHelperFunctions.ps1 +++ /dev/null @@ -1,4095 +0,0 @@ -function Get-CimInstanceFromPath { -<# -.SYNOPSIS -Converts a WMI path into a CimInstance object. -.DESCRIPTION -Get-CimInstanceFromPath takes an absolute WMI path and creates a WMI query that -Get-CimInstance takes as an argument. If everything works properly, a CimInstance -object will be returned. -.EXAMPLE -$Bios = Get-WmiObject Win32_BIOS; Get-CimInstanceFromPath -Path $Bios.__PATH -.EXAMPLE -Get-WmiObject Win32_BIOS | Get-CimInstanceFromPath -.NOTES -The function currently only works with absolute paths. It can easily be modified -to work with relative paths, too. -#> -<# -This function allows CIM objects to be represented as a string (like the WMI __PATH property). For example, -if you pass a CIM object that the module can get a security descriptor for (like a __SystemSecurity instance), -the SD's path property will include this string so that an instance of the CIM object can be obtained again. - -WMI cmdlets have this functionality built-in: -$Computer = gwmi Win32_ComputerSystem -[wmi] $Computer.__PATH # Get WMI instance from path - -This function was more usefule in v1.x of this module before GetNamedSecurityInfo() and GetSecurityInfo() -windows APIs were used. -#> - - [CmdletBinding()] - param( - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ValueFromPipeline=$true)] - [Alias('__PATH')] - # WMI path (Path must be absolute path, not relative path). See __PATH - # property on an object returned from Get-WmiObject - [string] $Path - ) - - process { - if ($Path -match "^\\\\(?[^\\]*)\\(?[^:]*):(?[^=\.]*)(?\.|(=@))(?.*)?$") { - $Query = "SELECT * FROM {0}" -f $matches.classname - - switch ($matches.separator) { - - "." { - # Key/value pairs are in string, so add a WHERE clause - $Query += " WHERE {0}" -f [string]::Join(" AND ", $matches.keyvaluepairs -split ",") - } - } - - $GcimParams = @{ - ComputerName = $matches.computername - Namespace = $matches.namespace - Query = $Query - ErrorAction = "Stop" - } - - } - else { - throw "Path not in expected format!" - } - - Get-CimInstance @GcimParams - } -} - -function Get-CimPathFromInstance { -<# -The opposite of the Get-CimInstanceFromPath. This is how a __PATH property can be computed for a CIM instance. - -Like the other function, this was more useful in 1.x versions of the module. It is still used in the GetWmiObjectInfo -helper function and the Get-Win32SecurityDescriptor exposed function. -#> - [CmdletBinding()] - param( - [Parameter(Mandatory=$true,ValueFromPipeline=$true)] - [ciminstance] $InputObject - ) - - process { - $Keys = $InputObject.CimClass.CimClassProperties | - Where-Object { $_.Qualifiers.Name -contains "Key" } | - Select-Object Name, CimType | - Sort-Object Name - - $KeyValuePairs = $Keys | ForEach-Object { - - $KeyName = $_.Name - switch -regex ($_.CimType) { - - "Boolean|.Int\d+" { - # No quotes surrounding value: - $Value = $InputObject.$KeyName - } - - "DateTime" { - # Conver to WMI datetime - $Value = '"{0}"' -f [System.Management.ManagementDateTimeConverter]::ToDmtfDateTime($InputObject.$KeyName) - } - - "Reference" { - throw "CimInstance contains a key with type 'Reference'. This isn't currenlty supported (but can be added later)" - } - - default { - # Treat it like a string and cross your fingers: - $Value = '"{0}"' -f ($InputObject.$KeyName -replace "`"", "\`"") - } - } - - "{0}={1}" -f $KeyName, $Value - } - - if ($KeyValuePairs) { - $KeyValuePairsString = ".{0}" -f ($KeyValuePairs -join ",") - } - else { - # This is how WMI seems to handle paths with no keys - $KeyValuePairsString = "=@" - } - - "\\{0}\{1}:{2}{3}" -f $InputObject.CimSystemProperties.ServerName, - ($InputObject.CimSystemProperties.Namespace -replace "/","\"), - $InputObject.CimSystemProperties.ClassName, - $KeyValuePairsString - - - } -} - -function Convert-AclToString { -<# - Converts an ACL into a string that has been formatted with Format-Table. The AccessToString and - AuditToString properties on the PSObject returned from Get-SecurityDescriptor use this function. -#> - - [CmdletBinding()] - param( - [Parameter(ValueFromPipeline=$true)] - $Ace, - [int] $MaxAces = 20, - [PowerShellAccessControl.AppliesTo] $DefaultAppliesTo - ) - - begin { - - $TableProperties = @( - @{ Label = "Type" - Expression = { - $CurrentAce = $_ - - if ($_.IsInherited) { $ExtraChar = ""} - else { $ExtraChar = "*" } - - $ReturnString = switch ($_.AceType.ToString()) { - "AccessAllowed" { "Allow$ExtraChar" } - "AccessDenied" { "Deny$ExtraChar" } - "SystemAudit" { - $AuditSuccess = $AuditFailure = " " - if ($CurrentAce.AuditFlags -band [System.Security.AccessControl.AuditFlags]::Success) { - $AuditSuccess = "S" - } - if ($CurrentAce.AuditFlags -band [System.Security.AccessControl.AuditFlags]::Failure) { - $AuditFailure = "F" - } - - "Audit$ExtraChar {0}{1}" -f $AuditSuccess, $AuditFailure - } - default { $_ } - - } - - $ReturnString -join " " - } - Width = 9 - } - @{ Label = "IdentityReference" - Expression = { - $_.Principal -replace "($env:COMPUTERNAME|BUILTIN|NT AUTHORITY)\\", "" - } - Width = 20 - } - @{ Label = "Rights" - Expression = { - $Display = $_.AccessMaskDisplay -replace "\s\(.*\)$" - if (($PSBoundParameters.ContainsKey("DefaultAppliesTo") -and ($_.AppliesTo.value__ -ne $DefaultAppliesTo.value__)) -or ($_.OnlyApplyToThisContainer)) { - #$Display += " (Special)" - $Display = "Special" - } - $Display - } - Width = 20 - } - ) - - # If the following properties are the same, the ACEs will be grouped together - $PropertiesToGroupBy = @( - "AceType" - "SecurityIdentifier" - "StringPermissions" # Modified form of the AccessMaskDisplay property, which is a string representation of the AccessMask (not grouping on that b/c GenericRights would mean that the AccessMasks might not match, while the effecitve rights do) - "IsInherited" - "OnlyApplyToThisContainer" - "AuditFlags" # Doesn't affect grouping access rights; this is a CommonAce property - "ObjectAceType" # Since it will be null if this is an ACE that doesn't contain this property, shouldn't affect grouping of normal non-object ACEs - "InheritedObjectAceType" # Since it will be null if this is an ACE that doesn't contain this property, shouldn't affect grouping of normal non-object ACEs - ) - - $CollectedAces = @() - $ExtraMessage = $null - } - - process { - - $CollectedAces += $Ace - - if ($CollectedAces.Count -ge $MaxAces) { - $ExtraMessage = "`n<...>" - break - } - - } - - end { - $Output = $CollectedAces | Format-Table -Property $TableProperties -HideTableHeaders -Wrap | Out-String | % { $_.Trim() } - $Output = "{0}{1}" -f $Output, $ExtraMessage - - if (-not $Output) { - "" - } - else { - $Output - } - } -} - -function GetAppliesToMapping { -<# - ACE inheritance and propagation are handled by the InheritanceFlags and PropagationFlags properties - on an ACE. Based on the flags enabled, a GUI ACL editor will show you two separate pieces of information - about an ACE: - 1. Whether or not it applies to itself, child containers, and/or child objects - 2. Whether or not it applies only to direct children (one level deep) or all descendants (infinite - depth) - - #1 is handled by both flags enumerations and #2 is only handled by PropagationFlags. This function - provides a way for determining #1 and #2 if you provide the flags enumerations, and it also provides - a way to get the proper flags enumerations for #1 if you provide string representations of where you - would like the ACE to apply. -#> - - [CmdletBinding(DefaultParameterSetName='FromAppliesTo')] - param( - [Parameter(Mandatory=$true, ParameterSetName="FromAppliesTo", Position=0)] - [PowerShellAccessControl.AppliesTo] $AppliesTo, - [Parameter(Mandatory=$true, ParameterSetname="ToAppliesTo", ValueFromPipelineByPropertyName=$true)] - [System.Security.AccessControl.InheritanceFlags] $InheritanceFlags, - [Parameter(Mandatory=$true, ParameterSetname="ToAppliesTo", ValueFromPipelineByPropertyName=$true)] - [System.Security.AccessControl.PropagationFlags] $PropagationFlags, - [Parameter(ParameterSetname="ToAppliesTo")] - [switch] $CheckForNoPropagateInherit, - [Parameter(Mandatory=$true, ParameterSetName="ADFromAppliesTo")] - [PowerShellAccessControl.AppliesTo] $ADAppliesTo, - [Parameter(ParameterSetName="ADFromAppliesTo")] - [switch] $OnlyApplyToThisADContainer = $false - - ) - - begin { - $Format = "{0},{1}" - $AppliesToMapping = @{ # Numeric values from [PowershellAccessControl.AppliesTo] flags enum - #ThisObjectOnly - 1 = $Format -f [System.Security.AccessControl.InheritanceFlags]::None.value__, [System.Security.AccessControl.PropagationFlags]::None.value__ - #ChildContainersOnly - 2 = $Format -f [System.Security.AccessControl.InheritanceFlags]::ContainerInherit.value__, [System.Security.AccessControl.PropagationFlags]::InheritOnly.value__ - #ThisObjectAndChildContainers - 3 = $Format -f [System.Security.AccessControl.InheritanceFlags]::ContainerInherit.value__, [System.Security.AccessControl.PropagationFlags]::None.value__ - #ChildObjectsOnly - 4 = $Format -f [System.Security.AccessControl.InheritanceFlags]::ObjectInherit.value__, [System.Security.AccessControl.PropagationFlags]::InheritOnly.value__ - #ThisObjectAndChildObjects - 5 = $Format -f [System.Security.AccessControl.InheritanceFlags]::ObjectInherit.value__, [System.Security.AccessControl.PropagationFlags]::None.value__ - #ChildContainersAndChildObjectsOnly - 6 = $Format -f ([System.Security.AccessControl.InheritanceFlags] "ContainerInherit, ObjectInherit").value__, [System.Security.AccessControl.PropagationFlags]::InheritOnly.value__ - #ThisObjectChildContainersAndChildObjects - 7 = $Format -f ([System.Security.AccessControl.InheritanceFlags] "ContainerInherit, ObjectInherit").value__, [System.Security.AccessControl.PropagationFlags]::None.value__ - } - } - - process { - switch ($PSCmdlet.ParameterSetName) { - "FromAppliesTo" { - $MappingString = $AppliesToMapping[$AppliesTo.value__] - if ($MappingString -eq $null) { - Write-Error ("Unable to map AppliesTo value ({0} to inheritance and propagation flags!" -f $AppliesTo) - return - } - $Mappings = $MappingString -split "," - - New-Object PSObject -Property @{ - InheritanceFlags = [System.Security.AccessControl.InheritanceFlags] $Mappings[0] - PropagationFlags = [System.Security.AccessControl.PropagationFlags] $Mappings[1] - } - } - - "ADFromAppliesTo" { - $Format = "{0}, {1}" - $ADAppliesToMapping = @{ # Numeric values from System.DirectoryServices.ActiveDirectorySecurityInheritance - # None is the same as [AppliesTo]::Object (doesn't matter if only applies here is set) - ($Format -f [PowerShellAccessControl.AppliesTo]::Object.value__, $false) = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::None - ($Format -f [PowerShellAccessControl.AppliesTo]::Object.value__, $true) = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::None - # All is the same as [AppliesTo]::Object, ChildContainers and applies to only this container false - ($Format -f ([PowerShellAccessControl.AppliesTo] "Object, ChildContainers").value__, $false) = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::All - # SelfAndChildren is the same as [AppliesTo]::Object, ChildContainers and applies to only this container is true - ($Format -f ([PowerShellAccessControl.AppliesTo] "Object, ChildContainers").value__, $true) = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::SelfAndChildren - # Descendats is the same as [AppliesTo]::ChildContainers and applies to only this container false - ($Format -f [PowerShellAccessControl.AppliesTo]::ChildContainers.value__, $false) = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::Descendents - # Children is the same as [AppliesTo]::ChildContainers and applies to only this container true - ($Format -f [PowerShellAccessControl.AppliesTo]::ChildContainers.value__, $true) = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::Children - } - - # Get numeric form of AppliesTo (get rid of ChildObjects if it is present) - $AppliesToInt = $ADAppliesTo.value__ -band ([int32]::MaxValue -bxor [PowerShellAccessControl.AppliesTo]::ChildObjects) - - $AdSecurityInheritance = $ADAppliesToMapping[($Format -f $AppliesToInt, $OnlyApplyToThisADContainer)] - - if ($AdSecurityInheritance -eq $null) { - Write-Error ("Unable to convert AppliesTo ($ADAppliesTo) and OnlyApplyToThisContainer ($OnlyApplyToThisADContainer) to ActiveDirectorySecurityInheritance") - return - } - $AdSecurityInheritance - } - - "ToAppliesTo" { - if ($CheckForNoPropagateInherit) { - $PropagationFlags = $PropagationFlags.value__ - - # NoPropagateInherit doesn't deal with AppliesTo, so make sure that flags isn't active - if ($PropagationFlags -band [System.Security.AccessControl.PropagationFlags]::NoPropagateInherit) { - $true - } - else { - $false - } - - } - else { - # NoPropagateInherit doesn't deal with AppliesTo, so make sure that flag isn't active - if ($PropagationFlags -band [System.Security.AccessControl.PropagationFlags]::NoPropagateInherit) { - [System.Security.AccessControl.PropagationFlags] $PropagationFlags = $PropagationFlags -bxor [System.Security.AccessControl.PropagationFlags]::NoPropagateInherit - } - $MappingString = $Format -f $InheritanceFlags.value__, $PropagationFlags.value__ - - $FlagsValue = $AppliesToMapping.Keys | where { $AppliesToMapping.$_ -eq $MappingString } - [PowerShellAccessControl.AppliesTo] $FlagsValue - } - } - } - } - -} - -function ConvertToSpecificAce { -<# -This function will take a CommonAce or ObjectAce and convert it into a .NET ACE that can be used -with security descriptors for Files, Folders, Registry keys, and AD objects. At some point, this -will probably be merged with ConvertToCommonAce to have a single function that looks at any type -of ACE coming in, and converts it to the right type based on the $AclType. - -This function allows Add-AccessControlEntry and Remove-AccessControlEntry to work with SDs from -the native Get-Acl cmdlet. -#> - - [CmdletBinding()] - param( - [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)] - $Rules, - [Parameter(Mandatory=$true)] - # The type of the ACL that this ACE will belong to. - [type] $AclType - ) - - begin { - # Figure out what the final type of the rule should be. This depends on - # the $AclType, and (if the ACL type is a CommonSecurityDescriptor), the - # ACE itself - - if ($AclType.FullName -match "^(System\.Security\.AccessControl\.|System\.DirectoryServices\.)(\w+?)Security$") { - # If its a File/DirectorySecurity create a FileSystemAccessRule (or Audit); otherwise, match can be used - # as found (Registry or ActiveDirectory are all that I know of that will match this and work with New-Ace). - $AclRuleKind = "{0}{1}{{0}}Rule" -f $Matches[1], ($Matches[2] -replace "^File|^Directory", "FileSystem") - $AccessMaskParamName = $Matches[2] -replace "^Directory", "Folder" - - # This will leave a string with a {0} where Access or Audit will go later - } - elseif ($AclType.FullName -eq "System.Security.AccessControl.CommonSecurityDescriptor") { -# This isn't suppported until a future release: -throw ("{0} ACLs aren't supported" -f $AclType.FullName) - # Final rule will need to either be a CommonAce or an ObjectAce (rules aren't different - # b/w Access and Audit rules) - - # ObjectAce if .ObjectAceFlags exists and has flags other than 'None' - # This is a design decision that may change. For non-AD ACEs, this is easy: .ObjectAceFlags - # won't exist, so they will be converted to CommonAce objects (if they're not already). For - # AD ACEs, though, either type is fine. ActiveDirectorySecurity objects always have .ObjectAceFlags - # properties, even if the property is set to 'None'. This function would take one of those and - # only output an ObjectAce if an ObjectAceType or InheritedObjectAceType were set. - - # Since more than one ACE can come through at once, this check is performed in the foreach() - # section in the process block. - } - else { - throw "Unknown ACL type ($($AclType.FullName))" - } - } - - process { - - foreach ($Rule in $Rules) { - # See note in begin block for an explanation of this check: - if ($AclType.Name -eq "CommonSecurityDescriptor") { - if ($Rule.ObjectAceFlags -and $Rule.ObjectAceFlags -ne "None") { - $AclRuleKind = "System.Security.AccessControl.ObjectAce" - } - else { - $AclRuleKind = "System.Security.AccessControl.CommonAce" - } - } - - if ($Rule.AuditFlags -and $Rule.AuditFlags -ne [System.Security.AccessControl.AuditFlags]::None) { - # This must be an audit rule - $AuditOrAccess = "Audit" - } - else { - # This must be an access rule - $AuditOrAccess = "Access" - } - $CurrentRuleKind = $AclRuleKind -f $AuditOrAccess - - - # Check to see if it's already the right type of rule - if ($Rule.GetType().FullName -eq $CurrentRuleKind) { - Write-Debug ("{0}: Rule already $CurrentRuleKind; no need to convert" -f $MyInvocation.InvocationName) - $Rule - continue - } - - Write-Debug ("{0}: Rule is currently {1}; needs to be converted to {2}" -f $MyInvocation.InvocationName, $Rule.GetType().FullName, $CurrentRuleKind) - - # Make sure this is a known AceType (also, strip away 'Object' if it is at the end - # of the type) - if ($Rule.AceType -notmatch "^(\w+?)(Object)?$") { - throw "Unknown ACE type ($($Rule.AceType))" - } - - $CurrentAceType = $Matches[1] - $NewAceParams = @{ - AceType = $CurrentAceType - Principal = $Rule.SecurityIdentifier - $AccessMaskParamName = $Rule.AccessMask - AppliesTo = $Rule | GetAppliesToMapping - OnlyApplyToThisContainer = $Rule | GetAppliesToMapping -CheckForNoPropagateInherit - } - - if ($Rule.ObjectAceType) { - $NewAceParams.ObjectAceType = $Rule.ObjectAceType - } - - if ($Rule.InheritedObjectAceType) { - $NewAceParams.InheritedObjectAceType = $Rule.InheritedObjectAceType - } - - if ($AuditOrAccess -eq "Audit") { - # Convert flags to string, split on comma, trim trailing or leading spaces, and - # create a boolean value to simulate [switch] statement for splatting: - $Rule.AuditFlags.ToString() -split "," | ForEach-Object { - $NewAceParams.$("Audit{0}" -f $_.Trim()) = $true - } - } - - New-AccessControlEntry @NewAceParams -ErrorAction Stop - } - } -} - -function ConvertToCommonAce { -<# -When dealing with the underlying CommonSecurityDescriptor object, ACEs need to be -CommonAce or ObjectAce types. This function takes lots of different types of ACEs -and converts them to ACEs that can be used by the CommonSecurityDescripor objects. - -This allows the module to work with file system rules, registry rules, Win32_ACE rules, -etc. -#> - [CmdletBinding()] - param( - [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)] - [AllowNull()] - [object[]] $Rules, # Allow any object to come through since we can accept different ACE types - # By default, this will create an ACE that was not inherited, even if an inherited ACE is - # passed to it. This switch will keep that (might actually flip the behavior at some point) - # - # One more thing: this won't do anything for a file or registry ACE, only an ACE from a - # Win32SD or from an ACE in a RawAcl object - [switch] $KeepInheritedFlag - ) - - process { - foreach ($Rule in $Rules) { - if ($Rule -eq $null) { continue } # PSv2 iterates once if $Rules is null - - # We work with System.Security.AccessControl.CommonAce objects, so make sure whatever came in - # is one of those, or can be converted to one: - Write-Debug "$($MyInvocation.MyCommand): Type of rule is '$($Rule.GetType().FullName)'" - switch ($Rule.GetType().FullName) { - - { $Rule.pstypenames -contains $__AdaptedAceTypeName } { - - $IsRuleInherited = $Rule.IsInherited - - # This is an ace created by the module; anything with this typename should be able to be - # piped directly to New-AccessControlEntry - # Note: Valid types should be CommonAce or ObjectAce - - # Make the rule: - Write-Debug "$($MyInvocation.MyCommand): Rule is adapted type; running original back through New-AccessControlEntry" - $Rule = $Rule | New-AccessControlEntry - break - } - - { "System.Security.AccessControl.CommonAce", "System.Security.AccessControl.ObjectAce" -contains $_ } { - # Get a copy of the rule (we don't want to touch the original object) - Write-Debug "$($MyInvocation.MyCommand): No conversion necessary" - $Rule = $Rule.Copy() - $IsRuleInherited = [bool] ($Rule.AceFlags -band [System.Security.AccessControl.AceFlags]::Inherited) - break - } - - { $_ -eq "System.Security.AccessControl.FileSystemAccessRule" -or - $_ -eq "System.Security.AccessControl.RegistryAccessRule" -or - $_ -eq "System.DirectoryServices.ActiveDirectoryAccessRule" } { - - # File system access rule or registry access rule - - $IsRuleInherited = $Rule.IsInherited - - if ($Rule.AccessControlType -eq [System.Security.AccessControl.AccessControlType]::Allow) { - $AceQualifier = [System.Security.AccessControl.AceQualifier]::AccessAllowed - } - else { - $AceQualifier = [System.Security.AccessControl.AceQualifier]::AccessDenied - } - - $Params = @{ - AceType = $AceQualifier - Principal = $Rule.IdentityReference - AppliesTo = $Rule | GetAppliesToMapping - OnlyApplyToThisContainer = $Rule | GetAppliesToMapping -CheckForNoPropagateInherit - GenericAce = $true - } - - if ($_ -eq "System.Security.AccessControl.FileSystemAccessRule") { - $Params.FileRights = $Rule.FileSystemRights - } - elseif ($_ -eq "System.Security.AccessControl.RegistryAccessRule") { - $Params.RegistryRights = $Rule.RegistryRights - } - else { - # AD access rule - $Params.ActiveDirectoryRights = [int] $Rule.ActiveDirectoryRights - $Params.ObjectAceType = $Rule.ObjectType - $Params.InheritedObjectAceType = $Rule.InheritedObjectType - } - - # Make the rule: - Write-Debug "$($MyInvocation.MyCommand): Calling New-AccessControlEntry to create CommonAce from access rule" - $Rule = New-AccessControlEntry @Params - break - } - - { $_ -eq "System.Security.AccessControl.FileSystemAuditRule" -or - $_ -eq "System.Security.AccessControl.RegistryAuditRule" -or - $_ -eq "System.DirectoryServices.ActiveDirectoryAuditRule" } { - - # File system or registry audit - - $IsRuleInherited = $Rule.IsInherited - - $Params = @{ - Principal = $Rule.IdentityReference - AppliesTo = $Rule | GetAppliesToMapping - OnlyApplyToThisContainer = $Rule | GetAppliesToMapping -CheckForNoPropagateInherit - GenericAce = $true - AceType = [System.Security.AccessControl.AceQualifier]::SystemAudit - AuditSuccess = [bool] ($Rule.AuditFlags -band [System.Security.AccessControl.AuditFlags]::Success) - AuditFailure = [bool] ($Rule.AuditFlags -band [System.Security.AccessControl.AuditFlags]::Failure) - } - - if ($_ -eq "System.Security.AccessControl.FileSystemAuditRule") { - $Params.FileSystemRights = $Rule.FileSystemRights - } - elseif ($_ -eq "System.Security.AccessControl.RegistryAuditRule") { - $Params.RegistryRights = $Rule.RegistryRights - } - else { - # AD audit rule - $Params.ActiveDirectoryRights = [int] $Rule.ActiveDirectoryRights - $Params.ObjectAceType = $Rule.ObjectType - $Params.InheritedObjectAceType = $Rule.InheritedObjectType - } - - # Make the rule: - Write-Debug "$($MyInvocation.MyCommand): Calling New-AccessControlEntry to create CommonAce from audit rule" - $Rule = New-AccessControlEntry @Params - break - } - - { ($_ -eq "System.Management.ManagementBaseObject" -and - ($Rule.__CLASS -eq "Win32_ACE") -or ($Rule.__CLASS -eq "__ACE")) -or - ($_ -eq "Microsoft.Management.Infrastructure.CimInstance" -and - ($Rule.CimClass.CimClassName -eq "Win32_ACE") -or ($Rule.CimClass.CimClassName -eq "__ACE")) } { - - $IsRuleInherited = [bool] ($Rule.AceFlags -band [System.Security.AccessControl.AceFlags]::Inherited) - - # Long and scary looking condition, but it just means do the - # following if it's a WMI object of the Win32_ACE class - - $Principal = ([System.Security.Principal.SecurityIdentifier] $Rule.Trustee.SIDString) - - if ($Rule.AccessMask.GetType().FullName -eq "System.UInt32") { - # I've seen file access rights with UInts; convert them to signed ints: - $AccessMask = [System.BitConverter]::ToInt32([System.BitConverter]::GetBytes($Rule.AccessMask), 0) - } - else { - $AccessMask = $Rule.AccessMask - } - - # Common params b/w access and audit ACEs: - $Params = @{ - Principal = $Principal - AccessMask = $AccessMask - AceFlags = $Rule.AceFlags - AceType = [System.Security.AccessControl.AceType] $Rule.AceType - } - - if ($Rule.AceType -eq [System.Security.AccessControl.AceQualifier]::SystemAudit) { - # Not an access entry, but an audit entry - $Params.AuditSuccess = [bool] ($Rule.AceFlags -band [System.Security.AccessControl.AceFlags]::SuccessfulAccess) - $Params.AuditFailure = [bool] ($Rule.AceFlags -band [System.Security.AccessControl.AceFlags]::FailedAccess) - } - - # Make the rule: - Write-Debug "$($MyInvocation.MyCommand): Calling New-AccessControlEntry to create CommonAce from Win32_ACE" - $Rule = New-AccessControlEntry @Params - break - - } - - default { - Write-Error "Unknown access rule type!" - return - } - } - - if (-not $KeepInheritedFlag) { - # There is a possibility that the ACE that came through - # this function was inherited. If this function is being used, - # it's usually to add or remove an ACE. In either of those - # scenarios, you don't want the resulting ACE to still be - # inherited, so remove that flag if it's present - if ($Rule.AceFlags -band [System.Security.AccessControl.AceFlags]::Inherited) { - $Rule.AceFlags = $Rule.AceFlags -bxor [System.Security.AccessControl.AceFlags]::Inherited - } - } - else { - if ($IsRuleInherited -and (-not ($Rule.AceFlags -band [System.Security.AccessControl.AceFlags]::Inherited))) { - # If the original rule was inherited, but the converted one isn't, fix it! - $Rule.AceFlags = $Rule.AceFlags -bxor [System.Security.AccessControl.AceFlags]::Inherited - } - } - - # Output the rule: - $Rule - } - } -} - -function GetSecurityInfo { -<# -Wraps the PInvoke signature for GetNamedSecurityInfo and GetSecurityInfo. Path validation is up -to the caller (but this function should return a meaningful error message if an error is encountered) - -#> - - [CmdletBinding()] - param( - [Parameter(Mandatory=$true, Position=0, ParameterSetName="Named")] - [string] $Path, - [Parameter(Mandatory=$true, Position=0, ParameterSetName="NotNamed")] - [IntPtr] $Handle, - [Parameter(Mandatory=$true)] - [System.Security.AccessControl.ResourceType] $ObjectType, - [PowerShellAccessControl.PInvoke.SecurityInformation] $SecurityInformation = "Owner, Group, Dacl" - ) - - # Initialize pointers for the different sections (the only pointer we'll use is the one - # to the entire SecurityDescriptor (it will work even if all sections weren't requested): - $pOwner = $pGroup = $pDacl = $pSacl = $pSecurityDescriptor = [System.IntPtr]::Zero - - # Function and arguments are slightly different depending on param set: - if ($PSCmdlet.ParameterSetName -eq "Named") { - $FunctionName = "GetNamedSecurityInfo" - $FirstArgument = $Path - } - else { - $FunctionName = "GetSecurityInfo" - $FirstArgument = $Handle - } - - - Write-Debug "$($MyInvocation.MyCommand): Getting security descriptor for '$FirstArgument' ($ObjectType) with the following sections: $SecurityInformation" - - if ($SecurityInformation -band [PowerShellAccessControl.PInvoke.SecurityInformation]::Sacl) { - # Make sure SeSecurityPrivilege is enabled, since this is required to view/modify - # the SACL - $AdjustPrivResults = SetTokenPrivilege -Privilege SeSecurityPrivilege - } - - try { - # Put arguments in array b/c PSv2 seems to require it to do the Invoke() call below (I didn't look - # into it too much, but it was definitely erroring out when I had them in directly in the method - # call): - $Arguments = @( - $FirstArgument, - $ObjectType, - $SecurityInformation, - [ref] $pOwner, - [ref] $pGroup, - [ref] $pDacl, - [ref] $pSacl, - [ref] $pSecurityDescriptor - ) - - [PowerShellAccessControl.PInvoke.advapi32]::$FunctionName.Invoke($Arguments) | - CheckExitCode -ErrorAction Stop -Action "Getting security descriptor for '$FirstArgument'" - - - if ($pSecurityDescriptor -eq [System.IntPtr]::Zero) { - # I've seen this happen with ADMIN shares (\\.\c$); ReturnValue is 0, - # but no SD is returned. - # - # Invalid pointer, so no need to try to free the memory - Write-Error "No security descriptor available for '$FirstArgument'" - return - } - - try { - # Get size of security descriptor: - $SDSize = [PowerShellAccessControl.PInvoke.advapi32]::GetSecurityDescriptorLength($pSecurityDescriptor) - Write-Debug "$($MyInvocation.MyCommand): SD size = $SDSize bytes" - - # Put binary SD in byte array: - $ByteArray = New-Object byte[] $SDSize - [System.Runtime.InteropServices.Marshal]::Copy($pSecurityDescriptor, $ByteArray, 0, $SDSize) - - # Output array: - $ByteArray - } - catch { - Write-Error $_ - } - finally { - # Clear memory from SD: - Write-Debug "$($MyInvocation.MyCommand): Freeing SD memory" - [PowerShellAccessControl.PInvoke.kernel32]::LocalFree($pSecurityDescriptor) | - CheckExitCode -Action "Freeing memory for security descriptor ($FirstArgument)" - } - } - catch { - Write-Error $_ - } - finally { - if ($AdjustPrivResults.PrivilegeChanged) { - # Privilege was changed earlier, so now it must be reverted: - - $AdjustPrivResults = SetTokenPrivilege -Privilege SeSecurityPrivilege -Disable - - if ($AdjustPrivResults.PrivilegeChanged -eq $false) { - Write-Error "Error reverting SeSecurityPrivilege back to disabled!" - } - } - } -} - -function SetSecurityInfo { -<# -Wraps the PInvoke signature for SetNamedSecurityInfo and SetSecurityInfo. Path validation is up -to the caller (but this function should return a meaningful error message if an error is encountered) - -#> - - [CmdletBinding()] - param( - [Parameter(Mandatory=$true, Position=0, ParameterSetName="Named")] - [string] $Path, - [Parameter(Mandatory=$true, Position=0, ParameterSetName="NotNamed")] - [IntPtr] $Handle, - [Parameter(Mandatory=$true)] - [System.Security.AccessControl.ResourceType] $ObjectType, - [System.Security.Principal.IdentityReference] $Owner, - [System.Security.Principal.IdentityReference] $Group, - [System.Security.AccessControl.DiscretionaryAcl] $DiscretionaryAcl, - [System.Security.AccessControl.SystemAcl] $SystemAcl, - [PowerShellAccessControl.PInvoke.SecurityInformation] $SecurityInformation - ) - - if (-not $PSBoundParameters.ContainsKey("SecurityInformation")) { - # SecurityInformation enum wasn't provided, so function will - # build it up using the sections that were provided - $SecurityInformation = 0 - } - - # If SecurityInformation was specified, the following section may still modify it. Example would - # be if SecurityInformation contained 'Dacl, ProtectedDacl' and the Owner parameter was supplied, - # 'Owner' would be added to the SecurityInformation flag. The provided SecurityInformation will - # be bor'ed with the flags for any of the four SD sections that are provided. - - # Get binary forms of sections: - foreach ($SectionName in "Owner", "Group", "DiscretionaryAcl", "SystemAcl") { - - if ($PSBoundParameters.ContainsKey($SectionName)) { - - $Section = $PSBoundParameters.$SectionName - - $SectionLength = $Section.BinaryLength - - if (-not $PSBoundParameters.ContainsKey("SecurityInformation")) { - # SecurityInformation wasn't provided to function, so it's the function's - # job to determine what needs to be set. It will do that by looking at the - # sections that were passed - - # This will convert 'DiscretionaryAcl' to 'Dacl' and 'SystemAcl' to 'Sacl' - # so that the section names will match with the SecurityInfo enum (Owner and - # Group already match) - $FlagName = $SectionName -replace "(ystem|iscretionary)A", "a" - - $SecurityInformation = $SecurityInformation -bor [PowerShellAccessControl.PInvoke.SecurityInformation]::$FlagName - } - - if ($SectionLength -ne $null) { - $ByteArray = New-Object byte[] $SectionLength - $Section.GetBinaryForm($ByteArray, 0) - } - else { - # In this scenario, a null section was passed, but the function was called - # with this section enabled, so a null ACL will be applied - $ByteArray = $null - } - } - else { - # Section wasn't specified, so no ptr - $ByteArray = $null - } - - Set-Variable -Scope Local -Name ${SectionName}ByteArray -Value $ByteArray -Confirm:$false -WhatIf:$false - } - - # Function and arguments are slightly different depending on param set: - if ($PSCmdlet.ParameterSetName -eq "Named") { - $FunctionName = "SetNamedSecurityInfo" - $FirstArgument = $Path - } - else { - $FunctionName = "SetSecurityInfo" - $FirstArgument = $Handle - } - - Write-Debug "$($MyInvocation.MyCommand): Setting security descriptor for '$FirstArgument' ($ObjectType) with the following sections: $SecurityInformation" - - if ($SecurityInformation -band [PowerShellAccessControl.PInvoke.SecurityInformation]::Sacl) { - # Make sure SeSecurityPrivilege is enabled - $SecurityPrivResults = SetTokenPrivilege -Privilege SeSecurityPrivilege - } - - if ($SecurityInformation -band [PowerShellAccessControl.PInvoke.SecurityInformation]::Owner) { - # Attempt to grant SeTakeOwnershipPrivilege and SeRestorePrivilege. If privilege isn't held, - # no error should be generated. That being said, these privs aren't always needed, so might - # end up putting logic here (or in Set-SecurityDescriptor) that checks to see if the current - # user has WRITE_OWNER and if the new owner is the current user (or a group that the current - # user has the Owner attribute set), then no privs are necessary. Also, if the current user - # doesn't have WRITE_OWNER, but they want the take ownership, then SeRestorePrivilege isn't - # required. Just some stuff to think about... - $TakeOwnershipPrivResults = SetTokenPrivilege -Privilege SeTakeOwnershipPrivilege - $RestorePrivilegeResults = SetTokenPrivilege -Privilege SeRestorePrivilege - } - - try { - [PowerShellAccessControl.PInvoke.advapi32]::$FunctionName.Invoke( - $FirstArgument, - $ObjectType, - $SecurityInformation, - $OwnerByteArray, - $GroupByteArray, - $DiscretionaryAclByteArray, - $SystemAclByteArray - ) | CheckExitCode -ErrorAction Stop -Action "Setting security descriptor for '$FirstArgument'" - } - catch { - Write-Error $_ - } - finally { - - foreach ($PrivilegeResult in ($SecurityPrivResults, $TakeOwnershipPrivResults, $RestorePrivilegeResults)) { - if ($PrivilegeResult.PrivilegeChanged) { - # If this is true, then the privilege was changed, so it needs to be - # reverted back. If it's false, then the privilege wasn't changed (either - # b/c the user doesn't hold the privilege, or b/c it was already enabled; - # it doesn't really matter why). So, disable it if it was successfully - # enabled earlier. - - $NewResult = SetTokenPrivilege -Privilege $PrivilegeResult.PrivilegeName -Disable - if (-not $NewResult.PrivilegeChanged) { - # This is an error; privilege wasn't changed back to original setting - Write-Error ("Error reverting {0}" -f $PrivilegeResult.PrivilegeName) - } - } - } - } -} - -function GetWmiObjectInfo { -<# -Takes as input a WMI or CimInstance object. Returns as output an object with the following -properties: ClassName, ComputerName, Path, Namespace. - -All of those properties are readily available for either type of object, but they are located -in different properties depending on the type of the object. This function returns a common, -known format for the properties that GetPathInformation can use. -#> - - [CmdletBinding()] - param( - [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0)] - $WmiObject - ) - - process { - $Properties = @{} - switch -Wildcard ($WmiObject.GetType().FullName) { - "Microsoft.Management.Infrastructure.CimInstance" { - $Properties.ClassName = $WmiObject.CimSystemProperties.ClassName - $Properties.ComputerName = $WmiObject.CimSystemProperties.ServerName - $Properties.Path = $WmiObject | Get-CimPathFromInstance - $Properties.Namespace = $WmiObject.CimSystemProperties.Namespace - } - "System.Management.Management*Object" { - $Properties.ClassName = $WmiObject.__CLASS - $Properties.ComputerName = $WmiObject.__SERVER - $Properties.Path = $WmiObject.__PATH - $Properties.Namespace = $WmiObject.__NAMESPACE - } - default { - throw "Unknown WMI object!" - } - } - New-Object PSObject -Property $Properties - } - -} - -function SetTokenPrivilege { - - [CmdletBinding()] - param( - [Parameter(ValueFromPipelineByPropertyName=$true)] - [int] $ProcessId = $pid, - [Parameter(Mandatory=$true)] - [ValidateSet( # Taken from Lee Holmes' privilege script: - "SeAssignPrimaryTokenPrivilege", "SeAuditPrivilege", "SeBackupPrivilege", "SeChangeNotifyPrivilege", - "SeCreateGlobalPrivilege", "SeCreatePagefilePrivilege", "SeCreatePermanentPrivilege", - "SeCreateSymbolicLinkPrivilege", "SeCreateTokenPrivilege", "SeDebugPrivilege", "SeEnableDelegationPrivilege", - "SeImpersonatePrivilege", "SeIncreaseBasePriorityPrivilege", "SeIncreaseQuotaPrivilege", - "SeIncreaseWorkingSetPrivilege", "SeLoadDriverPrivilege", "SeLockMemoryPrivilege", "SeMachineAccountPrivilege", - "SeManageVolumePrivilege", "SeProfileSingleProcessPrivilege", "SeRelabelPrivilege", "SeRemoteShutdownPrivilege", - "SeRestorePrivilege", "SeSecurityPrivilege", "SeShutdownPrivilege", "SeSyncAgentPrivilege", - "SeSystemEnvironmentPrivilege", "SeSystemProfilePrivilege", "SeSystemtimePrivilege", "SeTakeOwnershipPrivilege", - "SeTcbPrivilege", "SeTimeZonePrivilege", "SeTrustedCredManAccessPrivilege", "SeUndockPrivilege", "SeUnsolicitedInputPrivilege" - )] - [string] $Privilege, - [switch] $Disable - ) - - begin { - $Advapi32 = [PowerShellAccessControl.PInvoke.advapi32] - $Kernel32 = [PowerShellAccessControl.PInvoke.kernel32] - } - - process { - - if ($Disable) { - $Action = "disable" - } - else { - $Action = "enable" - } - - # Wrap the process handle in a HandleRef to make sure it isn't GC'd: - $Process = Get-Process -Id $ProcessId - $hRef = New-Object System.Runtime.InteropServices.HandleRef ($Process, $Process.Handle) - - try { - # Open the process token: - $Message = "Getting token handle for '{0}' process ({1})" -f $Process.Name, $Process.Id - Write-Debug "$($MyInvocation.MyCommand): $Message" - - $TokenHandle = [System.IntPtr]::Zero - $Advapi32::OpenProcessToken( - $hRef, - [System.Security.Principal.TokenAccessLevels] "AdjustPrivileges, Query", - [ref] $TokenHandle - ) | CheckExitCode -Action $Message - - # Look up the LUID for the privilege - $LUID = New-Object PowerShellAccessControl.PInvoke.advapi32+LUID - $Advapi32::LookupPrivilegeValue( - $null, # SystemName param; null means local system - $Privilege, - [ref] $LUID - ) | CheckExitCode -Action "Looking up ID for '$Privilege' privilege" - - - $LuidAndAttributes = New-Object PowerShellAccessControl.PInvoke.advapi32+LUID_AND_ATTRIBUTES - $LuidAndAttributes.Luid = $LUID - - if ($Disable) { - $LuidAndAttributes.Attributes = [PowerShellAccessControl.PInvoke.advapi32+PrivilegeAttributes]::Disabled - } - else { - $LuidAndAttributes.Attributes = [PowerShellAccessControl.PInvoke.advapi32+PrivilegeAttributes]::Enabled - } - - # Initialize some arguments for AdjustTokenPrivileges call - $TokenPrivileges = New-Object PowerShellAccessControl.PInvoke.advapi32+TOKEN_PRIVILEGES - $TokenPrivileges.PrivilegeCount = 1 - $TokenPrivileges.Privileges = $LuidAndAttributes - - $PreviousState = New-Object PowerShellAccessControl.PInvoke.advapi32+TOKEN_PRIVILEGES - $ReturnLength = 0 - - $Message = "Setting '$Privilege' to ${Action}d" - Write-Debug "$($MyInvocation.MyCommand): $Message" - - $Advapi32::AdjustTokenPrivileges( - $TokenHandle, - $false, # Disable all privileges - [ref] $TokenPrivileges, # NewState - [System.Runtime.InteropServices.Marshal]::SizeOf($PreviousState), - [ref] $PreviousState, # PreviousState - [ref] $ReturnLength - ) | CheckExitCode -Action $Message -ErrorAction Stop - } - catch { - Write-Error $_ - } - finally { - # Check out $PreviousState. If privilege was changed, PrivilegeCount will - # be greater than 0 (for our PInvoke signature, 1 is the highest we'll ever - # see; we can only change one at a time - $PrivilegeChanged = [bool] $PreviousState.PrivilegeCount - Write-Debug "$($MyInvocation.MyCommand): Privilege changed: $PrivilegeChanged" - - Write-Debug "$($MyInvocation.MyCommand): Closing token handle" - $Kernel32::CloseHandle($TokenHandle) | CheckExitCode -Action "Error closing token handle: $_" -ErrorAction Stop - } - - # Create a return object - New-Object PSObject -Property @{ - PrivilegeName = $Privilege - ReturnCode = $ReturnCode - PreviousState = $PreviousState - PrivilegeChanged = $PrivilegeChanged - } - } -} - -function CheckExitCode { -<# - Writes an error message if the provided code is non-zero. -#> - - [CmdletBinding()] - param( - [Parameter(Mandatory=$true, ValueFromPipeline=$true)] - $ExitCode, - [switch] $WriteWarnings, - [switch] $VerboseSuccesses, - $Action - ) - - process { - - # ExitCode needs to an Int32, but I didn't want to make that be all that the input - # takes. For that reason, we convert UInt32s to Int32s - if ($ExitCode -isnot [int]) { - try { - $ExitCode = [int] $ExitCode - } - catch { - try { - $ExitCode = [System.BitConverter]::ToInt32([System.BitConverter]::GetBytes($ExitCode), 0) - } - catch { - Write-Error ("Can't convert '{0}' to [int]" -f $ExitCode.GetType().FullName) - return - } - } - } - - if ($Action) { - $Action = "{0}: " -f $Action - } - else { - $Action = $null - } - - try { - $ErrorMessage = "{0}{1}" -f $Action, ([System.ComponentModel.Win32Exception] $ExitCode).Message - } - catch { - Write-Error $_ - return - } - - if ($ExitCode) { - $Params = @{ - Message = $ErrorMessage - } - - if ($WriteWarnings) { - $CmdletToUse = "Write-Warning" - } - else { - $CmdletToUse = "Write-Error" - $Params.ErrorId = $ExitCode - } - - & $CmdletToUse @Params - } - else { - if ($VerboseSuccesses) { - Write-Verbose $ErrorMessage - } - } - } -} - -function GetPathInformation { -<# -This is the function that (hopefully) allows the functions that get and set the security descriptors to know -all necessary information about the object the user is interested in. It should be able to tell if it's a -container (like a folder, registry key, WMI namespace, DS object, etc), if its a DS object, what access mask -enumeration to use, the SdPath (used by GetSecurityInfo and SetSecurityInfo), the Path (a friendlier version -of the path; might be a PsPath, might be a text form of a WMI or CIM object), DisplayName (usually the path, -but sometimes extra information is conveyed), the ObjectType (used by Get and SetSecurityInfo), etc. - -It should be able to take as input path strings, actual objects (.NET objects, WMI/CIM objects, WsMan objects, -etc). The output should be able to be splatted into New-AdaptedSecurityDescriptor (you'll still need the SDDL -or binary forms of the security descriptor) -#> - [CmdletBinding(DefaultParameterSetName='Path')] - param( - [Parameter(Mandatory=$true, ParameterSetName='InputObject', ValueFromPipeline=$true)] - $InputObject, - [Parameter(ParameterSetName='DirectPath', ValueFromPipelineByPropertyName=$true)] - [Parameter(ParameterSetName='Path', Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] - # Path that the Get-Item cmdlet can use to get an object. - [string[]] $Path = ".", - [Parameter(Mandatory=$true, ParameterSetName='LiteralPath', ValueFromPipelineByPropertyName=$true)] - # Literal path taht the Get-Item cmdlet can use to get an object - [string[]] $LiteralPath, - [Parameter(ParameterSetName='DirectPath', ValueFromPipelineByPropertyName=$true)] - [System.Security.AccessControl.ResourceType] $ObjectType, - [Parameter(ParameterSetName='DirectPath')] - [switch] $IsContainer = $false, - [Parameter(ValueFromRemainingArguments=$true)] - $__RemainingArguments - ) - - begin { - # The process block has two main steps: - # Step 1: Collect potential input objects into the $InputObject variable. If that parameter was - # passed, then the function gets to skip step #1 - # Step 2: Go through each object in the $InputObject variable. If the pstypenames property - # contains the following string, the object will not be "inspected" as much. This was - # originally used for when the path and ObjectType were explicitly supplied (notice - # the 'DirectPath' parameter set name), but it is actually used some in step #1, too. - $DirectPathObjectType = "PowerShellAccessControl.DirectPath" - } - - process { - - # Step 1: Convert everything to objects (unless $InputObject was the parameter supplied). - # 1.1: If paths were provided instead of objects, try to use Resolve-Path to get the fully resolved path, and the - # type of the object the path points to. If that works, add a custom object with whatever info we were able - # to obtain, and give it a type of $DirectPathObjectType. - # 1.2: If Resolve-Path can't handle it (and it wasn't already a DirectPath), check to see if it's some sort of - # path that this module is aware of (the module uses WMI/CIM path information kind of like a drive; also LDAP:// - # paths can be used, etc - try { - switch ($PSCmdlet.ParameterSetName) { - <# - If a path is defined, this function will first attempt to use Resolve-Path to see if it is a path - to a file, folder, or registry key (resolve-path isn't used if the -ObjectType parameter was passed; - that's handled in the second switch condition). If it's not a file, folder, or registry key, an error - will be thrown, and the catch block will check to see if it's a path format that this module created... - - NOTE: This function used to use Get-Item for Path and LiteralPath param sets, but that means that you - have to have read access in order for the function to return, and read access isn't always necessary - to get/change a security descriptor. Doing it this way means that there's no read access requirement. - #> - { $_ -eq "Path" -or $_ -eq "LiteralPath" } { - # Pass either the -Path or -LiteralPath param and its value (depends on param set name) - $ResolvePathParams = @{ - $PSCmdlet.ParameterSetName = $PSBoundParameters[$PSCmdlet.ParameterSetName] - ErrorAction = "Stop" - } - - # Notice that whether or not the object is a container is being stored in a property called PsIsContainer. That's - # to mimic the behavior that will occur if an object (FileInfo, DirectoryInfo, RegistryKey) is passed intead of - # a path that is inspected w/ Resolve-Path (or a direct path where the -IsContainer parameter determines whether - # or not the object is a container) - - $InputObject = foreach ($CurrentPath in (Resolve-Path @ResolvePathParams)) { - $ReturnObjectProperties = @{} - switch ($CurrentPath.Provider) { - - Microsoft.PowerShell.Core\FileSystem { - $ReturnObjectProperties.Path = $ReturnObjectProperties.DisplayName = $ReturnObjectProperties.SdPath = $CurrentPath.ProviderPath - $ReturnObjectProperties.ObjectType += [System.Security.AccessControl.ResourceType]::FileObject - try { - $ReturnObjectProperties.PsIsContainer = [bool]([System.IO.File]::GetAttributes($CurrentPath.ProviderPath) -band [System.IO.FileAttributes]::Directory) - } - catch { - # There was an error checking on this, so assume it's not a container: - Write-Warning ("Couldn't determine if '{0}' is a file or directory; treating as a file" -f $CurrentPath.ProviderPath) - $ReturnObjectProperties.PsIsContainer = $false - } - } - - Microsoft.PowerShell.Core\Registry { - $ReturnObjectProperties.SdPath = $CurrentPath.ProviderPath -replace "^HKEY_(LOCAL_)?" - $ReturnObjectProperties.ObjectType = [System.Security.AccessControl.ResourceType]::RegistryKey - $ReturnObjectProperties.PsIsContainer = $true - $ReturnObjectProperties.Path = $CurrentPath.Path - $ReturnObjectProperties.DisplayName = $CurrentPath.ProviderPath - } - - Microsoft.ActiveDirectory.Management\ActiveDirectory { - # Path should be in the form of {qualifier}:\{dn} - # We want the dn, so use Split-Path to remove the qualifier (which - # could be something other than the default AD:\ - $ReturnObjectProperties.SdPath = (Split-Path $CurrentPath.Path -NoQualifier) -replace "(^\\)?" - $ReturnObjectProperties.ObjectType = [System.Security.AccessControl.ResourceType]::DSObjectAll - $ReturnObjectProperties.Path = $ReturnObjectProperties.DisplayName = $CurrentPath.Path - } - - { $_ -match "^PowerShellAccessControl" } { - - # Proxy Resolve-Path function can handle long paths (somewhat). Provider returned is either - # PowerShellAccessControlDirectory or PowerShellAccessControlFile - $ReturnObjectProperties.SdPath = "\\?\{0}" -f $CurrentPath.Path - $ReturnObjectProperties.DisplayName = $ReturnObjectProperties.Path = $CurrentPath.Path - $ReturnObjectProperties.ObjectType = [System.Security.AccessControl.ResourceType]::FileObject - $ReturnObjectProperties.PsIsContainer = $CurrentPath.Provider -match "Directory$" - } - - default { - throw ("Unknown path provider: $_") - } - } - - $ReturnObject = New-Object PSObject -Property $ReturnObjectProperties - $ReturnObject.pstypenames.Insert(0, $DirectPathObjectType) # Function will inspect object type later - $ReturnObject - } - - if ($InputObject -eq $null) { - Write-Error ("Error resolving path: {0}" -f $PSBoundParameters[$PSCmdlet.ParameterSetName]) - } - } - - "DirectPath" { - $InputObject = foreach ($CurrentPath in $Path) { - $ReturnObject = New-Object PSObject -Property @{ - SdPath = $CurrentPath - ObjectType = $ObjectType - PsIsContainer = $IsContainer - } - - $ReturnObject.pstypenames.Insert(0, $DirectPathObjectType) - $ReturnObject - } - - } - - "InputObject" { - # No extra work needed - } - - default { - # Shouldn't happen - Write-Error "Unknown parameter set name!" - return - } - } - } - catch { - <# - Three possibilities: - 1. An invalid path was presented, in which case we should write the error, then exit this iteration of the - function - 2. The path is specially crafted by this module: - - WMI object - - Service object - - Process object - In that case, the module should understand the string. If it doesn't, it will throw an error. - 3. The path is an AD path. If the path is in the form LDAP://{distinguishedname}, then everything works - great. If it doesn't have the LDAP:// prefix, then things might not work so well. To try to handle - that, I have a check to see if 'DC=' is somewhere in the path. If so, [adsi]::Exists() is called - to see if it appears to be a valid AD path. If so, the path is modified to start with LDAP so the - switch statement will craft an object that can be used to create the adapted SD. - #> - - $Paths = $PSBoundParameters[$PSCmdlet.ParameterSetName] - $OriginalError = $_ - $InputObject = @() - foreach ($CurrentPath in $Paths) { - try { - if ($CurrentPath -match "^(?!LDAP://).*DC=" -and [adsi]::Exists("LDAP://{0}" -f $CurrentPath)) { - $CurrentPath = "LDAP://$CurrentPath" - } - } - catch { - # Don't need to do anything here since the path didn't have to be for AD - } - - try { - $Qualifier = (Split-Path $CurrentPath -Qualifier -ErrorAction Stop).TrimEnd(":") - $PathWithoutQualifier = (Split-Path $CurrentPath -NoQualifier -ErrorAction Stop).Trim() - - switch ($Qualifier) { - "ManagementObject" { - $InputObject += [wmi] $PathWithoutQualifier - } - - "CimInstance" { - $InputObject += Get-CimInstanceFromPath $PathWithoutQualifier - } - - "Service" { - if ($PathWithoutQualifier -notmatch "^\\\\(?.*)\\(?.*)$") { - throw "catch me" - } - - $InputObject += Get-Service -ComputerName $matches.computer -Name $matches.service - } - - "Process" { - if ($PathWithoutQualifier -notmatch "\(PID (?\d+)\)$") { - throw "catch me" - } - - $InputObject += Get-Process -Id $matches.processid - } - - LDAP { - $ReturnObject = New-Object PSObject -Property @{ - # Get rid of any leading slashes - SdPath = $PathWithoutQualifier -replace "^\/*" - ObjectType = [System.Security.AccessControl.ResourceType]::DSObjectAll - } - - $ReturnObject.pstypenames.Insert(0, $DirectPathObjectType) - $InputObject += $ReturnObject - } - - default { - # Must not be in proper path format! - throw "Catch this below and write original error" - } - } - } - catch { - throw $OriginalError - continue - } - } - } - - # Step 2: Go through each $InputObject and assemble all known information about it. That might include inspecting - # the underlying object. -:ObjectLoop foreach ($Object in $InputObject) { - if ($Object -eq $null) { continue} - - $OutputProperties = @{ - # This is usually just disposed of by the calling function, but in some instances it's useful - # information - InputObject = $Object - } - - # One of this functions most important jobs is figuring out if the supplied object is a - # container, since the inheritance and propagation flags allowed on ACEs contained in - # SDs depends on that. Here, we check to see if the object that was supplied to this function - # contains the information. There are several types of objects where this check doesn't matter - # because the IsContainer is going to be hard coded to true or false, but NTFS permissions - # definitely need this check since the object could be a file or a folder. - # Note that this property may exist b/c a FileInfo, DirectoryInfo, RegistryKey, etc object - # was passed into this function, or it may have been added earlier in this function b/c - # a path was passed. - if ($Object.PSIsContainer -ne $null) { - $OutputProperties.IsContainer = $Object.PSIsContainer - } - - Write-Debug "$($MyInvocation.MyCommand): Current object type: $($Object.GetType().FullName)" - switch ($Object.GetType().FullName) { - { $_ -match "System\.(Security\.AccessControl|DirectoryServices)\.(\w+)Security" } { - # User has passed a native .NET SD into the calling function. As of v3.0, the module should - # be able to handle those SDs, so this function is going to call itself against the path - # contained in the SD, but it is also going to add the Sddl from the SD's Sddl property - # to the output. The calling function will know that it shouldn't look up the SD at - # that point. This is desireable b/c this means that Get-SecurityDescriptor can now call - # on this function and convert a live, in-memory SD into the SD format that this module - # uses. This opens up the ability for Get-Ace and Set-SD to work with native .NET SDs. - - Write-Debug "$($MyInvocation.MyCommand): Security descriptor is native .NET class ($_). Creating temporary 'Adapted SD'..." - # First, get path information. This will fill in the DisplayName, Path, ObjectType, etc - if ($Object.Path) { - try { - $OutputProperties = GetPathInformation -Path $Object.Path -ErrorAction Stop - - # If there was an issue (and no errors were written), $OutputProperties will be $null. That's - # bad, so throw an error and let the catch {} block handle it - if ($OutputProperties -eq $null) { throw "Unable to get path information for security descriptor" } - } - catch { - Write-Error "Error getting access control entries from .NET class '$_'" - continue ObjectLoop - } - } - else { - # Using AD module w/ ntSecurityDescriptor or msExchMailboxSecurityDescriptor properites - # will return an object w/ an empty Path property. Not sure if there are other scenarios. - - # Try to get all of the necessary information (ObjectType is biggest we need to know; if other - # information is missing later, it gets filled in): - $OutputProperties.DisplayName = "[UNKNOWN]" - Write-Debug "$($MyInvocation.MyCommand): No path information available; setting DisplayName to $($OutputProperties.DisplayName)" - - switch ($_) { - System.Security.AccessControl.DirectorySecurity { - $OutputProperties.ObjectType = [System.Security.AccessControl.ResourceType]::FileObject - $OutputProperties.IsContainer = $true - } - - System.Security.AccessControl.FileSecurity { - $OutputProperties.ObjectType = [System.Security.AccessControl.ResourceType]::FileObject - $OutputProperties.IsContainer = $false - } - - System.DirectoryServices.ActiveDirectorySecurity { - $OutputProperties.ObjectType = [System.Security.AccessControl.ResourceType]::DSObjectAll - } - - default { - Write-Error "Unable to get path information for the security descriptor. Use New-AdaptedSecurityDescriptor to convert this into an adapted security descriptor." - continue ObjectLoop - } - } - } - - # Give the display name something to show that this is just an in-memory SD - $OutputProperties.DisplayName = "{0} (Converted .NET SD)" -f $OutputProperties.DisplayName - - # Add the SDDL of the current SD: - $OutputProperties.Sddl = $Object.Sddl - } - - - { $Object.pstypenames -eq $DirectPathObjectType } { - # Direct path means that the function shouldn't do any inspection on the object. Maybe - # the user is looking for Share permissions by supplying a path; if left up to the module - # to figure out what to do, it would see that path as a valid file path, and lookup NTFS - # permissions. If the user supplied the -ObjectType to Get-SD, then direct path mode - # goes into effect, and the module just accepts what the user told it. Another area where - # this is useful is paths too long for the .NET framework. - $OutputProperties.SdPath = $Object.SdPath - if ($Object.Path -eq $null) { - $OutputProperties.Path = $Object.SdPath - } - else { - $OutputProperties.Path = $Object.Path - } - $OutputProperties.ObjectType = $Object.ObjectType - if ($Object.DisplayName -eq $null) { - $OutputProperties.DisplayName = "{0} ({1})" -f $OutputProperties.SdPath, $OutputProperties.ObjectType - } - else { - $OutputProperties.DisplayName = $Object.DisplayName - } - } - - { $_ -like "System.Management.Management*Object" -or - $_ -eq "Microsoft.Management.Infrastructure.CimInstance" } { - - # WMI object; we might be able to work with this - # To find out, lets get some info from it: - $WmiInfo = GetWmiObjectInfo $Object - - # Path that allows module to get a WMI object back - $OutputProperties.Path = "{0}: {1}" -f $Object.GetType().Name, $WmiInfo.Path - - # And another switch :) - switch ($WmiInfo.ClassName) { - - "Win32_Service" { - $OutputProperties.SdPath = "\\{0}\{1}" -f $WmiInfo.ComputerName, $Object.Name - $OutputProperties.ObjectType = [System.Security.AccessControl.ResourceType]::Service - $OutputProperties.DisplayName = "Service: {0}" -f $Object.DisplayName - } - - { $_ -eq "Win32_Printer" -or $_ -eq "MSFT_Printer" } { - $OutputProperties.SdPath = "\\{0}\{1}" -f $WmiInfo.ComputerName, $Object.Name - $OutputProperties.ObjectType = [System.Security.AccessControl.ResourceType]::Printer - $OutputProperties.DisplayName = "Printer: {0}" -f $Object.Name - } - - "__SystemSecurity" { - # This isn't handled by Get/Set SecurityInfo cmdlets (which use Win32 calls), but it is handled - # by the module. We're going to set the paths to a string that this function can later use to - # get the WMI object back - $OutputProperties.SdPath = $OutputProperties.Path = "{0}: {1}" -f $Object.GetType().Name, $WmiInfo.Path - $OutputProperties.ObjectType = $__PowerShellAccessControlResourceTypeName - $OutputProperties.DisplayName = "WMI Namespace: {0}" -f $WmiInfo.Namespace - $OutputProperties.AccessMaskEnum = [PowerShellAccessControl.WmiNamespaceRights] - $OutputProperties.IsContainer = $true - } - - { $_ -eq "Win32_LogicalShareSecuritySetting" -or $_ -eq "Win32_Share" -or $_ -eq "MSFT_SmbShare" } { - $OutputProperties.SdPath = "\\{0}\{1}" -f $WmiInfo.ComputerName, $Object.Name - $OutputProperties.ObjectType = [System.Security.AccessControl.ResourceType]::LMShare - $OutputProperties.DisplayName = "Share: {0}" -f $Object.Name - } - - "Win32_Process" { - - GetPathInformation -InputObject (Get-Process -Id $Object.ProcessId) - continue ObjectLoop - } - - { "__SecurityDescriptor", "Win32_SecurityDescriptor" -contains $_ } { - $OutputProperties.Path = $OutputProperties.DisplayName = "[Win32_SecurityDescriptor]" - $OutputProperties.Sddl = $InputObject | ConvertFrom-Win32SecurityDescriptor -Sddl | select -exp Sddl - $OutputProperties.IsContainer = $true # Assume always a container so that inheritance flags on containers aren't messed up - $OutputProperties.ObjectType = $__PowerShellAccessControlResourceTypeName - } - - default { - Write-Error ("Unsupported WMI class: {0}" -f $_) - continue ObjectLoop - } - } - } - - { $Object.pstypenames -contains "Microsoft.ActiveDirectory.Management.ADObject" } { - # AD object from ActiveDirectory module was passed - $OutputProperties.SdPath = $OutputProperties.Path = $OutputProperties.DisplayName = $Object.DistinguishedName - $OutputProperties.ObjectType = [System.Security.AccessControl.ResourceType]::DSObjectAll - $OutputProperties.DsObjectClass = $Object.ObjectClass - } - - - "Microsoft.Win32.RegistryKey" { - # GetNamedSecurityInfo API function needs registry hive in a different format - # than PS uses (http://msdn.microsoft.com/en-us/library/windows/desktop/aa379593%28v=vs.85%29.aspx) - if ($Object.Name -notmatch "^(?[^\\]+)\\(?.*)$") { - throw ("Uknown registry path: {0}" -f $Object.Name) - } - $Hive = $matches.hive -replace "^HKEY_(LOCAL_)?", "" - $RegPath = $matches.path - - # Valid hives: CLASSES_ROOT, CURRENT_USER, MACHINE, USERS - if (-not ("CURRENT_USER","MACHINE" -contains $Hive)) { - throw ("Unknown registry hive: $Hive") - } - - # SdPath can start with \\ for remote machines (maybe in the future) - $OutputProperties.SdPath = "$Hive\{0}" -f $RegPath # Path may contain {} - $OutputProperties.ObjectType = [System.Security.AccessControl.ResourceType]::RegistryKey - $OutputProperties.Path = $Object.PsPath - $OutputProperties.DisplayName = $Object.ToString() - } - - { "System.IO.DirectoryInfo", - "System.IO.FileInfo" -contains $_ } { - $OutputProperties.SdPath = $OutputProperties.Path = $Object.FullName - $OutputProperties.ObjectType = [System.Security.AccessControl.ResourceType]::FileObject - } - - "Microsoft.WSMan.Management.WSManConfigLeafElement" { - - # Still figuring out how to handle WSMan better, but for now, leaf elements with - # an SDDL property will work - - if ($Object.Name -ne "SDDL") { - Write-Error ("'{0}' does not contain a security resource" -f $Object.PsPath) - return - } - - $OutputProperties.SdPath = $OutputProperties.Path = $Object.PsPath - $OutputProperties.ObjectType = $__PowerShellAccessControlResourceTypeName - $OutputProperties.AccessMaskEnum = [PowerShellAccessControl.WsManAccessRights] - } - - "System.ServiceProcess.ServiceController" { - $OutputProperties.SdPath = "\\{0}\{1}" -f $Object.MachineName, $Object.ServiceName - $OutputProperties.ObjectType = [System.Security.AccessControl.ResourceType]::Service - $OutputProperties.DisplayName = "Service: {0}" -f $Object.DisplayName - $OutputProperties.Path = "Service: {0}" -f $OutputProperties.SdPath - } - - "System.Diagnostics.Process" { - $OutputProperties.DisplayName = $OutputProperties.Path = "Process: {0} (PID {1})" -f $Object.Name, $Object.Id - - if (-not $Object.Handle) { - Write-Error ("Can't access process handle for {0}" -f $OutputProperties.DisplayName) - return - } - - $HandleRef = New-Object System.Runtime.InteropServices.HandleRef ($Object, $Object.Handle) - $OutputProperties.Handle = $HandleRef - $OutputProperties.ObjectType = [System.Security.AccessControl.ResourceType]::KernelObject - $OutputProperties.AccessMaskEnum = [PowerShellAccessControl.ProcessAccessRights] - } - - - default { - <# - An unsupported object was presented. We can just end it here, or we can see if the object has a - .Path property (could even check for a LiteralPath property). This might be a bad idea, but we're - going to check it for a path property, and if it has one, we're going to return information as - if that's what was called (param binder won't bind the path property if an object was piped into - this function, or if the -InputObject was called) - #> - - Write-Debug "$($MyInvocation.MyCommand): Unknown object. Checking for path property or string value..." - if ($Object.Path -ne $null) { - try { - GetPathInformation -Path $Object.Path -ErrorAction Stop - } - catch { - Write-Error $_ - } - } - elseif ($Object.GetType().FullName -eq "System.String") { - try { - GetPathInformation -Path $Object - } - catch { - Write-Error $_ - } - } - else { - Write-Error ("{0} type not supported!" -f $_) - } - - return - } - } - - if (-not $OutputProperties.ContainsKey("DisplayName")) { - $OutputProperties.DisplayName = $OutputProperties.Path - } - - # Add AccessMask enumerations based on object type (this may have been done earlier when detecting - # what type of object was sent. WMI namespaces and WSMAN nodes share the same ObjectType, so they - # were defined earlier. Processes aren't the only kernel objects that could potentially be handled, - # so those are taken care of above, too - if ($OutputProperties.AccessMaskEnum -eq $null) { - switch ($OutputProperties.ObjectType.ToString()) { - "FileObject" { - $OutputProperties.AccessMaskEnum = [System.Security.AccessControl.FileSystemRights] - } - "Service" { - $OutputProperties.AccessMaskEnum = [PowerShellAccessControl.ServiceAccessRights] - $OutputProperties.IsContainer = $false # Service objects aren't containers (at least I don't think they are) - } - "Printer" { - $OutputProperties.AccessMaskEnum = [PowerShellAccessControl.PrinterRights] - $OutputProperties.IsContainer = $true # The GUI appears to allow container inherit/propagation flags - } - { $_ -eq "RegistryKey" -or $_ -eq "RegistryWow6432Key" } { - $OutputProperties.AccessMaskEnum = [System.Security.AccessControl.RegistryRights] - $OutputProperties.IsContainer = $true # Registry keys are containers - } - "LMShare" { - $OutputProperties.AccessMaskEnum = [PowerShellAccessControl.LogicalShareRights] - $OutputProperties.IsContainer = $false # I don't think logical shares are containers - } - { $_ -like "DSObject*" } { - $OutputProperties.AccessMaskEnum = [PowerShellAccessControl.ActiveDirectoryRights] - $OutputProperties.IsContainer = $true # Is this always the case?? - $OutputProperties.IsDsObject = $true - } - } - } - - # If the IsContainer property hasn't been defined by this point, it will be $false b/c of default value - - if ($OutputProperties.ObjectType -like "DsObject*" -and $OutputProperties.DsObjectClass -eq $null) { - # If this is for an AD object, and the ActiveDirectory module didn't provide the output, we need - # to look up the object class (that's needed to help with the AppliesTo for InheritedObjectAceTypes) - try { - $OutputProperties.DsObjectClass = ([adsi] ("LDAP://{0}" -f $OutputProperties.SdPath)).Properties.ObjectClass | select -last 1 - } - catch { - Write-Warning ("Unable to determine object class for '{0}'" -f $OutputProperties.SdPath) - $OutputProperties.DsObjectClass = "Unknown" - } - } - - if ($OutputProperties.DsObjectClass) { - $OutputProperties.DisplayName = "{0} ({1})" -f $OutputProperties.DisplayName, ($OutputProperties.DsObjectClass -join ", ") - } - - # Return a hash table that can be splatted to other functions... - $OutputProperties - - } # end foreach $Object in $InputObject - } -} - -function GetNewAceParams { -<# -The *-AccessControlEntry functions all share parameters with New-AccessControlEntry. In early versions of the module, I -knew that new parameters could/would be added, so I didn't want to explicitly define them on all of the functions (I'd -have to change every function each time a parameter change was made). For that reason, I use dynamic params on the other -functions. Some of the functions require changes to the Parameter() attributes, so the switches to this function can -handle that. - -I may end up explicitly defining each of the param blocks now that the module has (hopefully) matured enough to where -constant parameter changes aren't necessary. -#> - [CmdletBinding()] - param( - # This can actually be used for other function/cmdlet parameters - [Parameter(ValueFromPipeline=$true)] - $ParameterDictionary = (Get-Command New-AccessControlEntry -ArgumentList @("SystemAudit") | select -exp Parameters), - # Used for Add-AccessControlEntry and Remove-AccessControlEntry (when looking for an exact ACE match) - [switch] $ReplaceAllParameterSets, - # Used for Get-AccessControlEntry and Remove-AccessControlEntry (when looking for loose ACE matching) - [switch] $RemoveMandatoryAttribute, - [switch] $ConvertTypesToArrays, - [switch] $AllowAliases, - [switch] $AllowPositionAttributes - ) - - begin { - $__CommonParameterNames = [System.Runtime.Serialization.FormatterServices]::GetUninitializedObject([type] [System.Management.Automation.Internal.CommonParameters]) | - Get-Member -MemberType Properties | - Select-Object -ExpandProperty Name - - # We're going to make copies of param attributes later. You basically have to create a blank attrib, - # then change the properties. Knowing the writable ones will be very useful: - $__WritableParamAttributePropertyNames = New-Object System.Management.Automation.ParameterAttribute | - Get-Member -MemberType Property | - Where-Object { $_.Definition -match "{.*set;.*}$" } | - Select-Object -ExpandProperty Name - - if (-not $AllowPositionAttributes) { - # For the purposes of this module, we want to strip away any positional parameters from dynamic params: - $__WritableParamAttributePropertyNames = $__WritableParamAttributePropertyNames | where { $_ -ne "Position" } - } - - } - - process { - - # Convert to object array and get rid of Common params: - $Parameters = $ParameterDictionary.GetEnumerator() | Where-Object { $__CommonParameterNames -notcontains $_.Key } - - if ($ReplaceAllParameterSets) { - # Get all parameter set names (we need to take any params that are in the __AllParameterSets from New-AccessControlEntry - # and manually add them to all available paramsets so that the __AllParameterSets on the function with these dynamic params - # won't have those params in the __AllParameterSets set): - $__NewAceParameterSetNames = foreach ($Parameter in $Parameters) { - # PSv3 would make this sooooo much easier! We're unpacking all of the parameter set names from ParameterAttribute - # attributes: - foreach ($ParamAttribute in ($Parameter.Value.Attributes | where { $_.TypeId.Name -eq "ParameterAttribute" })) { - $ParamAttribute.ParameterSetName - } - } - - # We're only interested in unique names, and we don't care about the __AllParameterSets name (it will be replaced - # on all of the params) - $__NewAceParameterSetNames = $__NewAceParameterSetNames | - where { $_ -ne [System.Management.Automation.ParameterAttribute]::AllParameterSets } | - select -Unique - } - - - # Create the dictionary that this scriptblock will return: - $DynParamDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary - - foreach ($Parameter in $Parameters) { - - $AttribColl = New-Object System.Collections.ObjectModel.Collection[System.Attribute] - - $Parameter.Value.Attributes | ForEach-Object { - $CurrentAttribute = $_ - $AttributeTypeName = $_.TypeId.FullName - - switch ($AttributeTypeName) { - "System.Management.Automation.ArgumentTypeConverterAttribute" { -# Ignore this; can't create a new one; -# does it get auto generated? - return # So blank param doesn't get added - } - - "System.Management.Automation.AliasAttribute" { -# # Create a new alias attribute: -# $NewParamAttribute = New-Object $AttributeTypeName $CurrentAttribute.AliasNames - # Since this won't get changed, there shouldn't be problem using the reference to the original - if ($AllowAliases) { - $AttribColl.Add($CurrentAttribute) - } - } - - "System.Management.Automation.ValidateSetAttribute" { - # Can't create a new one; will this work? - $NewParamAttribute = $CurrentAttribute - $AttribColl.Add($NewParamAttribute) - - } - - "System.Management.Automation.ParameterAttribute" { - - if ($ReplaceAllParameterSets -and $CurrentAttribute.ParameterSetName -eq [System.Management.Automation.ParameterAttribute]::AllParameterSets) { - $ParameterSets = $__NewAceParameterSetNames - } - else { - $ParameterSets = $CurrentAttribute.ParameterSetName - } - - foreach ($ParamSetName in $ParameterSets) { - - $NewParamAttribute = New-Object System.Management.Automation.ParameterAttribute - - foreach ($PropName in $__WritableParamAttributePropertyNames) { - if ($NewParamAttribute.$PropName -ne $CurrentAttribute.$PropName) { - # nulls cause an error if you assign them to some of the properties - $NewParamAttribute.$PropName = $CurrentAttribute.$PropName - } - } - - if ($RemoveMandatoryAttribute) { - $NewParamAttribute.Mandatory = $false - } - $NewParamAttribute.ParameterSetName = $ParamSetName - - $AttribColl.Add($NewParamAttribute) - } - } - - default { - # I think the type converter was what was giving me the problems. This can probably be - # where everything except the parameterattribute and the type converter go, and the attribute - # can be added to the collection untouched - Write-Warning "don't handle dynamic param copying for $AttributeTypeName" - return - } - } - - } - - $CurrentType = $Parameter.Value.ParameterType - $ParameterType = $CurrentType - - if ($ConvertTypesToArrays) { - # Make sure that the param type is an array: - - if (($CurrentType -ne [switch]) -and (-not $CurrentType.IsArray)) { - # Might need to add more types to not attempt this on - $NewType = ("{0}[]" -f $CurrentType.FullName) -as [type] - - if ($NewType) { - $ParameterType = $NewType - } - } - } - - $DynamicParameter = New-Object System.Management.Automation.RuntimeDefinedParameter ( - $Parameter.Key, - $ParameterType, - $AttribColl - ) - $DynParamDictionary.Add($Parameter.Key, $DynamicParameter) - } - - # Return the dynamic parameters - $DynParamDictionary - - } - -} - -function GetAceString { -<# --Confirm and -WhatIf params use this to get a friendly description for an ACE. - -This needs to be changed to use New-AdaptedAcl or the function should be removed, and -any functions that depend on it can use New-AdaptedAcl -#> - - [CmdletBinding()] - param( - [Parameter(Mandatory=$true, ValueFromPipeline=$true)] - $Ace - ) - - process { - # Get identity reference: - $UnknownAccountString = "Unknown Account" - if ($Ace.IdentityReference -ne $null) { - $IdentityReference = $Ace.IdentityReference - } - elseif ($Ace.SecurityIdentifier -ne $null) { - $IdentityReference = $Ace.SecurityIdentifier - } - else { - $IdentityReference = $UnknownAccountString - } - - if ($IdentityReference -is [System.Security.Principal.SecurityIdentifier]) { - try { - $IdentityReference = $IdentityReference.Translate([System.Security.Principal.NTAccount]) - } - catch { - $IdentityReference = "$UnknownAccountString ($IdentityReference)" - } - } - - # Get ACE type: - if ($Ace.AceType -ne $null) { - $AceType = $Ace.AceType - } - elseif ($Ace.AuditFlags -ne $null) { - $AceType = [System.Security.AccessControl.AceType]::SystemAudit - } - else { - # Last ditch effort: - $PropertyName = $Ace | Get-Member -MemberType Property -Name *Type | select -First 1 -ExpandProperty Name - $AceType = $Ace.$PropertyName - } - - # Get access mask: - if ($Ace.AccessMask) { - $AccessMask = $Ace.AccessMask - } - else { - # Last ditch effort: - $PropertyName = $Ace | Get-Member -MemberType Property -Name *Rights | select -First 1 -ExpandProperty Name - $AccessMask = $Ace.$PropertyName - } - - # Return output: - "{0} {1} {2}" -f $AceType, $IdentityReference, $AccessMask - } -} - -function InvokeCommonAclMethod { -<# -Used for RemoveAccessRule, RemoveAccessRuleSpecific, AddAccessRule, AddAuditRule on -the Get-SD objects. - -No param validation, so make sure the caller knows what's going on. -#> - [CmdletBinding()] - param( - $Rule, - $Acl, - $MethodName - ) - - process { - - if ($Acl -eq $null) { - return - } - - if ($Rule.GetType().FullName -ne "System.Security.AccessControl.CommonAce") { - # We need a CommonAce object for this to work - try { - $Rule = $Rule | ConvertToCommonAce -ErrorAction Stop - } - catch { - Write-Error $_ - return - } - } - - if ($Rule.AceType -match "AccessAllowed(Object)?") { - $AceType = [System.Security.AccessControl.AccessControlType]::Allow - } - elseif ($Rule.AceType -match "AccessDenied(Object)?") { - $AceType = [System.Security.AccessControl.AccessControlType]::Deny - } - elseif ($Rule.AceType -match "SystemAudit(Object)?") { - $AceType = $Rule.AuditFlags # Misnamed, but this will still work - } - else { - Write-Error ("Unknown ACE type: {0}" -f $Rule.AceType) - return - } - - # The methods (and their overloads) all have the same - # first five arguments: - $Arguments = @( - $AceType, - $Rule.SecurityIdentifier, - $Rule.AccessMask, - $Rule.InheritanceFlags, - $Rule.PropagationFlags - ) - - if ($Rule.AceType -match "Object$") { - # Methods overloads for object ACEs have extra arguments: - $Arguments += $Rule.ObjectAceFlags - $Arguments += $Rule.ObjectAceType - $Arguments += $Rule.InheritedObjectAceType - } - - Write-Debug "Invoking $MethodName" - $Acl.$MethodName.Invoke($Arguments) - } -} - -function CustomShouldProcess { -<# -Function that attempts to mimic $PsCmdlet.ShouldProcess(). There is a common scenario using this module -where I haven't figure out a way to get $PsCmdlet.ShouldProcess() to work propertly. Here it is: - - Set-SecurityDescriptor has a confirm impact of 'High' so that it will always prompt before saving - a security descriptor (unless, of course, the -Force or -Confirm:$false parameters are passed) - - Add-Ace, Remove-Ace, Disable/Enable-AclInheritance, Set-Owner, etc, all have an -Apply and -PassThru - parameter, and they can all take more than one object as input that need an SD modified. Those functions - have a ConfirmImpact of 'Medium' - - When you call one of those with more than one object w/o -Force or -Confirm:$false, and the -Apply parameter - is specified (or implied b/c of input object type), Set-SecurityDescriptor causes a prompt (which is good). - The problem is that a YesAll or NoAll selection at the prompt will not work (you'll be prompted every time). - That's annoying when you have ten or so SDs to modify, but it becomes absolutely unworkable when you try to - do tens or hundreds of SDs. I originally tried to get around this by having all SDs saved until the end {} - block, but that creates a limit on the number of SDs you can handle (even if it would be very difficult to - find that limit). Also, a single terminating error would mean that none of the SDs would be applied. - -I'm probably just missing something when it comes to $PsCmdlet.ShouldProcess(), so for now, this function is -an attempt to handle the issue. I want Set-SecurityDescriptor to prompt, but I don't want the modfication functions -to prompt (unless they're trying to apply). -#> - [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="Medium")] - param( - [Parameter(Mandatory=$true)] - [string] $Action, - [Parameter(Mandatory=$true)] - [string] $Target, - [Parameter(Mandatory=$true)] - [ref] $__DefaultReturn, - [Parameter(Mandatory=$true)] - [ref] $__CustomConfirmImpact - ) - - $Message = "Performing the operation `"{0}`" on target `"{1}`"." -f $Action, $Target - - if ($WhatIfPreference) { - Write-Host "What if: $Message" - return $false - } - elseif ($ConfirmPreference -eq "None") { - # -Confirm was passed with $false - return $true - } - elseif ($__CustomConfirmImpact.Value.value__ -ge $ConfirmPreference) { - - $YesChoice = New-Object System.Management.Automation.Host.ChoiceDescription ( - "&Yes", - "Continue with only the next step of the operation." - ) - $YesToAllChoice = New-Object System.Management.Automation.Host.ChoiceDescription ( - "Yes to &All", - "Continue with all the steps of the operation." - ) - $NoChoice = New-Object System.Management.Automation.Host.ChoiceDescription ( - "&No", - "Skip this operation and proceed with the next operation" - ) - $NoToAllChoice = New-Object System.Management.Automation.Host.ChoiceDescription ( - "No to A&ll", - "Skip this operation and all subsequent operations." - ) - $SuspendChoice = New-Object System.Management.Automation.Host.ChoiceDescription ( - "&Suspend", - 'Pause the current pipeline and return to the command prompt. Type "exit" to resume the pipeline' - ) - - $Choices = [System.Management.Automation.Host.ChoiceDescription[]] @( - $YesChoice, - $YesToAllChoice, - $NoChoice, - $NoToAllChoice, - $SuspendChoice - ) - - do { - $Result = $Host.UI.PromptForChoice("Confirm", "Are you sure you want to perform this action?`n${Message}", $Choices, 0) - - switch ($Result) { - 1 { - # Yes to All - $__CustomConfirmImpact.Value = [System.Management.Automation.ConfirmImpact]::None - $__DefaultReturn.Value = $true - } - { 0, 1 -contains $_ } { - # One of the Yes answers - return $true - } - 3 { - # No to All - $__CustomConfirmImpact.Value = [System.Management.Automation.ConfirmImpact]::None - $__DefaultReturn.Value = $false - } - - { 2, 3 -contains $_ } { - # One of the No ansers - return $false - } - 4 { $Host.EnterNestedPrompt() } - } - } while ($Result -ge 4) # Loop until one of the first 4 choices is made - } - else { - return $__DefaultReturn.Value - } -} - -function GetSdString { -<# -Used to get a ShouldProcess action string of what an SD object contains -#> - [CmdletBinding()] - param( - [Parameter(ValueFromPipeline=$true)] - $SDObject, - [PowerShellAccessControl.PInvoke.SecurityInformation] $SecurityInformation - ) - - process { - $OutputString = "" - - if (-not $PSBoundParameters.ContainsKey("SecurityInformation")) { - # $SecurityInformation wasn't supplied, so assume all SD parts will be listed - # (If an Audit section isn't present, that will be removed next) - $SecurityInformation = [PowerShellAccessControl.PInvoke.SecurityInformation]::All - - if ($SDObject.SecurityDescriptor.ControlFlags -and (-not $SDObject.AuditPresent)) { - # So, if there is a ControlFlags property (there wouldn't be on a Get-Acl object), and a - # SACL isn't present, make sure the $SecurityInformation doesn't say to look for it. - - $SecurityInformation = $SecurityInformation -bxor [PowerShellAccessControl.PInvoke.SecurityInformation]::Sacl - } - } - - if ($SDObject.DaclProtectionDirty -and ($SecurityInformation -band [PowerShellAccessControl.PInvoke.SecurityInformation] "ProtectedDacl, UnprotectedDacl")) { - $OutputString += "`n{0}`n" -f $SDObject.DaclProtectionDirty - } - if ($SDObject.SaclProtectionDirty -and ($SecurityInformation -band [PowerShellAccessControl.PInvoke.SecurityInformation] "ProtectedSacl, UnprotectedSacl")) { - $OutputString += "`n{0}`n" -f $SDObject.SaclProtectionDirty - } - - if ($SecurityInformation -band [PowerShellAccessControl.PInvoke.SecurityInformation]::Owner) { - $OutputString += "`nOwner: {0}`n" -f $SDObject.Owner - } - if ($SecurityInformation -band [PowerShellAccessControl.PInvoke.SecurityInformation]::Group) { - $OutputString += "`nGroup: {0}`n" -f $SDObject.Group - } - if ($SecurityInformation -band [PowerShellAccessControl.PInvoke.SecurityInformation]::ProtectedDacl) { - $OutputString += "`nDACL Inheritance: Disabled`n" - } - if ($SecurityInformation -band [PowerShellAccessControl.PInvoke.SecurityInformation]::UnprotectedDacl) { - $OutputString += "`nDACL Inheritance: Enabled`n" - } - if ($SecurityInformation -band [PowerShellAccessControl.PInvoke.SecurityInformation]::Dacl) { - $OutputString += "`nDACL{1}:`n{0}`n" -f $SDObject.AccessToString, "$(if ($SDObject.DaclProtectionDirty) { ' (NOT ACCURATE UNTIL DESCRIPTOR APPLIED)' } else { '' })" - } - if ($SecurityInformation -band [PowerShellAccessControl.PInvoke.SecurityInformation]::ProtectedSacl) { - $OutputString += "`nSACL Inheritance: Disabled`n" - } - if ($SecurityInformation -band [PowerShellAccessControl.PInvoke.SecurityInformation]::UnprotectedSacl) { - $OutputString += "`nSACL Inheritance: Enabled`n" - } - if ($SecurityInformation -band [PowerShellAccessControl.PInvoke.SecurityInformation]::Sacl) { - $OutputString += "`nSACL{1}:`n{0}`n" -f $SDObject.AuditToString, "$(if ($SDObject.SaclProtectionDirty) { ' (NOT ACCURATE UNTIL DESCRIPTOR APPLIED)' } else { '' })" - } - - $OutputString - } -} - -function GetSchemaObject { -<# -This uses an ADSI searcher to lookup DS class objects and properties. It's called once to get a list of all -of them. The function's output is a custom object with the guid, several name properties (the DisplayName -is what will be used in the hash table used for caching), the PropertySet GUID (if the object is an -attributeSchema and it belongs to a PropertySet). -#> - [CmdletBinding()] - param( - [Alias('Class')] - [ValidateSet("attributeSchema","classSchema")] - [string[]] $ObjectClass = ("attributeSchema","classSchema"), - [guid[]] $SchemaIdGuid, - [string[]] $Name, - [string[]] $AdminDisplayName, - [string[]] $LdapDisplayName, - [Alias('PropertySetGuid')] - [guid[]] $AttributeSecurityGuid - ) - - Write-Debug "$($MyInvocation.MyCommand): Entering function; searching for $ObjectClass objects" - - $__CommonParameterNames = [System.Runtime.Serialization.FormatterServices]::GetUninitializedObject([type] [System.Management.Automation.Internal.CommonParameters]) | - Get-Member -MemberType Properties | - Select-Object -ExpandProperty Name - - $Properties = echo Name, ObjectClass, SchemaIdGuid, LdapDisplayName, adminDisplayName, attributeSecurityGUID - - if (-not $PSBoundParameters.ContainsKey("ObjectClass")) { - # If object class wasn't specified via parameters, add the default value so loop - # below will add it to the filter - $PSBoundParameters.Add("ObjectClass", $ObjectClass) - } - - $FilterConditions = @() - - foreach ($Parameter in $PSBoundParameters.GetEnumerator()) { - # Ignore common params: - if ($__CommonParameterNames -contains $Parameter.Key) { continue } - - $CurrentSegment = @() - foreach ($Value in $Parameter.Value) { - if ($Value -is [guid]) { - # Guids need to be transformed into ldap filter format - $Value = -join ($Value.ToByteArray() | foreach { "\{0:x2}" -f $_ }) - } - - $CurrentSegment += "({0}={1})" -f $Parameter.Key, $Value - } - - if ($CurrentSegment.Count -gt 1) { - $StringFormat = "(|{0})" - } - else { - $StringFormat = "{0}" - } - - $FilterConditions += $StringFormat -f (-join $CurrentSegment) - } - - if ($FilterConditions.Count -gt 1) { - $StringFormat = "(&{0})" - } - else { - $StringFormat = "{0}" - } - - $LdapFilter = $StringFormat -f (-join $FilterConditions) - - Write-Debug "$($MyInvocation.MyCommand): LdapFilter = $LdapFilter" - - # Create a DirectorySearcher object: - $RootDSE = [adsi] "LDAP://RootDSE" - $SchemaNamingContext = [adsi] ("LDAP://{0}" -f $RootDSE.schemaNamingContext.Value) - - $Searcher = New-Object adsisearcher ($SchemaNamingContext, $LdapFilter, $Properties) - $Searcher.PageSize = 1000 - - $FoundResult = $false - try { - foreach ($Result in $Searcher.FindAll()) { - if ($null -eq $Result) { - break - } - $FoundResult = $true - - $DisplayNameProp = "LdapDisplayName" - #$DisplayNameProp = "AdminDisplayName" -<# -AdminDisplayName is prettier, but LdapDisplayName is required for ObjectClass property off of AD -objects to be able to be looked up properly. Possible to make yet another hash table that keeps -up with objects whose LdapDisplayName and AdminDisplayName don't match, and that can be checked -if necessary... -#> - - if ($Result.Properties.Item($DisplayNameProp)) { - $DisplayName = $Result.Properties.Item($DisplayNameProp)[0] - } - else { - $DisplayName = $Result.Properties.Item("Name")[0] - } - - $Props = @{ - Name = $Result.Properties.Item("Name")[0] - SchemaIdGuid = [guid] $Result.Properties.Item("SchemaIdGuid")[0] - ObjectClass = $Result.Properties.Item("ObjectClass")[$Result.Properties.Item("ObjectClass").Count - 1] - DisplayName = $DisplayName - AdminDisplayName = $Result.Properties.Item("AdminDisplayName")[0] - LdapDisplayName = $Result.Properties.Item("lDAPDisplayName")[0] - } - - # Property, so it could belong to a propertyset - if ($Props.ObjectClass -eq "attributeSchema") { - try { - $Props.PropertySet = [guid] $Result.Properties.Item("attributeSecurityGUID")[0] - } - catch { - # Probably blank, so no propertyset - } - } - - New-Object PSObject -Property $Props - } - $Searcher.Dispose() - $SchemaNamingContext.Dispose() - $RootDSE.Dispose() - } - catch { - throw $_ - } - - if (-not $FoundResult) { - Write-Error "Couldn't find any schema objects that matched the search criteria" - } - Write-Debug "$($MyInvocation.MyCommand): Exiting function" - -} - -function GetExtendedRight { -<# -Like GetSchemaObject, except it looks in the Extended-Rights configuration container. It will find ExtendedRights, ValidatedWrites, -and PropertySets. Just like that function, custom PSObjects are output, and the function that calls this function will save all objects -to a hash table for faster lookups -#> - [CmdletBinding()] - param( - [guid[]] $AppliesTo, - [guid[]] $RightsGuid, - [string[]] $Name, - [string[]] $DisplayName, - [ValidateSet("Self", "ExtendedRight", "ReadProperty,WriteProperty")] - [string[]] $ValidAccesses - ) - - Write-Debug "$($MyInvocation.MyCommand): Entering function; searching for $ValidAccesses" - - $__CommonParameterNames = [System.Runtime.Serialization.FormatterServices]::GetUninitializedObject([type] [System.Management.Automation.Internal.CommonParameters]) | - Get-Member -MemberType Properties | - Select-Object -ExpandProperty Name - - $Properties = echo appliesTo, rightsGuid, DisplayName, validAccesses, Name - - $FilterConditions = @() - - foreach ($Parameter in $PSBoundParameters.GetEnumerator()) { - - if ($__CommonParameterNames -contains $Parameter.Key) { continue } - $CurrentSegment = @() - foreach ($Value in $Parameter.Value) { - if ($Parameter.Key -eq "ValidAccesses") { - # Valid accesses gets special handling: - $Value = ([PowerShellAccessControl.ActiveDirectoryRights]$Value).value__ - } - $CurrentSegment += "({0}={1})" -f $Parameter.Key, $Value - } - - if ($CurrentSegment.Count -gt 1) { - $StringFormat = "(|{0})" - } - else { - $StringFormat = "{0}" - } - - $FilterConditions += $StringFormat -f (-join $CurrentSegment) - } - - if ($FilterConditions.Count -eq 0) { - $FilterConditions += "(name=*)" - } - - if ($FilterConditions.Count -gt 1) { - $StringFormat = "(&{0})" - } - else { - $StringFormat = "{0}" - } - - $LdapFilter = $StringFormat -f (-join $FilterConditions) - - Write-Debug "$($MyInvocation.MyCommand): LdapFilter = $LdapFilter" - - # Create a DirectorySearcher object: - $RootDSE = [adsi] "LDAP://RootDSE" - $ExtendedRights = [adsi] ("LDAP://CN=Extended-Rights,{0}" -f $RootDSE.ConfigurationNamingContext.Value) - $Searcher = New-Object adsisearcher ($ExtendedRights, $LdapFilter, $Properties) - $Searcher.PageSize = 1000 - - $FoundResult = $false - try { - foreach ($Result in $Searcher.FindAll()) { - if ($null -eq $Result) { - break - } - $FoundResult = $true - - New-Object PSObject -Property @{ - DisplayName = $Result.Properties.Item("DisplayName")[0] - Name = $Result.Properties.Item("Name")[0] - RightsGuid = [guid] $Result.Properties.Item("RightsGuid")[0] - ValidAccesses = $Result.Properties.Item("ValidAccesses")[0] - appliesTo = [guid[]] ($Result.Properties.Item("appliesTo") | % { $_ }) - } - } - $Searcher.Dispose() - $ExtendedRights.Dispose() - $RootDSE.Dispose() - } - catch { - throw $_ - } - - if (-not $FoundResult) { - Write-Error "Couldn't find any extended rights that matched the search criteria" - } - - Write-Debug "$($MyInvocation.MyCommand): Exiting function" -} - -function ConvertGuidToName { -<# -Helper function that allows GUID to name translation, and also the ability to list all relevant -schema objects (ClassObjects, PropertySets, Properties, ValidatedWrites, ExtendedRights). - -Get-ADObjectAce uses the -ListAll in the dynamicparam{} block when one of the switches is used. - -This function is also responsible for populating the hash table(s) used for quick lookup. When the -function is called, the $Type param is used to determine which hash table(s) is checked. If the -table has no data, the GetSchemaObject and/or GetExtendedRights functions are called to populate -it. -#> - [CmdletBinding()] - param( - [Parameter(Mandatory=$true, ParameterSetName="ListAll")] - [switch] $ListAll, - [Parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName="Lookup")] - [guid] $Guid, - [Parameter(Mandatory=$true)] - [ValidateSet( - "ValidatedWrite", - "ExtendedRight", - "Property", - "PropertySet", - "ClassObject" - )] - [string] $Type, - # Can be used to limit -ListAll results for extended rights - [guid[]] $AppliesTo - ) - - begin { -# Write-Debug "$($MyInvocation.MyCommand): Entering function; searching for $Type" - - # Grab the proper caching hash table: - $HashTable = Get-Variable -Scope Script -Name "__Ds${Type}Table" -ValueOnly - - # Check to see if table has been populated. If not, populate it: - if ($HashTable.Count -eq 0) { - Write-Debug "$($MyInvocation.MyCommand): Populating $Type table..." - Write-Progress -Activity "Populating $Type table" -Status "Progress:" -Id 1 -PercentComplete 50 - - # Figure out the function and parameters to run: - $Params = @{} - switch ($Type) { - { "ValidatedWrite","ExtendedRight","PropertySet" -contains $_ } { - $FunctionName = "GetExtendedRight" - $KeyPropertyName = "RightsGuid" - if ($PSBoundParameters.ContainsKey("AppliesTo")) { - $Params.AppliesTo = $AppliesTo - } - } - ValidatedWrite { - $Params.ValidAccesses = "Self" - } - - ExtendedRight { - $Params.ValidAccesses = "ExtendedRight" - } - - PropertySet { - $Params.ValidAccesses = "ReadProperty,WriteProperty" - } - - { "Property","ClassObject" -contains $_ } { - $FunctionName = "GetSchemaObject" - $KeyPropertyName = "SchemaIdGuid" - } - - ClassObject { - $Params.ObjectClass = "classSchema" - } - - Property { - $Params.ObjectClass = "attributeSchema" - } - - default { - throw "Unknown param set!" - } - } - - try { - & $FunctionName @Params | ForEach-Object { - try { - $Value = $_.DisplayName -replace "\s","-" - $HashTable.Add($_.$KeyPropertyName, $Value) - } - catch { - Write-Warning ("Duplicate ${Type}: {0}" -f $_.$ValuePropertyName) - } - - if ($_.PropertySet) { - $__DsPropertyToPropertySetTable.Add($_.$KeyPropertyName, $_.PropertySet) - } - } - } - catch { - throw $_ - } - finally { - Write-Progress -Activity Done -Status "Progress:" -Id 1 -Completed - } - } - - } - process { - switch ($PSCmdlet.ParameterSetName) { - Lookup { - - if ($HashTable.ContainsKey($Guid)) { - New-Object PSObject -Property @{ - Guid = $Guid - Name = $HashTable[$Guid] - Type = $Type - } - } - else { - Write-Error "Unknown ${Type} GUID: $Guid" - } - } - - ListAll { - $HashTable.GetEnumerator() | select @{N="Guid"; E={$_.Key}}, @{N="DisplayName"; E={$_.Value}}, @{N="Type"; E={$Type}} - } - } - - } - - end { -# Write-Debug "$($MyInvocation.MyCommand): Exiting function" - } -} - -function LookupPropertySet { -<# -If given a property, get the propertyset -If given a propertyset, get the properties - -Return is an object where 'Name' property is a property GUID, and -'Value' property is a propertyset GUID - -Hash table is populated at the same time the Property hash table is -populated (inside ConvertGuidToName function) - -Function is used in Get-EffectiveAccess function when ObjectAceType -is used. -#> - [CmdletBinding()] - param( - [Parameter(Mandatory=$true, ParameterSetName="Property")] - $Property, - [Parameter(Mandatory=$true, ParameterSetName="PropertySet")] - $PropertySet - ) - - # If property to propertyset table hasn't been populated, then populate it - if ($__DsPropertyToPropertySetTable.Count -eq 0) { - $null = ConvertGuidToName -ListAll -Type "Property" - } - - switch ($PSCmdlet.ParameterSetName) { - "Property" { - # Filter on name - $FilterProperty = "Name" - } - - "PropertySet" { - # Filter on value - $FilterProperty = "Value" - } - - default { - return - } - } - - $InputValues = $PSBoundParameters.($PSCmdlet.ParameterSetName) - - foreach ($InputValue in $InputValues) { - # Guid form is needed to do lookup from hash table - if ($InputValue -is [PSObject] -and $InputValue.Guid -is [guid]) { - $InputValue = $InputValue.Guid - } - - try { - # Attempt to convert to a GUID (since string GUID may have been passed): - $InputValue = [guid] $InputValue - } - catch { - # Conversion failed, so attempt lookup via Get-ADObjectAceGuid - - $InputValue = Get-ADObjectAceGuid -Name $InputValue -ErrorAction Stop -TypesToSearch $PSCmdlet.ParameterSetName | select -ExpandProperty Guid - } - - - $__DsPropertyToPropertySetTable.GetEnumerator() | where { $InputValue -contains $_.$FilterProperty } - } -} - -function ConvertNameToGuid { -<# -Opposite of ConvertGuidToName. If caching hash tables haven't been populated when the function -is called, ConvertGuidToName is called to populate them. -#> - [CmdletBinding()] - param( - [Parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName="Lookup")] - [string] $Name, - [Parameter(Mandatory=$true)] - [ValidateSet( - "ValidatedWrite", - "ExtendedRight", - "Property", - "PropertySet", - "ClassObject" - )] - [string] $Type - ) - - begin { - # Grab the proper caching hash table: - $HashTable = Get-Variable -Scope Script -Name "__Ds${Type}Table" -ValueOnly - - # Check to see if table has been populated. If not, populate it by calling the -ConvertGuidToName -ListAll and throwing the results - # away (I don't think this should ever happen. This function should really only be called from the Get-SdObjectAceType and - # Get-SdInheritedObjectAceType functions, and they would have already populated the hash tables by calling convertguidtoname.: - if ($HashTable.Count -eq 0) { - $null = ConvertGuidToName -ListAll -Type $Type - } - } - process { - $HashTable.GetEnumerator() | where { $_.Value -match $Name } | select @{N="Guid"; E={[guid] $_.Name }}, @{N="Name"; E={$_.Value}}, @{N="Type";E={$Type}} - } -} - -function GetPermissionString { -<# -Originally used to translate AD rights into friendly strings (Get-EffectiveAccess and -New-AdaptedAcl both had the need to do this, and I didn't want to implement the code -inside each function. I later decided to run all AccessMasks through this function -(it makes the Get-EffectiveAccess code easier to follow). For that reason (originally -for AD), the structure of the function is a little wacky (it basically assumes you're -going to have an ObjectAceType, and if you don't (which you never will for any non-AD -permissions), it still creates some objects assuming you're using AD perms. -#> - - [CmdletBinding()] - param( - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true)] - [Int32] $AccessMask, - [Parameter(ValueFromPipelineByPropertyName=$true)] - [guid] $ObjectAceType, - $AccessMaskEnumeration = [int], - [switch] $ListEffectivePermissionMode, - [switch] $DontTranslateGenericRights - ) - - begin { - - $GenericRightsMask = 0 - [enum]::GetNames([PowerShellAccessControl.GenericAceRights]) | % { $GenericRightsMask = $GenericRightsMask -bor [PowerShellAccessControl.GenericAceRights]::$_.value__ } - - } - - process { - - # Function works off of ObjectAceTypeObject(s). This is geared towards AD permissions, - # but non-AD permissions will work, too. If an ObjectAceType GUID isn't specified, then - # a single ObjectAceTypeObject will be created after the if/else - $ObjectAceTypeObject = $null - if ($ObjectAceType -eq $null -or $ObjectAceType -eq [guid]::Empty) { - $ObjectAceTypeName = "All" - } - else { - try { - $ObjectAceTypeObject = (Get-ADObjectAceGuid -Guid $ObjectAceType -ErrorAction Stop) - } - catch { - $ObjectAceTypeName = $ObjectAceType - } - } - - # ObjectAceType either wasn't specified, or it was a GUID that couldn't be translated. Either - # way, there will be no Type associated with the ObjectAceTypeObject. If this is an AD permission, - # the name will either be 'All' (because the GUID was empty or non-existent, or the unknown GUID - # (because it couldn't be translated) - if ($ObjectAceTypeObject -eq $null) { - $ObjectAceTypeObject = New-Object PSObject -Property @{ - Name = $ObjectAceTypeName - Type = $null - } - } - - $Output = @() - $NontranslatedString = $null - - # Check to see if GenericRights are included in the AccessMask (this works even if there are object - # specific rights mixed in with the generic rights) - if ($AccessMask -band $GenericRightsMask) { - $GenericAccessMask = $AccessMask -band $GenericRightsMask # Remove any object specific rights - $AccessMask = $AccessMask -band (-bnot $GenericRightsMask) # Remove any generic rights - - $GenericAccessMaskDisplay = $GenericAccessMask -as [PowerShellAccessControl.GenericAceRights] - if ($DontTranslateGenericRights -or (-not $__GenericRightsMapping.ContainsKey($AccessMaskEnumeration))) { - $Output += $GenericAccessMaskDisplay -split ", " - } - elseif ($__GenericRightsMapping.ContainsKey($AccessMaskEnumeration)) { - $NontranslatedString = ($GenericAccessMaskDisplay, (GetPermissionString -AccessMask $AccessMask -AccessMaskEnumeration $AccessMaskEnumeration) | where { $_ -ne "None" }) -join ", " - - foreach ($CurrentRight in ($GenericAccessMaskDisplay -split ", ")) { - $AccessMask = $AccessMask -bor $__GenericRightsMapping[$AccessMaskEnumeration].$CurrentRight - } - - } - } - - $Output += foreach ($CurrentObject in $ObjectAceTypeObject) { - # If an ObjectAceType was specified, then the AccessMask needs to be limited depending on the type - # of the GUID. If an ObjectAceType wasn't specified (or if it was, but Get-ADObjectAceGuid couldn't - # translate it), then the default{} block will take over, which won't try to limit the AccessMask - switch ($CurrentObject.Type) { - - ClassObject { - $LimitingPermissions = [PowerShellAccessControl.ActiveDirectoryRights] "CreateChild, DeleteChild" - } - - ExtendedRight { - $LimitingPermissions = [PowerShellAccessControl.ActiveDirectoryRights]::ExtendedRight - } - - { "Property", "PropertySet" -contains $_ } { - $LimitingPermissions = [PowerShellAccessControl.ActiveDirectoryRights] "ReadProperty, WriteProperty" - } - - ValidatedWrite { - $LimitingPermissions = [PowerShellAccessControl.ActiveDirectoryRights]::Self - } - - default { - try { - $LimitingPermissions = ([System.Enum]::GetValues($AccessMaskEnumeration) | select -Unique | sort { $_ -as $AccessMaskEnumeration } -Descending ) -join ", " - } - catch { - # $AccessMaskEnumeration probably wasn't an enum - $LimitingPermissions = $AccessMask - } - } - } - - if ($ListEffectivePermissionMode) { - # Instead of a single limiting value, attempt to split the $LimitingPermissions into - # multiple rights. Those strings will be converted back to ints since they are enumeration - # names - $LimitingPermissions = $LimitingPermissions -split ", " - } - - foreach ($CurrentPermission in $LimitingPermissions) { - if (($CurrentPermission -as $AccessMaskEnumeration) -ne $null) { - # Current permission string can be cast as the enumeration type, so band the provided - # AccessMask with the limiting permission. When the function isn't in 'ListEffectivePermissionMode', - # this is only useful for AD permissions (e.g., ObjectAceType is for a property, but the - # access mask is for 'FullControl'. The ACE would really only give Read/Write property - # permission, so this is where the rest of the FullControl rights would be removed. - # When the function is in 'ListEffectivePermissionMode', this is useful for all ACEs, - # since it will split the enumeration strings up and show which rights the provided - # AccessMask maps to - $ModifiedAccessMask = $AccessMask -band ($CurrentPermission -as $AccessMaskEnumeration) - } - else { - # Couldn't successfully cast to the enum type (which shouldn't happen). Basically, don't - # modify the access mask - $ModifiedAccessMask = $AccessMask - } - - if ($ListEffectivePermissionMode) { - # The modified access mask listed above might not provide the permission specified by - # $CurrentPermission. For that reason, always list the $CurrentPermission as the - # display access mask in this mode - $DisplayAccessMask = $CurrentPermission -as $AccessMaskEnumeration - } - else { - # Modified access mask will be translated to the display access mask - $DisplayAccessMask = $ModifiedAccessMask - } - - # Recast the int value back into the enum string(s) - $AccessString = $DisplayAccessMask -as $AccessMaskEnumeration - - if ($AccessMaskEnumeration -eq [PowerShellAccessControl.ActiveDirectoryRights]) { - # AD rights may be heavily modified, so there's some extra work to do - $ObjectName = $CurrentObject.Name - $ObjectType = $CurrentObject.Type - - if ($CurrentObject.Type -eq $null) { - $AccessString = $AccessString -replace "Self", "Perform $ObjectName ValidatedWrite" - $AccessString = $AccessString -replace "ExtendedRight", "Perform $ObjectName ExtendedRight" - $AccessString = $AccessString -replace "\b(\w*)(Child|Property)\b", ('$1 {0} $2' -f $ObjectName) - $AccessString = $AccessString -replace "($ObjectName) Child", '$1 ChildObject' - - if ($ObjectName -eq "All") { - $AccessString = $AccessString -replace "(ValidatedWrite|ExtendedRight|ChildObject)", '$1s' - $AccessString = $AccessString -replace ("({0}) Property" -f $CurrentObject.Name), '$1 Properties' - } - elseif ($ObjectName -as [guid]) { - # Valid Guid with $null Type means that this is some unknown ObjectAceType - $AccessString = $AccessString += " (Unknown ObjectAceType $ObjectName)" - } - } - else { - $AccessString = $AccessString -replace "Self|ExtendedRight", "Perform" - $AccessString = $AccessString -replace "Property|Child", "" - $AccessString = $AccessString -replace ",", " and" - - $AccessString = "{0} {1} {2}" -f $AccessString, $ObjectName, $ObjectType - } - } - - if ($ListEffectivePermissionMode) { - New-Object PSObject -Property @{ - Allowed = [bool] ($ModifiedAccessMask -eq ($CurrentPermission -as $AccessMaskEnumeration)) - Permission = $AccessString - } - } - elseif ($ModifiedAccessMask -ne 0) { - # Return the access string - $AccessString - } - - # Nothing returned if modified access mask is 0 and not in ListEffectivePermissionMode - } - } - - if ($ListEffectivePermissionMode) { - $Output - } - else { - - # Previous foreach() loop usually only runs once. There are some GUIDs that can be - # interpreted as more than one type (bf9679c0-0de6-11d0-a285-00aa003049e2 is a - # property and a validated write), so it might have run more than once. In that - # scenario, there may be more than one string that was returned. - if (-not $Output) { $Output = "None" } - $Output = $Output -join ", " - - if ($NontranslatedString) { - $Output = "$Output ($NontranslatedString)" - } - - $Output - } - } -} - -function New-AdaptedAcl { -<# -Takes as input either an adapted SD object (from New-AdaptedSecurityDescriptor) (-SDObject parameter), or a collection -of access control entries (-Ace and -AccessMaskEnum parameters). - -Returns as output a collection of CommonAce or ObjectAce objects that have extra properties added. - -There is currently one issue that needs to be fixed: the AceType may be wrong on each object that comes out. That happens -with ObjectAces and/or dynamic access control CallbackAces. The AceType is overwritten with either AccessAllowed, AccessDenied, -or SystemAudit. This happens so that the "adapted" ACE can be piped into New-AccessControlEntry, Add-AccessControlEntry, -Remove-AccessControlEntry, etc. I might try to just overwrite the ToString() method of the AceType in the future - -By default, generic access rights are translated to object specific access rights. That behavior can be suppressed by using -the -DontTranlsateGenericRights switch. - -If the -GetInheritanceSource switch is used, inheritance source information will be checked using P/Invoke. -#> - - # Default set to handle empty ACL coming through - [CmdletBinding(DefaultParameterSetName="CommonAceObjects")] - param( - # Arrays of these *can* come through, but function doesn't handle that since it's a function - # that should only be called internally - [Parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName="BySD")] - [ValidateScript({ - $_.pstypenames -contains $__AdaptedSecurityDescriptorTypeName - })] - $SDObject, - [Parameter(ParameterSetName="BySD")] - # Include discretionary ACL in output - [switch] $Dacl, - [Parameter(ParameterSetName="BySD")] - # Include system ACL (if present) in output - [switch] $Sacl, - [switch] $DontTranslateGenericRights, - [Parameter(ParameterSetName="BySD")] - [switch] $GetInheritanceSource, - [Parameter(Mandatory=$true, ParameterSetName="ByACE")] - # Useful when there's a single ACE that needs to be converted (should actually work on multiples. This paramset was made for Get-MandatoryIntegrityLevel - $Ace, - [Parameter(ParameterSetName="ByACE")] - $AccessMaskEnum - ) - - process { - $AceObjects = @() - $InheritanceArray = @{} # Used to keep track of inheritance information for each ACL - $GetPrincipalParams = @{} # Used when doing SID translation (not populated when ByACE - # paramset is used) - - switch ($PSCmdlet.ParameterSetName) { - BySD { - - # SID translation will fall back on SdPath and ObjectType if the SID can't be - # translated locally, so fill in the hash table if the following properties - # are available: - if ($SDObject.SdPath) { - $GetPrincipalParams.SdPath = $SDObject.SdPath - } - if ($SDObject.ObjectType) { - $GetPrincipalParams.ObjectType = $SDObject.ObjectType - } - - $AccessMaskEnum = $SDObject.GetAccessMaskEnumeration() - - # If neither -Dacl or -Sacl switch is provided, assume that the DACL is what's - # requested - if ($Dacl -or (-not $Dacl -and -not $Sacl)) { - # Add the discretionary ACL to the - $AceObjects += '$SDObject.SecurityDescriptor.DiscretionaryAcl' - - if ($GetInheritanceSource) { - try { - $InheritanceArray.Access = $SDObject | Get-InheritanceSource -Dacl -ErrorAction Stop - } - catch { - $GetInheritanceSource = $false - } - } - } - - if ($Sacl) { - $AceObjects += '$SDObject.SecurityDescriptor.SystemAcl' - - if ($GetInheritanceSource) { - try { - $InheritanceArray.Audit = $SDObject | Get-InheritanceSource -Sacl -ErrorAction Stop - } - catch { - $GetInheritanceSource = $false - } - } - } - } - - ByACE { - $AceObjects += '$Ace' - } - - default { - return - } - } - - if ($AccessMaskEnum -eq $null) { - # Numeric AccessMasks are cast to this type via -as in several places, so a null variable - # won't work. If one wasn't supplied, just make the type [int] so that the AccessMask - # stays numeric - $AccessMaskEnum = [int] - } - - $LastAceType = $null # Used to keep track of the current ACE number so that Inheritance information - $AceNumber = 0 # can be matched up. These are only used when $GetInheritanceSource is specified, - # and they are reset when the ACE type changes from Access to Audit (so it is - # assumed that the ACEs will come through with like types, i.e., all the Access ACEs - # (Allow or Deny) followed by all the Audit ACEs. That should be a valid - # assumption based on how $AceObjects is created) - - & ([scriptblock]::Create($AceObjects -join "; ")) | Where-Object { $_ } | ForEach-Object { - - $CurrentAce = $_ - - # Make sure the ACE is a supported type: - if ("IntegrityLevel", "CentralAccessPolicy" -contains $CurrentAce.AceType) { - # Special CustomAce types that other functions in this module have put in. These are OK to adapt, - # so no need to exit out with an error - } - elseif ($CurrentAce.AceType -notmatch "^(Access(Allowed|Denied)|SystemAudit)(Callback)?(Object)?$") { - Write-Warning ("{0} ace type not supported!" -f $CurrentAce.AceType) - return # Exit this iteration of ForEach-Object - } - - # Hash table will contain properties that will get added to the CommonAce - <# - Biggest time wasters (sorted): - 1. AccessMaskDisplay - 2. Principal - 3. AceType - - Those together take the time it takes to get an AD object to over a second (not taking anything else in this function into account) - #> - $AdaptedAceProps = @{ - DisplayName = $SDObject.DisplayName - InheritanceString = $SDObject.InheritanceString - Path = $SDObject.Path - Principal = GetPrincipalString -IdentityReference $CurrentAce.SecurityIdentifier @GetPrincipalParams - AccessMaskDisplay = $CurrentAce | GetPermissionString -AccessMaskEnumeration $AccessMaskEnum -DontTranslateGenericRights:$DontTranslateGenericRights - AceType = $CurrentAce.AceType.ToString() -replace "(Callback)?(Object)?$" # All we care about is whether or not ACE is for Allow, Deny or Audit - AppliesTo = $CurrentAce | GetAppliesToMapping - OnlyApplyToThisContainer = [bool] ($CurrentAce.PropagationFlags -band [System.Security.AccessControl.PropagationFlags]::NoPropagateInherit) - } - - if ($GetInheritanceSource) { - # If inheritance source was obtained, there are potentially two lists: one for DACL and one for SACL - # These ACEs are being fed through the pipeline, so the $CurrentAceType and $AceNumber keep track - # of where in the $InheritanceArray.$CurrentAceType we are: - $CurrentAceType = $AdaptedAceProps.AceType -replace "(Allowed$|Denied$|^System)" - - if ($LastAceType -ne $CurrentAceType) { - $AceNumber = 0 - $LastAceType = $CurrentAceType - } - - $AdaptedAceProps.InheritedFrom = $InheritanceArray.$CurrentAceType[$AceNumber].AncestorName -replace "^\\\\\?\\" - } - - # Make sure InheritedFrom property contains something: - if (-not $AdaptedAceProps.InheritedFrom) { - if ($CurrentAce.IsInherited) { - $AdaptedAceProps.InheritedFrom = "Parent Object" - } - else { - $AdaptedAceProps.InheritedFrom = "" - } - } - - # Clear this out in case a previous ACE was an object ACE, so later AD permission check won't show that old info: - $InheritedObjectAceTypeProperties = $null - - # Do more stuff for ObjectAce - if ($CurrentAce.AceType -match "Object$") { - - if ($CurrentAce.ObjectAceFlags -band [System.Security.AccessControl.ObjectAceFlags]::InheritedObjectAceTypePresent) { - try { - $InheritedObjectAceTypeProperties = ConvertGuidToName -Guid $CurrentAce.InheritedObjectAceType -Type ClassObject -ErrorAction Stop - } - catch { - $InheritedObjectAceTypeProperties = New-Object PSObject -Property @{ - Name = $CurrentAce.InheritedObjectAceType - Type = $null - Guid = $CurrentAce.InheritedObjectAceType - } - } - } - - $AdaptedAceProps.InheritedObjectAceTypeDisplayName = $InheritedObjectAceTypeProperties.Name - } - - if ($CurrentAce.AceType -match "Callback") { - $AdaptedAceProps.AccessMaskDisplay += " (CONDITIONAL STATEMENT GOES HERE)" - $AdaptedAceProps.ConditonalBinaryData = $CurrentAce.GetOpaque() - # Still missing a function to convert binary data to a string - } - - # v3 and higher can take the hash table as a parameter to Add-Member, but to stay v2 compliant, - # we'll just loop through each element in the ht and add it to the object to be returned. Also - # add the type name so the formatting system will take over how to display the objects. - $AdaptedAceProps.GetEnumerator() | ForEach-Object { - $CurrentAce | Add-Member -MemberType NoteProperty -Name $_.Name -Value $_.Value -Force - } - - $CurrentAce.pstypenames.Insert(0, $__AdaptedAceTypeName) #Custom typename used for PS formatting and type systems - - # Output ACE object: - $CurrentAce - - # Increment ACE number to keep up with Inheritance information - $AceNumber++ - } - } -} - -function MergeAclEntries { -<# -Use Get-Acl to take a look at c:\windows and HKLM:\SOFTWARE. You'll find multiple entries -for different principals. The access masks are defintely different b/c the ACEs that apply -to children are using generic rights. If you translate those generic rights into specific -rights, you'll have a situation (at least on some of the ACEs) where the access mask, principal, -inheritance source, etc all match. The only things that won't match are the AppliesTo. If all -those other properties match, you can do what the ACL editor GUI does, and only show one ACE -instead of multiple ones (and go ahead and combine the AppliesTo). - -One downside to this: this makes the resulting ACE's InheritanceFlags, PropagationFlags, and/or -AceFlags not necessarily accurate. That's OK as long as you don't try to use the ACEs directly -on a RawSecurityDescriptor or CommonSecurityDescriptor object outside of the module (you can -use the .NET methods on one of the SD objects from this module, or the *-AccessControlEntry -functions just fine). This will work fine as long as you use the ACE(s) with the PAC module -b/c the ACE will be piped to the New-AccessControlEntry, and if the AppliesTo flags are specified -(which they will be if they're piped in), inheritance and propagation are taken from that property -instead of AceFlags property). - -One case this function doesn't currently handle: If everything is the same except the AccessMask, e.g., -two ACEs share everything, including the AppliesTo, then we should be able to combine the AccessMasks -and return a single ACE. That's pretty rare, and it'll just have to wait for a future release. -#> - [CmdletBinding()] - param( - [Parameter(Mandatory=$true, ValueFromPipeline=$true)] - $Ace - ) - - begin { - $PropertiesToGroupBy = @( - "AceType" - "SecurityIdentifier" - {$_.AccessMaskDisplay -replace "\s\(.*\)$" } # Get rid of any parenthesis from Generic rights translations - "IsInherited" - "OnlyApplyToThisContainer" - "AuditFlags" # Doesn't affect grouping access rights; this is a CommonAce property - "ObjectAceType" # Since it will be null if this is an ACE that doesn't contain this property, shouldn't affect grouping of normal non-object ACEs - "InheritedObjectAceType" # Since it will be null if this is an ACE that doesn't contain this property, shouldn't affect grouping of normal non-object ACEs - "InheritedFrom" - ) - - $CollectedAces = @() - } - - process { - # Function needs to collect all input first - $CollectedAces += $Ace - } - - end { - Write-Debug "$($MyInvocation.MyCommand): Starting to merge ACEs" - - # Group on the collected ACEs, then output them - $CollectedAces | Group-Object $PropertiesToGroupBy -Debug:$false | - # Most of the time, each group is going to have one item (which means no ACEs were grouped). When ACEs were grouped, - # the AppliesTo properties will almost certainly be different. Also, it's possible for the AccessMasks to be different - # (if one of the ACEs used generic rights that were translated in the __Permissions string, and the other used - # object specific/standard rights, then the AccessMask could be different). For that reason, those two properites will - # be combined from all objects in the group, and then the first item in the group will have those two properties updated, - # and they will be sent out into the world: - ForEach-Object { - if ($_.Count -gt 1) { - - $NewAppliesTo = $NewAccessMask = 0 - $NewAccessMaskDisplay = @() - - $_.Group | ForEach-Object -Process { - $NewAppliesTo = $NewAppliesTo -bor $_.AppliesTo.value__ - $NewAccessMask = $NewAccessMask -bor $_.AccessMask - $NewAccessMaskDisplay += ($_.AccessMaskDisplay -replace "\s\(.*\)$") -split ", " - } - - $_.Group[0] | - Add-Member -MemberType NoteProperty -Name AppliesTo -Force -PassThru -Value ($NewAppliesTo -as [PowerShellAccessControl.AppliesTo]) | - Add-Member -MemberType NoteProperty -Name AccessMask -Force -PassThru -Value $NewAccessMask | - Add-Member -MemberType NoteProperty -Name AccessMaskDisplay -Force -PassThru -Value (($NewAccessMaskDisplay | select -Unique) -join ", ") - } - else { - # Just output the only element: - $_.Group[0] - } - } - } -} - -function Get-InheritanceSource { -<# -Uses WinApi to get ACE inheritance source -#> - [CmdletBinding()] - param( - [Parameter(Mandatory=$true, ValueFromPipeline=$true)] - $SDObject, - [switch] $Dacl, - [switch] $Sacl - ) - - begin { - # If neither switch was passed, act like Dacl was: - if (-not ($PSBoundParameters.ContainsKey("Dacl") -or $PSBoundParameters.ContainsKey("Sacl"))) { - $PSBoundParameters.Add("Dacl", $true) - } - - # Each InheritArray entry takes up this much space (used to determine memory allocation, and to walk - # the pointer - $EntrySize = [System.Runtime.InteropServices.Marshal]::SizeOf([type][PowerShellAccessControl.PInvoke.InheritArray]) - } - - process { - foreach ($AclType in "Dacl","Sacl") { - if (-not $PSBoundParameters.$AclType) { - continue - } - - if ($AclType -eq "Dacl") { - $Acl = $SDObject.SecurityDescriptor.DiscretionaryAcl - } - else { - $Acl = $SDObject.SecurityDescriptor.SystemAcl - } - - if ($null -eq $Acl) { - Write-Debug "$AclType is null" - continue - } - - # Get binary ACL form: - $AclBytes = New-Object byte[] $Acl.BinaryLength - $Acl.GetBinaryForm($AclBytes, 0) - - if ($__GenericRightsMapping.ContainsKey($SDObject.GetAccessMaskEnumeration())) { - $GenericMapping = $__GenericRightsMapping[$SDObject.GetAccessMaskEnumeration()] - } - else { - Write-Error "Missing generic mapping for type [$($SDObject.GetAccessMaskEnumeration().FullName)]" - continue - } - - [guid[]] $GuidArray = @() - if ($SDObject.DsObjectClass) { - # This is an AD object, so we need the guid for the call to GetInheritanceSource - [guid[]] $GuidArray = Get-ADObjectAceGuid -Name ("^{0}$" -f $SDObject.DsObjectClass) -TypesToSearch ClassObject | select -first 1 -exp Guid - } - - Write-Debug ("{0}: Calling GetInheritanceSource() for $AclType on {1}" -f $MyInvocation.MyCommand, $SDObject.DisplayName) - try { - # Allocate memory for the InheritArray return array (one for each ACE) - $InheritArray = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($Acl.Count * $EntrySize) - - if ($AclType -eq "Sacl") { - # Make sure SeSecurityPrivilege is enabled - $SecurityPrivResults = SetTokenPrivilege -Privilege SeSecurityPrivilege - } - else { - $SecurityPrivResults = $null - } - - [PowerShellAccessControl.PInvoke.advapi32]::GetInheritanceSource( - $SDObject.SdPath, # ObjectName - $SDObject.ObjectType, # ObjectType - [PowerShellAccessControl.PInvoke.SecurityInformation]::$AclType, # SecurityInfo - $SDObject.SecurityDescriptor.IsContainer, # Container - [ref] $GuidArray, # ObjectClassGuids - $GuidArray.Count, # GuidCount - $AclBytes, # Acl - [System.IntPtr]::Zero, # pfnArray (must be null) - [ref] $GenericMapping, # GenericMapping - $InheritArray # InheritArray (return) - - ) | CheckExitCode -Action "Getting $AclType inheritance source for '$($SDObject.SdPath)'" -ErrorAction Stop - - try { - $Ptr = $InheritArray.ToInt64() - for ($i = 0; $i -lt $Acl.Count; $i++) { - - $Struct = [System.Runtime.InteropServices.Marshal]::PtrToStructure($Ptr, [type] [PowerShellAccessControl.PInvoke.InheritArray]) - $Ptr += $EntrySize - - New-Object PSObject -Property @{ - AceNumber = $i - GenerationGap = $Struct.GenerationGap - AncestorName = $Struct.AncestorName - } - } - } - catch { - Write-Error $_ - continue - } - finally { - # Make sure InheritArray is freed: - [PowerShellAccessControl.PInvoke.advapi32]::FreeInheritedFromArray( - $InheritArray, - $Acl.Count, - [System.IntPtr]::Zero - ) | CheckExitCode -Action "Freeing InheritedFrom array" -ErrorAction Stop - } - } - catch { - Write-Error $_ - continue - } - finally { - # Free allocated memory - [System.Runtime.InteropServices.Marshal]::FreeHGlobal($InheritArray) - - if ($SecurityPrivResults.PrivilegeChanged) { - # If this is true, then the privilege was changed, so it needs to be - # reverted back. If it's false, then the privilege wasn't changed (either - # b/c the user doesn't hold the privilege, or b/c it was already enabled; - # it doesn't really matter why). So, disable it if it was successfully - # enabled earlier. - $ActionText = "Reverting privilege '{0}' (back to disabled)" -f $SecurityPrivResults.PrivilegeName - Write-Debug "$($MyInvocation.MyCommand): $ActionText" - - $NewResult = SetTokenPrivilege -Privilege $SecurityPrivResults.PrivilegeName -Disable - if (-not $NewResult.PrivilegeChanged) { - # This is an error; privilege wasn't changed back to original setting - Write-Error $ActionText - } - } - } - } - } -} - -function ConvertToIdentityReference { -<# - Attempts to convert an arbitrary object ($Principal) into a IdentityReference object. Optional - switch parameters allow return object to be returned as NTAccount or SecurityIdentifier objects. - It doesn't use the .NET .Translate() method since that doesn't appear to support remote - translation. Instead, it uses two functions from this module that use P/Invoke -#> - - [CmdletBinding(DefaultParameterSetName="__AllParameterSets")] - param( - [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0)] - $Principal, - [Parameter(Mandatory=$true, ParameterSetName="ReturnSid")] - [switch] $ReturnSid, - [Parameter(Mandatory=$true, ParameterSetName="ReturnAccount")] - [switch] $ReturnAccount, - [switch] $DontVerifyNtAccount, - [string] $ComputerName - ) - - process { - # Convert $Principal to an IdentityReference (most of the time, this will probably be a string, which will be treated - # as a [System.Security.Principal.NTAccount], but can also be a SID object: - - $ExtraParam = @{} - if ($PSBoundParameters.ContainsKey("ComputerName")) { - $ExtraParam.ComputerName = $ComputerName - } - - switch ($Principal.GetType().FullName) { - { "System.String", "System.Security.Principal.NTAccount" -contains $_ } { - # Principal will be an NTAccount (constructors below will cast this to an IdentityReference). Assume strings - # are account names (if this fails, an attempt to convert to a sid will occur later) - try { - $IdentityReference = [System.Security.Principal.NTAccount] $Principal - } - catch { - Write-Error $_ - return - } - - # Verify that this is a valid user - try { - $TranslatedSid = Get-SidFromAccountName $IdentityReference @ExtraParam -ErrorAction Stop | select -exp Sid - $NtAccount = $IdentityReference # Assign this if translation was successful - } - catch { - # Couldn't get a sid from what was assumed to be an account. It might have been a string representation of - # a SID, though - if ($Principal -like "S-*") { # This could use a regex - try { - # Attempt to convert supplied string to a SID (this shouldn't happen much with PAC module, b/c - # SIDs will usually come through as an object, not a string - $TranslatedSid = $IdentityReference = [System.Security.Principal.SecurityIdentifier] $Principal - - # If we made it here, conversion must have worked! - break # Break out of switch statement - } - catch { - # Don't do anything; parent catch block will output error - } - } - - if ($DontVerifyNtAccount) { - $NtAccount = $IdentityReference # Go ahead and assign this - break # Break out of switch statement - } - else { - # Write error and break out of process{} block - Write-Error $_ - return - } - } - } - - default { - try { - # The only type that should allow this would be a SecurityIdentifier. Attempt the cast, - # and write an error if it doesn't work. - $TranslatedSid = $IdentityReference = [System.Security.Principal.IdentityReference] $Principal - } - catch { - Write-Error $_ - return - } - } - } - - switch ($PSCmdlet.ParameterSetName) { - ReturnSid { - # If everything worked, this should have been populated (if it's null, there must have been an error - # and -DontVerifyNtAccount switch was passed) - $TranslatedSid - } - - ReturnAccount { - if ($NtAccount -eq $null) { - # This can happen if a SID was passed to the function. Go ahead and try to translate it: - try { - $Account = Get-AccountFromSid -Sid $TranslatedSid @ExtraParam -ErrorAction Stop - [System.Security.Principal.NTAccount] $NtAccount = ("{0}\{1}" -f $Account.Domain, $Account.AccountName).TrimStart("\") - } - catch { - Write-Error $_ - return - } - } - $NtAccount - } - - default { - # Just return the identity reference - $IdentityReference - } - } - } -} - -function GetPrincipalString { -<# -I may put this functionality in the ConvertToIdentityReference. This uses ConvertToIdentityReference to attempt to -convert an IdentityReference into a string. If the initial translation fails, the $SdPath and $ObjectType are -inspected, and ConvertToIdentityReference may be called again w/ a remote computer name. If that translation fails, -the original IdentityReference is returned along with an 'Account Unknown' string - -It gets its own function b/c New-AdaptedAcl and the Onwer/Group properties all need the exact same functionality -(attempt local translation, then possibly remote translation) -#> - - param( - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true)] - [Alias("SecurityIdentifier", "Principal")] - $IdentityReference, - [Parameter(ValueFromPipelineByPropertyName=$true)] - [System.Security.AccessControl.ResourceType] $ObjectType, - [Parameter(ValueFromPipelineByPropertyName=$true)] - $SdPath - ) - - process { - $Principal = $null - - # This will convert the SID to a string representation of the account. If translation isn't possible, principal name will be null (which - # will make it easy to tell accounts that weren't able to be translated later) - try { - $Principal = $IdentityReference | ConvertToIdentityReference -ReturnAccount -ErrorAction Stop - } - catch { - # Error converting. Could this be a user/group on a remote system? Check the SdPath to see if we can pull a - # machine name out of it - - try { - if ($PSBoundParameters.ObjectType -match "^DSObject" -and $PSBoundParameters.SdPath -match "((,DC=[^,]*)*?)$") { - $DomainName = $matches[1] -replace ",DC=", "." - $DomainName = $DomainName -replace ".*DnsZones\." - $DomainName = $DomainName -replace "^\." - - $Principal = "{0}\{1}" -f $DomainName, ($IdentityReference | ConvertToIdentityReference -ReturnAccount -ErrorAction Stop -ComputerName $DomainName) - - - } - elseif ($PSBoundParameters.SdPath -match "^(\\\\|Microsoft\.WSMan\.Management\\WSMan::)(?[^\\]+)\\") { - $Principal = "{0}" -f ($IdentityReference | ConvertToIdentityReference -ReturnAccount -ErrorAction Stop -ComputerName $matches.ComputerName) - } - } - catch { - # Don't do anything here. We'll take care of it outside of the if statement - } - - if (-not $Principal) { - # Couldn't convert SID, so return account unknown string. Overloading ToString() method b/c sometimes this value - # may be used as an identity reference (e.g., Owner property couldn't be translated. If just string is returned, - # then there will be an error trying to use the actual string value, but a SID object that can't be translated - # could still be used successfully - $Principal = $IdentityReference | Add-Member -PassThru -MemberType ScriptMethod -Name ToString -Force -Value { "Account Unknown ({0})" -f $this.Value } - } - } - - $Principal - } -} - -function Get-SidFromAccountName { - - [CmdletBinding()] - param( - [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] - [string] $AccountName, - # If Computer/Domain name is used above in [computer]\[user] above, this param will be used in place of the computer/domain above - [string] $ComputerName - ) - - process { - $Use = New-Object PowerShellAccessControl.PInvoke.advapi32+SID_NAME_USE - $ByteArraySize = 0 - $DomainNameBufferLength = 0 - - # Was a remote location specified through the parameters? - if ($PSBoundParameters.ContainsKey("ComputerName")) { - $Computer = $PSBoundParameters.ComputerName - } - else { - $Computer = $null - } - - # Dirty hack. ALL APPLICATION PACKAGES can't be converted from name to SID if the authority is included. Remove - # that authority if found: - $AccountName = $AccountName -replace "^APPLICATION PACKAGE AUTHORITY\\" - - try { - # First call tells us SID and DomainName size; return code should be 122: - $ReturnValue = [PowerShellAccessControl.PInvoke.advapi32]::LookupAccountName( - $Computer, - $AccountName, - $null, - [ref] $ByteArraySize, - $null, - [ref] $DomainNameBufferLength, - [ref] $Use - ) - $ReturnValue | CheckExitCode -Action "Looking up SID for '$AccountName'" -ErrorAction Stop - } - catch { - #$RegEx = "^((?[^\\]+)\\)?(?[^\\]+)$" - # Previous RegEx would fail with things like 'DOMAIN\BUILTIN\Pre-Windows 2000 Compatible Access' - $RegEx = "^((?[^\\]+)\\)?(?.+)$" - - if (($ReturnValue -eq 1332) -and - ($AccountName -match $RegEx) -and - (-not $PSBoundParameters.ContainsKey("ComputerName")) - ) { - $null = $PSBoundParameters.Remove("AccountName") - Write-Debug ("{0}: Failed to translate SID; attempting with computername '{1}'" -f $MyInvocation.MyCommand, $matches.ComputerOrDomain) - Get-SidFromAccountName -AccountName $matches.AccountName -ComputerName $matches.ComputerOrDomain @PSBoundParameters - return - } - elseif ($ReturnValue -ne 122) { - Write-Error $_ - return - } - } - - $ByteArray = New-Object byte[] $ByteArraySize - $DomainName = New-Object System.Text.StringBuilder $DomainNameBufferLength - - try { - [PowerShellAccessControl.PInvoke.advapi32]::LookupAccountName( - $Computer, - $AccountName, - $ByteArray, - [ref] $ByteArraySize, - $DomainName, - [ref] $DomainNameBufferLength, - [ref] $Use - ) | CheckExitCode -ErrorAction Stop - } - catch { - Write-Error $_ - return - } - - New-Object PSObject -Property @{ - Use = $Use - Domain = $DomainName.ToString() - Sid = (New-Object System.Security.Principal.SecurityIdentifier ($ByteArray, 0)) - } - } -} - -function Get-AccountFromSid { - [CmdletBinding()] - param( - [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] - [Alias('SecurityIdentifier')] - [System.Security.Principal.SecurityIdentifier] $Sid, - [string] $ComputerName - ) - - process { - - $SidBytes = New-Object byte[] $Sid.BinaryLength - $Sid.GetBinaryForm($SidBytes, 0) - - $Use = New-Object PowerShellAccessControl.PInvoke.advapi32+SID_NAME_USE - $NameBufferLength = $DomainNameBufferLength = 255 - $Name = New-Object System.Text.StringBuilder $NameBufferLength - $DomainName = New-Object System.Text.StringBuilder $DomainNameBufferLength - - if ($PSBoundParameters.ContainsKey("ComputerName")) { - $Computer = $PSBoundParameters.ComputerName - } - else { - $Computer = $null - } - - try { - [PowerShellAccessControl.PInvoke.advapi32]::LookupAccountSid( - $Computer, - $SidBytes, - $Name, - [ref] $NameBufferLength, - $DomainName, - [ref] $DomainNameBufferLength, - [ref] $Use - ) | CheckExitCode -ErrorAction Stop - } - catch { - Write-Error "Error looking up account for SID '$Sid': $($_.Exception.Message)" - return - } - - New-Object PSObject -Property @{ - Use = $Use - Domain = $DomainName.ToString() - AccountName = $Name.ToString() - } - } -} - -function Select-SingleObject { -<# -.SYNOPSIS -Takes multiple inputs and allows a user to choose a single one for the output. - -.DESCRIPTION -This function will filter multiple inputs into a single output. If the PS version -is greater than version 3.0, Out-GridView is used by default. Otherwise, the -built-in prompt for choice is used. - -If a specific prompt type is desired, that can be handled with -PromptMode -parameter. -#> - - [CmdletBinding()] - param( - [Parameter(ValueFromPipeline=$true)] - $InputObject, - [ValidateSet("OutGridView","PromptForChoice")] - $PromptMode, - [string] $Title = "Please choose one", # Title for out-gridview; description for prompt for choice - [string] $PromptForChoiceTitle = "Choice", - [int] $MaxObjectsToDisplay - ) - - begin { - if ($PSBoundParameters.ContainsKey("PromptMode")) { - $PromptMode = $PSBoundParameters.PromptMode - } - else { - if ($PSVersionTable.PSVersion -ge "3.0") { - $PromptMode = "OutGridView" - } - else { - $PromptMode = "PromptForChoice" - } - } - - # Extra check to make sure OutGridView won't be used on a system w/o at least PSv3: - if ($PromptMode -eq "OutGridView" -and ($PSVersionTable.PSVersion -lt "3.0")) { - Write-Warning "OutGridView prompt mode not supported in this version of PowerShell" - $PromptMode = "PromptForChoice" - } - - $AllInputObjects = @() - } - - process { - foreach ($CurrentInputObject in $InputObject) { - $AllInputObjects += $CurrentInputObject - } - } - - end { - if ($AllInputObjects.Count -eq 0) { - Write-Error "No objects were provided as input" - return - } - elseif ($AllInputObjects.Count -eq 1) { - # Single object came through, so output that object and exit - $AllInputObjects | select -first 1 - return - } - - # Use Select-Object along with some of the function's parameters to work - # on the InputObject: - $SelectObjectParams = @{} - if ($PSBoundParameters.ContainsKey("MaxObjectsToDisplay")) { - $SelectObjectParams.First = $MaxObjectsToDisplay - } - - $AllInputObjects = $AllInputObjects | Select-Object @SelectObjectParams - - switch ($PromptMode) { - OutGridView { - do { - $AllInputObjects = $AllInputObjects | Out-GridView -Title $Title -OutputMode Single - } while ($AllInputObjects.Count -gt 1) - - $Output = $AllInputObjects - } - - PromptForChoice { - $UsedHotkeys = @() - - # This is used as a backup in case the ToString() method doesn't return anything - $PropertyNames = $AllInputObjects | select -first 1 @Property | Get-Member -MemberType Properties | select -First 4 -ExpandProperty Name - [System.Management.Automation.Host.ChoiceDescription[]] $Choices = $AllInputObjects | ForEach-Object { - $Name = $_.ToString() - if (-not $Name) { - $Name = foreach ($CurrentPropertyName in $PropertyNames) { - $_.$CurrentPropertyName.ToString() - } - $Name = $Name -join " - " - } - - for ($i = 0; $i -lt $Name.Length; $i++) { - $CurrentLetter = $Name[$i] - if ($UsedHotkeys -notcontains $CurrentLetter) { - $UsedHotkeys += $CurrentLetter - $Name = "{0}&{1}" -f $Name.SubString(0, $i), $Name.SubString($i, $Name.Length - $i) - break - } - } - - New-Object System.Management.Automation.Host.ChoiceDescription $Name - } - - $Result = $Host.UI.PromptForChoice( - $PromptForChoiceTitle, - $Title, - $Choices, - 0 - ) - - $Output = $AllInputObjects | select -Skip $Result -First 1 - - } - } - - if ($Output -eq $null) { - Write-Error "Selection cancelled" - } - else { - $Output - } - } -} - -if ($PSVersionTable.PSVersion -ge "3.0") { -# Long path names only supported on PS version 3.0 or greater -# Used for long filename support: -Add-Type -Path "$PSScriptRoot\bin\Microsoft.Experimental.IO.dll" - - function Resolve-Path { - <# - Proxy function used for very basic long path support. If resolve-path cmdlet encounters and error, this - function will catch it, and attempt to use the experimental io library to resolve the path as a long - directory name or long file name. - - #> - - [CmdletBinding(DefaultParameterSetName='Path', SupportsTransactions=$true)] #, HelpUri='http://go.microsoft.com/fwlink/?LinkID=113384')] - param( - [Parameter(ParameterSetName='Path', Mandatory=$true, Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] - [string[]] - ${Path}, - - [Parameter(ParameterSetName='LiteralPath', Mandatory=$true, ValueFromPipelineByPropertyName=$true)] - [Alias('PSPath')] - [string[]] - ${LiteralPath}, - - [switch] - ${Relative}, - - [Parameter(ValueFromPipelineByPropertyName=$true)] - [pscredential] - ${Credential}) - - begin - { - - try { - $outBuffer = $null - if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) - { - $PSBoundParameters['OutBuffer'] = 1 - } - $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Resolve-Path', [System.Management.Automation.CommandTypes]::Cmdlet) - - #region PAC module addition - $PSBoundParameters.ErrorVariable = "__ResolvePathErrors" - $PSBoundParameters.ErrorAction = "SilentlyContinue" - #endregion - - $scriptCmd = { & $wrappedCmd @PSBoundParameters } - $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin) - $steppablePipeline.Begin($PSCmdlet) - } catch { - throw - } - } - - process - { - try { - $steppablePipeline.Process($_) - } - catch { - throw - } - - #region PAC module addition - if ($__ResolvePathErrors) { - - $ErrorsToWrite = @() - foreach ($CurrentError in ($__ResolvePathErrors | select -Unique)) { # For some reason, Resolve-Path sometimes outputs duplicate errors - - $ResolvedLongPaths = if ($_) { - ResolveLongPath $_ - } - else { - foreach ($CurrentPath in $Path) { - ResolveLongPath $CurrentPath - } - } - - if ($ResolvedLongPaths) { - $ResolvedLongPaths - } - else { - $ErrorsToWrite += $CurrentError - } - } - - # All errors have either been dealt with or written back out. Clear them: - foreach ($CurrentError in $ErrorsToWrite) { - Write-Error $CurrentError - } - $__ResolvePathErrors.Clear() - } - #endregion - } - - end - { - try { - $steppablePipeline.End() - } catch { - throw - } - } - <# - - .ForwardHelpTargetName Resolve-Path - .ForwardHelpCategory Cmdlet - - #> - } - - function ResolveLongPath { - <# - When Resolve-Path encounters an error, this function is used to check to see if the path was a - long path: - #> - [CmdletBinding()] - param( - [Parameter(Mandatory=$true)] - [string] $Path, - [string] $SearchPattern - ) - - $ProviderPrefix = "PowerShellAccessControl" - - if (-not $Path) { return } - - try { - if (-not $SearchPattern) { - if ([Microsoft.Experimental.IO.LongPathDirectory]::Exists($Path)) { - $Type = "directory" - } - elseif ([Microsoft.Experimental.IO.LongPathFile]::Exists($Path)) { - $Type = "file" - } - else { - throw "syntax is incorrect" - } - - New-Object PSObject -Property @{ - Path = $Path - Provider = "$ProviderPrefix$Type" - } - } - else { - [Microsoft.Experimental.IO.LongPathDirectory]::EnumerateDirectories($Path, $SearchPattern) | ForEach-Object { - New-Object PSObject -Property @{ - Path = $_ - Provider = "${ProviderPrefix}Directory" - } - } - [Microsoft.Experimental.IO.LongPathDirectory]::EnumerateFiles($Path, $SearchPattern) | ForEach-Object { - New-Object PSObject -Property @{ - Path = $_ - Provider = "${ProviderPrefix}File" - } - } - } - } - catch { - if ($_.Exception.Message -match "syntax is incorrect") { - $Params = @{ - Path = Split-Path $Path -Parent - SearchPattern = Split-Path $Path -Leaf - } - - ResolveLongPath @Params -ErrorAction SilentlyContinue | ForEach-Object { - if ($SearchPattern) { - ResolveLongPath -Path $_.Path -SearchPattern $SearchPattern - } - else { - $_ - } - } - } - else { - # Write the error as is - Write-Error $_ - } - } - } -} - -function GetDefaultAppliesTo { -<# -Different types of objects have ACEs that have a different "AppliesTo" value. For example, folders default to -"Object, ChildContains, ChildObjects", files to just "Object", registry keys to "Object, ChildContainers", etc. - -This function takes the access mask enumeration and a boolean value telling whether or not the ACE belongs to -a container object (like a folder or registry entry), and outputs the default "AppliesTo" enumeration value. -#> - - [CmdletBinding()] - param( - $AccessMaskEnumeration, - [switch] $IsContainer = $false - ) - - # SDs have ACEs that apply to their object by default: - $AppliesTo = [PowerShellAccessControl.AppliesTo]::Object - - if ($IsContainer) { - # If the SD belongs to container, ACEs also apply to child containers by default: - $AppliesTo = $AppliesTo -bor [PowerShellAccessControl.AppliesTo]::ChildContainers - - # ACEs apply to child objects if they are folders. Switch statement used in case there - # are future types that need a special handling - switch ($AccessMaskEnumeration.FullName) { - - System.Security.AccessControl.FileSystemRights { - $AppliesTo = $AppliesTo -bor [PowerShellAccessControl.AppliesTo]::ChildObjects - } - } - } - - [PowerShellAccessControl.AppliesTo] $AppliesTo -} - -function GetCentralAccessPolicy { -<# -Currently just messing around with retrieving CAPs. This relies on the ActiveDirectory module, -and since the function doesn't need that, this will fail miserably on a system that doesn't -have it. Once CAPs are officially supported, ActiveDirectory module dependence will be removed. - -#> -param( - $SDObject -) - if ($__OsVersion -lt "6.2") { - return - } - - $BinaryScopeInfo = GetSecurityInfo -Path $SDObject.Path -ObjectType $SDObject.ObjectType -SecurityInformation Scope - - $SD = New-Object System.Security.AccessControl.RawSecurityDescriptor (([byte[]] $BinaryScopeInfo), 0) - - # AceType of 19 is what holds the info we want: - $SD.SystemAcl | - where { [int] $_.AceType -eq 19 } | - ForEach-Object { - - $Data = $_.GetOpaque() - $NewAceParams = @{ - Principal = New-Object System.Security.Principal.SecurityIdentifier ($Data, 4) - AccessMask = [System.BitConverter]::ToInt32($Data, 0) - AppliesTo = $_ | GetAppliesToMapping - OnlyApplyToThisContainer = $_ | GetAppliesToMapping -CheckForNoPropagateInherit - } - $Ace = New-AccessControlEntry @NewAceParams - - $Policy = Get-ADCentralAccessPolicy -Filter { policyID -eq $Ace.SecurityIdentifier } -ErrorAction SilentlyContinue - if ($Policy) { - $Rules = $Policy.Members | Get-ADCentralAccessRule - - # PSCustomObject is OK since CAP will only apply on systems that have PS > 2 - $Policy = [PSCustomObject] @{ - Policy = $Policy - Rules = $Rules - } - } - - - # There are a few things that still need fixing - $Ace | Add-Member -NotePropertyMembers @{ - AceType = "CentralAccessPolicy" - IsInherited = $_.IsInherited - Policy = $Policy - } -Force - - $Ace - } -} - -filter ModifySearchRegex { -<# -There are a few places where a regex is used, but I wanted a * -to be replaced with a .* - -I also wanted a way for the user to still escape the * so that -they could use one in a proper regex. Just in case the steps -I came up with were wrong, I wanted to have the replacement -handled somewhere else so I would just have to make changes in -one place in the future. - -This replaces a single asterisk with a .* -If it encounteres a double asterisk, **, it will not do the .* -replacement, but it will replace it with a single asterisk. -#> - $Temp = $_ -replace "(? - - - - Add-AccessControlEntry - - Adds access control entries to security descriptors. - - - - - Add - AccessControlEntry - - - - - Remove-AccessControlEntry allows the removal of access control entries (ACEs) -from either the discretionary access control list (DACL), which deals with -object access, or the system access control list (SACL), which deals with -object auditing, of an object's security descriptor (SD). - -The function will automatically determine which ACL to modify by inspecting the -ACE object. - -There are four major ways to use this function: -1. Remove a specific set of permissions from any existing matching ACEs - This is the default behavior when you supply a security object and an ACE - (which can be specified through the -AceObject parameter, through the ACE - creation parameters (which resemble New-AccessControlEntry's parameters), or - from output from the Get-AccessControlEntry function. - - An example would be to remove 'Write' allow access from the 'Users' group - when an existing ACE that grants 'Read' and 'Write' access already exists. - After running this function, the existing ACE would only grant 'Read' access. - -2. Remove a specific ACE - This is the same as #1 above, except the -Specific switch is applied. Using - the example mentioned, running the function with the -Specific switch - wouldn't modify the ACL since the supplied ACE with 'Write' permission - wouldn't match the existing ACE with 'Read' and 'Write' permission. - -3. Remove a specific principal from an ACL - To remove a specific principal from either ACL, provide a user/group name or - a security identifier to the -Principal parameter and specify one or both of - the the -PurgeAccessRules and/or the -PurgeAuditRules switch parameters. - -4. Remove all ACEs from an ACL - To clear all entries from an ACL, specify the -RemoveAllAccessEntries and/or - -RemoveAllAuditEntries switch parameters. It is possible to use one at a - time, or both at the same time. - - - - - Add-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry added -to it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - AceObject - - This is one or more ACEs to be added to the security descriptor. Each ACE will -be added to each security descriptor in the -SDObject parameter (which means -more than one -AceObject and/or -SDObject can be provided). - -The -AceObject objects can be created via the New-AccessControlEntry, they can -come from the Access and/or Audit properties of a security descriptor, or they -can come from Get-AccessControlEntry. - - Object[] - - - AddEvenIfAclDoesntExist - - By default, if an attempt is made to add an ACE to a non-existent ACL, the -function will write a warning and not make any changes to the security -descriptor. An example of this would be using Get-SecurityDescriptor without -the -Audit switch, then trying to add a 'SystemAudit' ACE to the security -descriptor. - -This switch will cause the function to create a blank ACL and add the ACE if -the ACL that the ACE should belong to does not already exist. If the ACL does -already exist, this switch will not do anything. - -Note that using this switch and then saving the resulting security descriptor -object back out could cause a previously populated ACL to be overwritten. - - SwitchParameter - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Overwrite - - By default, if an existing ACE's properties match all of the properties of the -ACE to be added (except the access mask), the rights from both ACEs are merged. - -If this switch is specified, the existing ACE is removed before the new ACE is -added. This causes the function to behave like the SetAccessRule/SetAuditRule -methods instead of the AddAccessRule/AddAuditRule methods on Get-Acl security -descriptors. - -Example: If an ACE granting Everyone Read rights already exists in the security -descriptor, and an ACE granting Everyone Write rights is added, the default -behavior would result in a single ACE giving Everyone Read and Write rights -over the object. Using this switch would result in a single ACE giving Everyone -Write rights (no Read rights), because the original ACE would be removed before -the new one is added. - - SwitchParameter - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Add-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry added -to it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - AddEvenIfAclDoesntExist - - By default, if an attempt is made to add an ACE to a non-existent ACL, the -function will write a warning and not make any changes to the security -descriptor. An example of this would be using Get-SecurityDescriptor without -the -Audit switch, then trying to add a 'SystemAudit' ACE to the security -descriptor. - -This switch will cause the function to create a blank ACL and add the ACE if -the ACL that the ACE should belong to does not already exist. If the ACL does -already exist, this switch will not do anything. - -Note that using this switch and then saving the resulting security descriptor -object back out could cause a previously populated ACL to be overwritten. - - SwitchParameter - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Overwrite - - By default, if an existing ACE's properties match all of the properties of the -ACE to be added (except the access mask), the rights from both ACEs are merged. - -If this switch is specified, the existing ACE is removed before the new ACE is -added. This causes the function to behave like the SetAccessRule/SetAuditRule -methods instead of the AddAccessRule/AddAuditRule methods on Get-Acl security -descriptors. - -Example: If an ACE granting Everyone Read rights already exists in the security -descriptor, and an ACE granting Everyone Write rights is added, the default -behavior would result in a single ACE giving Everyone Read and Write rights -over the object. Using this switch would result in a single ACE giving Everyone -Write rights (no Read rights), because the original ACE would be removed before -the new one is added. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - WsManAccessRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - WsManAccessRights - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Add-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry added -to it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - AddEvenIfAclDoesntExist - - By default, if an attempt is made to add an ACE to a non-existent ACL, the -function will write a warning and not make any changes to the security -descriptor. An example of this would be using Get-SecurityDescriptor without -the -Audit switch, then trying to add a 'SystemAudit' ACE to the security -descriptor. - -This switch will cause the function to create a blank ACL and add the ACE if -the ACL that the ACE should belong to does not already exist. If the ACL does -already exist, this switch will not do anything. - -Note that using this switch and then saving the resulting security descriptor -object back out could cause a previously populated ACL to be overwritten. - - SwitchParameter - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Overwrite - - By default, if an existing ACE's properties match all of the properties of the -ACE to be added (except the access mask), the rights from both ACEs are merged. - -If this switch is specified, the existing ACE is removed before the new ACE is -added. This causes the function to behave like the SetAccessRule/SetAuditRule -methods instead of the AddAccessRule/AddAuditRule methods on Get-Acl security -descriptors. - -Example: If an ACE granting Everyone Read rights already exists in the security -descriptor, and an ACE granting Everyone Write rights is added, the default -behavior would result in a single ACE giving Everyone Read and Write rights -over the object. Using this switch would result in a single ACE giving Everyone -Write rights (no Read rights), because the original ACE would be removed before -the new one is added. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - ProcessAccessRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - ProcessAccessRights - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Add-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry added -to it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - AddEvenIfAclDoesntExist - - By default, if an attempt is made to add an ACE to a non-existent ACL, the -function will write a warning and not make any changes to the security -descriptor. An example of this would be using Get-SecurityDescriptor without -the -Audit switch, then trying to add a 'SystemAudit' ACE to the security -descriptor. - -This switch will cause the function to create a blank ACL and add the ACE if -the ACL that the ACE should belong to does not already exist. If the ACL does -already exist, this switch will not do anything. - -Note that using this switch and then saving the resulting security descriptor -object back out could cause a previously populated ACL to be overwritten. - - SwitchParameter - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Overwrite - - By default, if an existing ACE's properties match all of the properties of the -ACE to be added (except the access mask), the rights from both ACEs are merged. - -If this switch is specified, the existing ACE is removed before the new ACE is -added. This causes the function to behave like the SetAccessRule/SetAuditRule -methods instead of the AddAccessRule/AddAuditRule methods on Get-Acl security -descriptors. - -Example: If an ACE granting Everyone Read rights already exists in the security -descriptor, and an ACE granting Everyone Write rights is added, the default -behavior would result in a single ACE giving Everyone Read and Write rights -over the object. Using this switch would result in a single ACE giving Everyone -Write rights (no Read rights), because the original ACE would be removed before -the new one is added. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - ServiceAccessRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - ServiceAccessRights - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Add-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry added -to it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - AddEvenIfAclDoesntExist - - By default, if an attempt is made to add an ACE to a non-existent ACL, the -function will write a warning and not make any changes to the security -descriptor. An example of this would be using Get-SecurityDescriptor without -the -Audit switch, then trying to add a 'SystemAudit' ACE to the security -descriptor. - -This switch will cause the function to create a blank ACL and add the ACE if -the ACL that the ACE should belong to does not already exist. If the ACL does -already exist, this switch will not do anything. - -Note that using this switch and then saving the resulting security descriptor -object back out could cause a previously populated ACL to be overwritten. - - SwitchParameter - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Overwrite - - By default, if an existing ACE's properties match all of the properties of the -ACE to be added (except the access mask), the rights from both ACEs are merged. - -If this switch is specified, the existing ACE is removed before the new ACE is -added. This causes the function to behave like the SetAccessRule/SetAuditRule -methods instead of the AddAccessRule/AddAuditRule methods on Get-Acl security -descriptors. - -Example: If an ACE granting Everyone Read rights already exists in the security -descriptor, and an ACE granting Everyone Write rights is added, the default -behavior would result in a single ACE giving Everyone Read and Write rights -over the object. Using this switch would result in a single ACE giving Everyone -Write rights (no Read rights), because the original ACE would be removed before -the new one is added. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - WmiNameSpaceRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - WmiNamespaceRights - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Add-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry added -to it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - AddEvenIfAclDoesntExist - - By default, if an attempt is made to add an ACE to a non-existent ACL, the -function will write a warning and not make any changes to the security -descriptor. An example of this would be using Get-SecurityDescriptor without -the -Audit switch, then trying to add a 'SystemAudit' ACE to the security -descriptor. - -This switch will cause the function to create a blank ACL and add the ACE if -the ACL that the ACE should belong to does not already exist. If the ACL does -already exist, this switch will not do anything. - -Note that using this switch and then saving the resulting security descriptor -object back out could cause a previously populated ACL to be overwritten. - - SwitchParameter - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Overwrite - - By default, if an existing ACE's properties match all of the properties of the -ACE to be added (except the access mask), the rights from both ACEs are merged. - -If this switch is specified, the existing ACE is removed before the new ACE is -added. This causes the function to behave like the SetAccessRule/SetAuditRule -methods instead of the AddAccessRule/AddAuditRule methods on Get-Acl security -descriptors. - -Example: If an ACE granting Everyone Read rights already exists in the security -descriptor, and an ACE granting Everyone Write rights is added, the default -behavior would result in a single ACE giving Everyone Read and Write rights -over the object. Using this switch would result in a single ACE giving Everyone -Write rights (no Read rights), because the original ACE would be removed before -the new one is added. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - PrinterRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - PrinterRights - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Add-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry added -to it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - AddEvenIfAclDoesntExist - - By default, if an attempt is made to add an ACE to a non-existent ACL, the -function will write a warning and not make any changes to the security -descriptor. An example of this would be using Get-SecurityDescriptor without -the -Audit switch, then trying to add a 'SystemAudit' ACE to the security -descriptor. - -This switch will cause the function to create a blank ACL and add the ACE if -the ACL that the ACE should belong to does not already exist. If the ACL does -already exist, this switch will not do anything. - -Note that using this switch and then saving the resulting security descriptor -object back out could cause a previously populated ACL to be overwritten. - - SwitchParameter - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Overwrite - - By default, if an existing ACE's properties match all of the properties of the -ACE to be added (except the access mask), the rights from both ACEs are merged. - -If this switch is specified, the existing ACE is removed before the new ACE is -added. This causes the function to behave like the SetAccessRule/SetAuditRule -methods instead of the AddAccessRule/AddAuditRule methods on Get-Acl security -descriptors. - -Example: If an ACE granting Everyone Read rights already exists in the security -descriptor, and an ACE granting Everyone Write rights is added, the default -behavior would result in a single ACE giving Everyone Read and Write rights -over the object. Using this switch would result in a single ACE giving Everyone -Write rights (no Read rights), because the original ACE would be removed before -the new one is added. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - LogicalShareRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - LogicalShareRights - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Add-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry added -to it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - AddEvenIfAclDoesntExist - - By default, if an attempt is made to add an ACE to a non-existent ACL, the -function will write a warning and not make any changes to the security -descriptor. An example of this would be using Get-SecurityDescriptor without -the -Audit switch, then trying to add a 'SystemAudit' ACE to the security -descriptor. - -This switch will cause the function to create a blank ACL and add the ACE if -the ACL that the ACE should belong to does not already exist. If the ACL does -already exist, this switch will not do anything. - -Note that using this switch and then saving the resulting security descriptor -object back out could cause a previously populated ACL to be overwritten. - - SwitchParameter - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Overwrite - - By default, if an existing ACE's properties match all of the properties of the -ACE to be added (except the access mask), the rights from both ACEs are merged. - -If this switch is specified, the existing ACE is removed before the new ACE is -added. This causes the function to behave like the SetAccessRule/SetAuditRule -methods instead of the AddAccessRule/AddAuditRule methods on Get-Acl security -descriptors. - -Example: If an ACE granting Everyone Read rights already exists in the security -descriptor, and an ACE granting Everyone Write rights is added, the default -behavior would result in a single ACE giving Everyone Read and Write rights -over the object. Using this switch would result in a single ACE giving Everyone -Write rights (no Read rights), because the original ACE would be removed before -the new one is added. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - ObjectAceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - InheritedObjectAceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Add-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry added -to it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - AddEvenIfAclDoesntExist - - By default, if an attempt is made to add an ACE to a non-existent ACL, the -function will write a warning and not make any changes to the security -descriptor. An example of this would be using Get-SecurityDescriptor without -the -Audit switch, then trying to add a 'SystemAudit' ACE to the security -descriptor. - -This switch will cause the function to create a blank ACL and add the ACE if -the ACL that the ACE should belong to does not already exist. If the ACL does -already exist, this switch will not do anything. - -Note that using this switch and then saving the resulting security descriptor -object back out could cause a previously populated ACL to be overwritten. - - SwitchParameter - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Overwrite - - By default, if an existing ACE's properties match all of the properties of the -ACE to be added (except the access mask), the rights from both ACEs are merged. - -If this switch is specified, the existing ACE is removed before the new ACE is -added. This causes the function to behave like the SetAccessRule/SetAuditRule -methods instead of the AddAccessRule/AddAuditRule methods on Get-Acl security -descriptors. - -Example: If an ACE granting Everyone Read rights already exists in the security -descriptor, and an ACE granting Everyone Write rights is added, the default -behavior would result in a single ACE giving Everyone Read and Write rights -over the object. Using this switch would result in a single ACE giving Everyone -Write rights (no Read rights), because the original ACE would be removed before -the new one is added. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - ActiveDirectoryRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - ActiveDirectoryRights - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - ObjectAceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - InheritedObjectAceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Add-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry added -to it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - AddEvenIfAclDoesntExist - - By default, if an attempt is made to add an ACE to a non-existent ACL, the -function will write a warning and not make any changes to the security -descriptor. An example of this would be using Get-SecurityDescriptor without -the -Audit switch, then trying to add a 'SystemAudit' ACE to the security -descriptor. - -This switch will cause the function to create a blank ACL and add the ACE if -the ACL that the ACE should belong to does not already exist. If the ACL does -already exist, this switch will not do anything. - -Note that using this switch and then saving the resulting security descriptor -object back out could cause a previously populated ACL to be overwritten. - - SwitchParameter - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Overwrite - - By default, if an existing ACE's properties match all of the properties of the -ACE to be added (except the access mask), the rights from both ACEs are merged. - -If this switch is specified, the existing ACE is removed before the new ACE is -added. This causes the function to behave like the SetAccessRule/SetAuditRule -methods instead of the AddAccessRule/AddAuditRule methods on Get-Acl security -descriptors. - -Example: If an ACE granting Everyone Read rights already exists in the security -descriptor, and an ACE granting Everyone Write rights is added, the default -behavior would result in a single ACE giving Everyone Read and Write rights -over the object. Using this switch would result in a single ACE giving Everyone -Write rights (no Read rights), because the original ACE would be removed before -the new one is added. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - RegistryRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - RegistryRights - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Add-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry added -to it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - AddEvenIfAclDoesntExist - - By default, if an attempt is made to add an ACE to a non-existent ACL, the -function will write a warning and not make any changes to the security -descriptor. An example of this would be using Get-SecurityDescriptor without -the -Audit switch, then trying to add a 'SystemAudit' ACE to the security -descriptor. - -This switch will cause the function to create a blank ACL and add the ACE if -the ACL that the ACE should belong to does not already exist. If the ACL does -already exist, this switch will not do anything. - -Note that using this switch and then saving the resulting security descriptor -object back out could cause a previously populated ACL to be overwritten. - - SwitchParameter - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Overwrite - - By default, if an existing ACE's properties match all of the properties of the -ACE to be added (except the access mask), the rights from both ACEs are merged. - -If this switch is specified, the existing ACE is removed before the new ACE is -added. This causes the function to behave like the SetAccessRule/SetAuditRule -methods instead of the AddAccessRule/AddAuditRule methods on Get-Acl security -descriptors. - -Example: If an ACE granting Everyone Read rights already exists in the security -descriptor, and an ACE granting Everyone Write rights is added, the default -behavior would result in a single ACE giving Everyone Read and Write rights -over the object. Using this switch would result in a single ACE giving Everyone -Write rights (no Read rights), because the original ACE would be removed before -the new one is added. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - FolderRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - FileSystemRights - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Add-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry added -to it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - AddEvenIfAclDoesntExist - - By default, if an attempt is made to add an ACE to a non-existent ACL, the -function will write a warning and not make any changes to the security -descriptor. An example of this would be using Get-SecurityDescriptor without -the -Audit switch, then trying to add a 'SystemAudit' ACE to the security -descriptor. - -This switch will cause the function to create a blank ACL and add the ACE if -the ACL that the ACE should belong to does not already exist. If the ACL does -already exist, this switch will not do anything. - -Note that using this switch and then saving the resulting security descriptor -object back out could cause a previously populated ACL to be overwritten. - - SwitchParameter - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Overwrite - - By default, if an existing ACE's properties match all of the properties of the -ACE to be added (except the access mask), the rights from both ACEs are merged. - -If this switch is specified, the existing ACE is removed before the new ACE is -added. This causes the function to behave like the SetAccessRule/SetAuditRule -methods instead of the AddAccessRule/AddAuditRule methods on Get-Acl security -descriptors. - -Example: If an ACE granting Everyone Read rights already exists in the security -descriptor, and an ACE granting Everyone Write rights is added, the default -behavior would result in a single ACE giving Everyone Read and Write rights -over the object. Using this switch would result in a single ACE giving Everyone -Write rights (no Read rights), because the original ACE would be removed before -the new one is added. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - FileRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - FileSystemRights - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Add-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry added -to it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - AddEvenIfAclDoesntExist - - By default, if an attempt is made to add an ACE to a non-existent ACL, the -function will write a warning and not make any changes to the security -descriptor. An example of this would be using Get-SecurityDescriptor without -the -Audit switch, then trying to add a 'SystemAudit' ACE to the security -descriptor. - -This switch will cause the function to create a blank ACL and add the ACE if -the ACL that the ACE should belong to does not already exist. If the ACL does -already exist, this switch will not do anything. - -Note that using this switch and then saving the resulting security descriptor -object back out could cause a previously populated ACL to be overwritten. - - SwitchParameter - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Overwrite - - By default, if an existing ACE's properties match all of the properties of the -ACE to be added (except the access mask), the rights from both ACEs are merged. - -If this switch is specified, the existing ACE is removed before the new ACE is -added. This causes the function to behave like the SetAccessRule/SetAuditRule -methods instead of the AddAccessRule/AddAuditRule methods on Get-Acl security -descriptors. - -Example: If an ACE granting Everyone Read rights already exists in the security -descriptor, and an ACE granting Everyone Write rights is added, the default -behavior would result in a single ACE giving Everyone Read and Write rights -over the object. Using this switch would result in a single ACE giving Everyone -Write rights (no Read rights), because the original ACE would be removed before -the new one is added. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - AccessMask - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Int32 - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - ObjectAceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - InheritedObjectAceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - - - SDObject - - Specifies the security descriptor that will have an access control entry added -to it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - Object - - - - - - AceObject - - This is one or more ACEs to be added to the security descriptor. Each ACE will -be added to each security descriptor in the -SDObject parameter (which means -more than one -AceObject and/or -SDObject can be provided). - -The -AceObject objects can be created via the New-AccessControlEntry, they can -come from the Access and/or Audit properties of a security descriptor, or they -can come from Get-AccessControlEntry. - - Object[] - - Object[] - - - - - - AddEvenIfAclDoesntExist - - By default, if an attempt is made to add an ACE to a non-existent ACL, the -function will write a warning and not make any changes to the security -descriptor. An example of this would be using Get-SecurityDescriptor without -the -Audit switch, then trying to add a 'SystemAudit' ACE to the security -descriptor. - -This switch will cause the function to create a blank ACL and add the ACE if -the ACL that the ACE should belong to does not already exist. If the ACL does -already exist, this switch will not do anything. - -Note that using this switch and then saving the resulting security descriptor -object back out could cause a previously populated ACL to be overwritten. - - SwitchParameter - - SwitchParameter - - - - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - SwitchParameter - - - - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - SwitchParameter - - - - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - SwitchParameter - - - - - - Overwrite - - By default, if an existing ACE's properties match all of the properties of the -ACE to be added (except the access mask), the rights from both ACEs are merged. - -If this switch is specified, the existing ACE is removed before the new ACE is -added. This causes the function to behave like the SetAccessRule/SetAuditRule -methods instead of the AddAccessRule/AddAuditRule methods on Get-Acl security -descriptors. - -Example: If an ACE granting Everyone Read rights already exists in the security -descriptor, and an ACE granting Everyone Write rights is added, the default -behavior would result in a single ACE giving Everyone Read and Write rights -over the object. Using this switch would result in a single ACE giving Everyone -Write rights (no Read rights), because the original ACE would be removed before -the new one is added. - - SwitchParameter - - SwitchParameter - - - - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - SwitchParameter - - - - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - SwitchParameter - - - - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - String - - - - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - Object - - - - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - AppliesTo - - - - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - SwitchParameter - - - - - - WsManAccessRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - WsManAccessRights - - WsManAccessRights - - - - - - ProcessAccessRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - ProcessAccessRights - - ProcessAccessRights - - - - - - ServiceAccessRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - ServiceAccessRights - - ServiceAccessRights - - - - - - WmiNameSpaceRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - WmiNamespaceRights - - WmiNamespaceRights - - - - - - PrinterRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - PrinterRights - - PrinterRights - - - - - - LogicalShareRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - LogicalShareRights - - LogicalShareRights - - - - - - ObjectAceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - Object - - - - - - InheritedObjectAceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - Object - - - - - - ActiveDirectoryRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - ActiveDirectoryRights - - ActiveDirectoryRights - - - - - - RegistryRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - RegistryRights - - RegistryRights - - - - - - FolderRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - FileSystemRights - - FileSystemRights - - - - - - FileRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - FileSystemRights - - FileSystemRights - - - - - - AccessMask - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Int32 - - Int32 - - - - - - - - - - - - - - - - - - - - - - - - Nothing is returned by default. If the -PassThru parameter is specified, though, then a security descriptor object is output. - - - - - - - - - - - - - - - - -------------- Example 1 -------------- - - - - PS C:\> $SourceFileName = 'C:\Folder1\source.txt' -PS C:\> $TargetFileName = 'C:\Folder2\target.txt' -PS C:\> Get-SecurityDescriptor $TargetFileName | - Add-AccessControlEntry -AceObject (Get-SecurityDescriptor $SourceFileName).Access -PassThru | - Set-SecurityDescriptor -WhatIf - - This example adds every single discretionary ACE (access) from the 'source.txt' -file as an explicit ACE on the 'target.txt' file. Both Non-Inherited and -Inherited ACEs on 'source.txt' would be added to 'target.txt'. - -The following commands to the same as the last command above, but using -different methods. All three commands (including the one above) use the -Whatif -switch, so no changes are made: - -PS C:\> Add-AccessControlEntry -Path $TargetFileName -AceObject (Get-SecurityDescriptor $SourceFileName).Access -WhatIf -PS C:\> Get-AccessControlEntry $SourceFileName -AceType AccessAllowed,AccessDenied | - Add-AccessControlEntry -Path $TargetFileName -WhatIf - - - - - - - - - -------------- Example 2 -------------- - - - - PS C:\> $SourceFileName = 'C:\Folder1\source.txt' -PS C:\> $TargetFileName = 'C:\Folder2\target.txt' -PS C:\> Get-AccessControlEntry $SourceFileName -AceType AccessAllowed,AccessDenied -NotInherited | - Add-AccessControlEntry -Path $TargetFileName -WhatIf - - This does the same thing as example #1, except only explicitly assigned ACEs -from 'source.txt' will be copied to 'target.txt'. -Path is an alias for the --SDObject parameter. - -This example demonstrates how Get-AccessControlEntry can be combined with Add- -AccessControlEntry to add ACEs that match certain conditions (see the help -for Get-AccessControlEntry for more examples of filtering ACLs). - - - - - - - - - -------------- Example 3 -------------- - - - - PS C:\> Get-Service b* | - Add-AccessControlEntry (New-AccessControlEntry -Principal Users -ServiceAccessRights Start, Stop) -WhatIf - - This example pretends to give the 'Users' group Start and Stop rights over -every service that starts with the letter 'b' (it only pretends because the --WhatIf switch is was supplied). The example demonstrates that -Add-AccessControlEntry can work against multiple objects being piped into it. - -The previous command used the New-AccessControlEntry function to create an ACE -object that was passed to the -AceObject positional parameter. The following -command does the same thing, but using the New-AccessControlEntry parameters -directly: - -PS C:\> Get-Service b* | - Add-AccessControlEntry -Principal Users -ServiceAccessRights Start, Stop -WhatIf - - - - - - - - - -------------- Example 4 -------------- - - - - PS C:\> Add-AccessControlEntry -Path HKCU:\Software\SubKey -Principal GoodUser -RegistryRights FullControl -PassThru | Add-AccessControlEntry -Principal BadUser -RegistryRights FullControl -AceType AccessDenied -Apply - - This example will add two new discretionary ACEs to the HKCU:\Software\SubKey registry key: an ACE giving the 'GoodUser' user full control, and an ACE denying the 'BadUser' user full control. Note the use of -PassThru in the first call to Add-AccessControlEntry. This allows multiple changes to the security descriptor in a single line. - - - - - - - - - -------------- Example 5 -------------- - - - - PS C:\> Get-SecurityDescriptor C:\Folder -Audit | Add-AccessControlEntry -AceType SystemAudit -Principal Everyone -FolderRights FullControl -AuditSuccess -AuditFailure -PassThru | Set-SecurityDescriptor -Sections Audit -WhatIf - - This example adds a system ACE (auditing) entry to the security descriptor for the 'C:\Folder' folder. First, Get-SecurityDescriptor is called with the -Audit switch to get the current security descriptor (the owner, group, DACL, and SACL will all be obtained). That is passed to Add-AccessControlEntry through the pipeline, and it is provided with parameters to create an ACE that will audit any successful or failed actions against the folder. Add-AccessControlEntry is also called with the -PassThru switch, which allows Set-SecurityDescriptor to receive the modified security descriptor through the pipeline. Set-SecurityDescriptor is called with the -Sections parameter set to 'Audit', which means only the SACL is written (in this example, since none of the other security descriptor sections changed, there would be no harm in leaving the -Sections parameter out of the call). - -Since the -WhatIf parameter was provided, no permanent changes will be made. - - - - - - - - - -------------- Example 6 -------------- - - - - PS C:\> Get-WmiObject __SystemSecurity | Add-AccessControlEntry (New-AccessControlEntry -Principal User1 -WmiNamespaceRights RemoteEnable) - - This example gives the 'User1' user the 'RemoteEnable' right on the root/cimv2 namespace (since no namespace was provided to Get-WmiObject). This allows 'User1' to use Get-WmiObject and/or Get-CimInstance remotely against this computer (there's one more required step; see note below). The Get-WmiObject call could have provided the -ComputerName parameter and included a remote computer (or computers), too. - -You could confirm the change by calling this command: -Get-WmiObject __SystemSecurity | Get-AccessControlEntry - -In order to use Get-WmiObject and/or Get-CimInstance without admin privileges, you must add the user to a local group on the remote computer. This module can actually be used to make the necessary changes, but adding the user to one of these groups easier: - - For Get-WmiObject, add user to 'Distributed COM Users' local group - - For Get-CimInstance, add user to 'WinRMRemoteWMIUsers__' local group - - - - - - - - - -------------- Example 7 -------------- - - - - PS C:\> Get-Process calc | Add-AccessControlEntry -Principal TestUser -ProcessAccessRights AllAccess -WhatIf - - This gives the 'TestUser' 'AllAccess' rights to any calc.exe processes (the user that runs this command must already have 'AllAccess' rights over the processes. - - - - - - - - - -------------- Example 8 -------------- - - - - PS C:\> $Demo = New-Item -Path "$env:TEMP\pac_demo" -ItemType directory -PS C:\> $Demo | Add-AccessControlEntry -Principal Users -FolderRights Read -Force -PS C:\> $Demo | Add-AccessControlEntry -Principal Users -FolderRights ExecuteFile -PS C:\> $Demo | Add-AccessControlEntry -Principal Users -FolderRights Write - - This example calls Add-AccessControlEntry three separate times to give three separate rights to the 'Users' group. After all three calls, there should be a single ACE that gives 'Users' 'ReadAndExecute' and 'Write' rights. Since the -Overwrite switch wasn't specified, the ACEs were merged. - - - - - - - - - -------------- Example 9 -------------- - - - - PS C:\> $Demo = New-Item -Path "$env:TEMP\pac_demo" -ItemType directory -PS C:\> $Demo | Add-AccessControlEntry -Principal Users -FolderRights Read -Force -PS C:\> $Demo | Add-AccessControlEntry -Principal Users -FolderRights ExecuteFile -Overwrite -PS C:\> $Demo | Add-AccessControlEntry -Principal Users -FolderRights Write -Overwrite - - This is very similar to example 8, except the -Overwrite switch is specified. That means that after the second call to Add-AccessControlEntry, the allow ACE for 'Users' contains only the 'ExecuteFile' right, and after the last call, the ACE contains only the 'Write' right. Each time the function is called with the -Overwrite switch, the new ACE overwrites any existing ACEs. - - - - - - - - - - - about_PowerShellAccessControl_Module - - - - Get-SecurityDescriptor - - - - Set-SecurityDescriptor - - - - New-AccessControlEntry - - - - Remove-AccessControlEntry - - - - - - - - ConvertFrom-Win32SecurityDescriptor - - - - - - - ConvertFrom - Win32SecurityDescriptor - - - - - - - - - ConvertFrom-Win32SecurityDescriptor - - InputObject - - - - Object - - - Sddl - - - - SwitchParameter - - - BinarySD - - - - SwitchParameter - - - SddlOld - - - - SwitchParameter - - - BinarySDOld - - - - SwitchParameter - - - - - - InputObject - - - - Object - - Object - - - - - - Sddl - - - - SwitchParameter - - SwitchParameter - - - - - - BinarySD - - - - SwitchParameter - - SwitchParameter - - - - - - SddlOld - - - - SwitchParameter - - SwitchParameter - - - - - - BinarySDOld - - - - SwitchParameter - - SwitchParameter - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - about_PowerShellAccessControl_Module - - - - Get-Win32SecurityDescriptor - - - - ConvertTo-Win32SecurityDescriptor - - - - - - - - ConvertTo-Win32SecurityDescriptor - - Converts an SDDL or binary form of a security descriptor into an instance of the Win32_SecurityDescriptor WMI class. - - - - - ConvertTo - Win32SecurityDescriptor - - - - - The ConvertTo-Win32SecurityDescriptor function is used to convert an SDDL or -binary form of a security descriptor into an instance of the -Win32_SecurityDescriptor WMI class. By default, the function returns a custom -object that includes the original SDDL or binary form, along with the -Win32_SecurityDescriptor form. The Descriptor property contains the -Win32_SecurityDescriptor object. If the -ValueOnly switch is provided, though, -the output object is either a CimInstance or ManagementBaseObject containing -just the Win32_SecurityDescriptor. - -By default, the function returns a CimInstance on PowerShell instances running -version 3 or higher. On version 2, a ManagementBaseObject is returned. To force -a ManagementBaseObject to be returned, use the -LegacyWmiObject switch. - - - - - ConvertTo-Win32SecurityDescriptor - - Sddl - - A string containing the SDDL representation of a security descriptor. This -string will be converted to a Win32_SecurityDescriptor object. - - String - - - ValueOnly - - Instead of returning a custom object that contains the Win32_SecurityDescriptor -object as a property, this switch will make the function return just the -Win32_SecurityDescriptor object. - - SwitchParameter - - - LegacyWmiObject - - By default, the function uses the newer "CIM cmdlets" to do the conversion, and -a CimInstance object is returned. Using this switch makes the function use the -older "WMI cmdlets", which causes a ManagementBaseObject to be returned. - - SwitchParameter - - - - ConvertTo-Win32SecurityDescriptor - - BinarySD - - A byte array containing the bianry representation of a security descriptor. -This byte array will be converted to a Win32_SecurityDescriptor object. - - Byte[] - - - ValueOnly - - Instead of returning a custom object that contains the Win32_SecurityDescriptor -object as a property, this switch will make the function return just the -Win32_SecurityDescriptor object. - - SwitchParameter - - - LegacyWmiObject - - By default, the function uses the newer "CIM cmdlets" to do the conversion, and -a CimInstance object is returned. Using this switch makes the function use the -older "WMI cmdlets", which causes a ManagementBaseObject to be returned. - - SwitchParameter - - - - - - Sddl - - A string containing the SDDL representation of a security descriptor. This -string will be converted to a Win32_SecurityDescriptor object. - - String - - String - - - - - - ValueOnly - - Instead of returning a custom object that contains the Win32_SecurityDescriptor -object as a property, this switch will make the function return just the -Win32_SecurityDescriptor object. - - SwitchParameter - - SwitchParameter - - - - - - LegacyWmiObject - - By default, the function uses the newer "CIM cmdlets" to do the conversion, and -a CimInstance object is returned. Using this switch makes the function use the -older "WMI cmdlets", which causes a ManagementBaseObject to be returned. - - SwitchParameter - - SwitchParameter - - - - - - BinarySD - - A byte array containing the bianry representation of a security descriptor. -This byte array will be converted to a Win32_SecurityDescriptor object. - - Byte[] - - Byte[] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -------------- Example 1 -------------- - - - - PS C:\> ConvertTo-Win32SecurityDescriptor -BinarySD (Get-Acl 'C:\Program Files').GetSecurityDescriptorBinaryForm() -ValueOnly - - This example gets the binary form of the security descriptor for the -'C:\Program Files' folder and converts it to a Win32_SecurityDescriptor object. - - - - - - - - - - -------------- Example 2 -------------- - - - - PS C:\> (Get-SecurityDescriptor 'C:\Program Files').Sddl | ConvertTo-Win32SecurityDescriptor -LegacyWmiObject -ValueOnly - - This example gets the SDDL form of the security descriptor for the -'C:\Program Files' folder and converts it to a Win32_SecurityDescriptor object. - - - - - - - - - - - - about_PowerShellAccessControl_Module - - - - Get-Win32SecurityDescriptor - - - - ConvertFrom-Win32SecurityDescriptor - - - - - - - - Disable-AclInheritance - - Disables inheritance for discretionary and system ACLs on security descriptors. - - - - - Disable - AclInheritance - - - - - The Disable-AclInheritance function disables inheritance for both discretionary -(access) and system (auditing) access control lists. If it is called without -the -DiscretionaryAcl and -SystemAcl switches (aliased as -Access and -Audit, -respectively), the function will behave as if the -DiscretionaryAcl switch was -provided, and the DACL inheritance will be disabled. - -The function takes as input any combination of the following: -1. Security descriptors from Get-Acl -2. Security descriptors from the PowerShellAccessControl module - (Get-SecurityDescriptor/New-AdaptedSecurityDescriptor) -3. Certain types of objects or strings (when you pass a string or an object, - the function attempts to call Get-SecurityDescriptor on the input, so this - is technically the same as #2) - -This function does the opposite of the Enable-AclInheritance function. - - - - Disable-AclInheritance - - InputObject - - The security descriptor object whose inheritance will be disabled. This can be -a security descriptor object obtained from Get-SecurityDescriptor or -New-AdaptedSecurityDescriptor, a security descriptor object obtained from the -native Get-Acl cmdlet, or an object (or string representation of a path to an -object) that Get-SecurityDescriptor can work with. - - Object - - - DiscretionaryAcl - - Causes inheritance to be changed for the discretionary ACL (access). This -switch can be used at the same time as the -SystemAcl switch. If neither switch -is provided, the function behaves as if this switch was provided. - - SwitchParameter - - - SystemAcl - - Causes inheritance to be changed for the system ACL (auditing). This switch can -be used at the same time as the -DiscretionaryAcl switch. If neither switch is -provided, the function behaves as if the -DiscretionaryAcl switch was provided. - - SwitchParameter - - - Apply - - Causes the change to the security descriptor to be saved. By default, when a -security descriptor object is provided as input to the InputObject parameter, -the in memory security descriptor is changed, and a separate function or cmdlet -call is required to save the change. Using the -Apply switch causes the change -to be made without a separate function or cmdlet call. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PreserveExistingAces - - Converts any inherited ACEs to explicitly defined entries. If this switch isn't -provided a prompt is displayed asking for the expected behavior (unless the --Force switch is provided). The default behavior is to not explicitly define -any previously inherited ACEs. - - SwitchParameter - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Disable-AclInheritance - - Path - - Specifies the path to a resource whose inheritance is to be changed. - - String[] - - - DiscretionaryAcl - - Causes inheritance to be changed for the discretionary ACL (access). This -switch can be used at the same time as the -SystemAcl switch. If neither switch -is provided, the function behaves as if this switch was provided. - - SwitchParameter - - - SystemAcl - - Causes inheritance to be changed for the system ACL (auditing). This switch can -be used at the same time as the -DiscretionaryAcl switch. If neither switch is -provided, the function behaves as if the -DiscretionaryAcl switch was provided. - - SwitchParameter - - - Apply - - Causes the change to the security descriptor to be saved. By default, when a -security descriptor object is provided as input to the InputObject parameter, -the in memory security descriptor is changed, and a separate function or cmdlet -call is required to save the change. Using the -Apply switch causes the change -to be made without a separate function or cmdlet call. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PreserveExistingAces - - Converts any inherited ACEs to explicitly defined entries. If this switch isn't -provided a prompt is displayed asking for the expected behavior (unless the --Force switch is provided). The default behavior is to not explicitly define -any previously inherited ACEs. - - SwitchParameter - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Disable-AclInheritance - - LiteralPath - - Specifies the path to a resource whose inheritance is to be changed. - -Unlike Path, the value of the LiteralPath parameter is used exactly as it is -typed. No characters are interpreted as wildcards. If the path includes escape -characters, enclose it in single quotation marks. Single quotation marks tell -Windows PowerShell not to interpret any characters as escape sequences. - - String[] - - - DiscretionaryAcl - - Causes inheritance to be changed for the discretionary ACL (access). This -switch can be used at the same time as the -SystemAcl switch. If neither switch -is provided, the function behaves as if this switch was provided. - - SwitchParameter - - - SystemAcl - - Causes inheritance to be changed for the system ACL (auditing). This switch can -be used at the same time as the -DiscretionaryAcl switch. If neither switch is -provided, the function behaves as if the -DiscretionaryAcl switch was provided. - - SwitchParameter - - - Apply - - Causes the change to the security descriptor to be saved. By default, when a -security descriptor object is provided as input to the InputObject parameter, -the in memory security descriptor is changed, and a separate function or cmdlet -call is required to save the change. Using the -Apply switch causes the change -to be made without a separate function or cmdlet call. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PreserveExistingAces - - Converts any inherited ACEs to explicitly defined entries. If this switch isn't -provided a prompt is displayed asking for the expected behavior (unless the --Force switch is provided). The default behavior is to not explicitly define -any previously inherited ACEs. - - SwitchParameter - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - - - InputObject - - The security descriptor object whose inheritance will be disabled. This can be -a security descriptor object obtained from Get-SecurityDescriptor or -New-AdaptedSecurityDescriptor, a security descriptor object obtained from the -native Get-Acl cmdlet, or an object (or string representation of a path to an -object) that Get-SecurityDescriptor can work with. - - Object - - Object - - - - - - DiscretionaryAcl - - Causes inheritance to be changed for the discretionary ACL (access). This -switch can be used at the same time as the -SystemAcl switch. If neither switch -is provided, the function behaves as if this switch was provided. - - SwitchParameter - - SwitchParameter - - - True - - - SystemAcl - - Causes inheritance to be changed for the system ACL (auditing). This switch can -be used at the same time as the -DiscretionaryAcl switch. If neither switch is -provided, the function behaves as if the -DiscretionaryAcl switch was provided. - - SwitchParameter - - SwitchParameter - - - - - - Apply - - Causes the change to the security descriptor to be saved. By default, when a -security descriptor object is provided as input to the InputObject parameter, -the in memory security descriptor is changed, and a separate function or cmdlet -call is required to save the change. Using the -Apply switch causes the change -to be made without a separate function or cmdlet call. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor. - - SwitchParameter - - SwitchParameter - - - - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - SwitchParameter - - - - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - SwitchParameter - - - - - - PreserveExistingAces - - Converts any inherited ACEs to explicitly defined entries. If this switch isn't -provided a prompt is displayed asking for the expected behavior (unless the --Force switch is provided). The default behavior is to not explicitly define -any previously inherited ACEs. - - SwitchParameter - - SwitchParameter - - - - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - SwitchParameter - - - - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - SwitchParameter - - - - - - Path - - Specifies the path to a resource whose inheritance is to be changed. - - String[] - - String[] - - - - - - LiteralPath - - Specifies the path to a resource whose inheritance is to be changed. - -Unlike Path, the value of the LiteralPath parameter is used exactly as it is -typed. No characters are interpreted as wildcards. If the path includes escape -characters, enclose it in single quotation marks. Single quotation marks tell -Windows PowerShell not to interpret any characters as escape sequences. - - String[] - - String[] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -------------- Example 1 -------------- - - - - PS C:\> Get-SecurityDescriptor HKCU:\Software\Subkey | Disable-AclInheritance -PassThru - - This example gets the security descriptor for the HKCU:\Software\Subkey -registry key, then disables the discretionary ACL inheritance. Since the --PreserveExistingAces switch was not specified, the user will be prompted about -what to do with the existing inherited ACEs. A value of $true or $false can be -provided to the switch: -PreserveExistingAces:$false - - - - - - - - - - -------------- Example 2 -------------- - - - - PS C:\> Get-Item HKCU:\Software\Subkey | Disable-AclInheritance -DiscretionaryAcl -PreserveExistingAces -PassThru - - This does the same thing as example #1, except a RegistryKey item is passed to -the function through the pipeline instead of a security descriptor object. -Also, existing inherited ACEs are converted to explicit entries since the --PreserveExistingAces switch was specified. The -DiscretionaryAcl switch is -supplied, but it is not necessary since it is the default behavior when neither -the -DiscretionaryAcl or -SystemAcl switches are supplied. - -An alternate way to call the function is to use the -Path parameter: -PS C:\> Disable-AclInheritance -Path HKCU:\Software\Subkey -Apply -Confirm - - - - - - - - - -------------- Example 3 -------------- - - - - PS C:\> $Acl = Get-Acl C:\folder -PS C:\> $Acl | Disable-AclInheritance -PreserveExistingAces:$false -PS C:\> $Acl | Set-Acl - - - This is an example of using the Get-Acl and Set-Acl cmdlets, but letting the -PowerShell Access Control module's functions handle modifying the security -descriptor. Because the -PreserveExistingAces switch was specified, the user -will not be prompted to decide what to do with the existing inherited ACEs. -A value of $false was passed, so inherited ACEs will be removed from the SD. -The following single line command does the same thing, but without -relying on the Set-Acl cmdlet: - -PS C:\> Get-Acl C:\folder | Disable-AclInheritance -PreserveExistingAces:$false -Apply - - - - - - - - - - - - about_PowerShellAccessControl_Module - - - - Enable-AclInheritance - - - - Get-SecurityDescriptor - - - - New-AdaptedSecurityDescriptor - - - - Get-Acl - - - - Set-SecurityDescriptor - - - - - - - - Enable-AclInheritance - - Enables inheritance for discretionary and system ACLs on security descriptors. - - - - - Enable - AclInheritance - - - - - The Enabled-AclInheritance function enables inheritance for both discretionary -(access) and system (auditing) access control lists. If it is called without -the -DiscretionaryAcl and -SystemAcl switches (aliased as -Access and -Audit, -respectively), the function will behave as if the -DiscretionaryAcl switch was -provided, and the DACL inheritance will be enabled. - -The function takes as input any combination of the following: -1. Security descriptors from Get-Acl -2. Security descriptors from the PowerShellAccessControl module - (Get-SecurityDescriptor/New-AdaptedSecurityDescriptor) -3. Certain types of objects or strings (when you pass a string or an object, - the function attempts to call Get-SecurityDescriptor on the input, so this - is technically the same as #2) - -This function does the opposite of the Disable-AclInheritance function. - - - - Enable-AclInheritance - - InputObject - - The security descriptor object whose inheritance will be disabled. This can be -a security descriptor object obtained from Get-SecurityDescriptor or -New-AdaptedSecurityDescriptor, a security descriptor object obtained from the -native Get-Acl cmdlet, or an object (or string representation of a path to an -object) that Get-SecurityDescriptor can work with. - - Object - - - DiscretionaryAcl - - Causes inheritance to be changed for the discretionary ACL (access). This -switch can be used at the same time as the -SystemAcl switch. If neither switch -is provided, the function behaves as if this switch was provided. - - SwitchParameter - - - SystemAcl - - Causes inheritance to be changed for the system ACL (auditing). This switch can -be used at the same time as the -DiscretionaryAcl switch. If neither switch is -provided, the function behaves as if the -DiscretionaryAcl switch was provided. - - SwitchParameter - - - Apply - - Causes the change to the security descriptor to be saved. By default, when a -security descriptor object is provided as input to the InputObject parameter, -the in memory security descriptor is changed, and a separate function or cmdlet -call is required to save the change. Using the -Apply switch causes the change -to be made without a separate function or cmdlet call. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Enable-AclInheritance - - Path - - Specifies the path to a resource whose inheritance is to be changed. - - String[] - - - DiscretionaryAcl - - Causes inheritance to be changed for the discretionary ACL (access). This -switch can be used at the same time as the -SystemAcl switch. If neither switch -is provided, the function behaves as if this switch was provided. - - SwitchParameter - - - SystemAcl - - Causes inheritance to be changed for the system ACL (auditing). This switch can -be used at the same time as the -DiscretionaryAcl switch. If neither switch is -provided, the function behaves as if the -DiscretionaryAcl switch was provided. - - SwitchParameter - - - Apply - - Causes the change to the security descriptor to be saved. By default, when a -security descriptor object is provided as input to the InputObject parameter, -the in memory security descriptor is changed, and a separate function or cmdlet -call is required to save the change. Using the -Apply switch causes the change -to be made without a separate function or cmdlet call. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Enable-AclInheritance - - LiteralPath - - Specifies the path to a resource whose inheritance is to be changed. - -Unlike Path, the value of the LiteralPath parameter is used exactly as it is -typed. No characters are interpreted as wildcards. If the path includes escape -characters, enclose it in single quotation marks. Single quotation marks tell -Windows PowerShell not to interpret any characters as escape sequences. - - String[] - - - DiscretionaryAcl - - Causes inheritance to be changed for the discretionary ACL (access). This -switch can be used at the same time as the -SystemAcl switch. If neither switch -is provided, the function behaves as if this switch was provided. - - SwitchParameter - - - SystemAcl - - Causes inheritance to be changed for the system ACL (auditing). This switch can -be used at the same time as the -DiscretionaryAcl switch. If neither switch is -provided, the function behaves as if the -DiscretionaryAcl switch was provided. - - SwitchParameter - - - Apply - - Causes the change to the security descriptor to be saved. By default, when a -security descriptor object is provided as input to the InputObject parameter, -the in memory security descriptor is changed, and a separate function or cmdlet -call is required to save the change. Using the -Apply switch causes the change -to be made without a separate function or cmdlet call. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - - - InputObject - - The security descriptor object whose inheritance will be disabled. This can be -a security descriptor object obtained from Get-SecurityDescriptor or -New-AdaptedSecurityDescriptor, a security descriptor object obtained from the -native Get-Acl cmdlet, or an object (or string representation of a path to an -object) that Get-SecurityDescriptor can work with. - - Object - - Object - - - - - - DiscretionaryAcl - - Causes inheritance to be changed for the discretionary ACL (access). This -switch can be used at the same time as the -SystemAcl switch. If neither switch -is provided, the function behaves as if this switch was provided. - - SwitchParameter - - SwitchParameter - - - - - - SystemAcl - - Causes inheritance to be changed for the system ACL (auditing). This switch can -be used at the same time as the -DiscretionaryAcl switch. If neither switch is -provided, the function behaves as if the -DiscretionaryAcl switch was provided. - - SwitchParameter - - SwitchParameter - - - - - - Apply - - Causes the change to the security descriptor to be saved. By default, when a -security descriptor object is provided as input to the InputObject parameter, -the in memory security descriptor is changed, and a separate function or cmdlet -call is required to save the change. Using the -Apply switch causes the change -to be made without a separate function or cmdlet call. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor. - - SwitchParameter - - SwitchParameter - - - - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - SwitchParameter - - - - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - SwitchParameter - - - - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - SwitchParameter - - - - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - SwitchParameter - - - - - - Path - - Specifies the path to a resource whose inheritance is to be changed. - - String[] - - String[] - - - - - - LiteralPath - - Specifies the path to a resource whose inheritance is to be changed. - -Unlike Path, the value of the LiteralPath parameter is used exactly as it is -typed. No characters are interpreted as wildcards. If the path includes escape -characters, enclose it in single quotation marks. Single quotation marks tell -Windows PowerShell not to interpret any characters as escape sequences. - - String[] - - String[] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -------------- Example 1 -------------- - - - - PS C:\> Get-SecurityDescriptor HKCU:\Software\Subkey | Enable-AclInheritance -PassThru - - This example gets the security descriptor for the HKCU:\Software\Subkey -registry key, then enables the discretionary ACL inheritance. - - - - - - - - - - -------------- Example 2 -------------- - - - - PS C:\> Get-Item HKCU:\Software\Subkey | Enable-AclInheritance -DiscretionaryAcl -PassThru - - This does the same thing as example #1, except a RegistryKey item is passed to -the function through the pipeline instead of a security descriptor object. The --DiscretionaryAcl switch is supplied, but it is not necessary since it is the -default behavior when neither the -DiscretionaryAcl or -SystemAcl switches are -supplied. - - - - - - - - - - -------------- Example 3 -------------- - - - - PS C:\> Enable-AclInheritance -Path HKCU:\Software\Subkey -Apply -Confirm - - This does the same as example #1, except the path is passed through the -Path -parameter instead of getting the security descriptor and passing it through -the pipeline. Also, the updated security descriptor will be saved without -having to call Set-SecurityDescriptor (if the confirmation prompts are -answered). - - - - - - - - - - -------------- Example 4 -------------- - - - - PS C:\> dir C:\folder -recurse | - Get-SecurityDescriptor -Audit | - Remove-AccessControlEntry -RemoveAllAccessEntries -RemoveAllAuditEntries -PassThru | - Enable-AclInheritance -DiscretionaryAcl -SystemAcl -PassThru | - Set-SecurityDescriptor - - - This will reset the security descriptors for all files and folders under the -C:\folder folder. All explicitly defined discretionary and system ACEs will be -removed, and any entries that apply to child containers and objects from -C:\folder are propagated to child containers and objects. - - - - - - - - - - -------------- Example 5 -------------- - - - - PS C:\> $Acl = Get-Acl C:\folder -PS C:\> $Acl | Enable-AclInheritance -PS C:\> $Acl | Set-Acl - - - This is an example of using the Get-Acl and Set-Acl cmdlets, but letting the -PowerShell Access Control module's functions handle modifying the security -descriptor. The following single line command does the same thing, but without -relying on the Set-Acl cmdlet: - -PS C:\> Get-Acl C:\folder | Enable-AclInheritance -Apply - - - - - - - - - - - - about_PowerShellAccessControl_Module - - - - Disable-AclInheritance - - - - Get-SecurityDescriptor - - - - New-AdaptedSecurityDescriptor - - - - Get-Acl - - - - Set-SecurityDescriptor - - - - - - - - Get-AccessControlEntry - - Extracts access control entries found in security descriptor access control lists. - - - - - Get - AccessControlEntry - - - - - Get-AccessControlEntry is designed to extract access control entries (ACEs) -from the access control lists (ACLs) of security descriptors (SDs). By default, -it will show ACEs from discretionary ACLs (which deal with allow and deny -access rules) and ACEs from system ACLs (which deal with auditing rules). - -Get-AccessControlEntry can be used with the following types of security -descriptors (see the examples section for more information): -1. Security descriptors from Get-Acl -2. Security descriptors from the PowerShellAccessControl module - (Get-SecurityDescriptor/New-AdaptedSecurityDescriptor) -3. Certain types of objects or strings (when you pass a string or an object, - the function attempts to call Get-SecurityDescriptor on the input, so this - is technically the same as #2) -4. Win32_SecurityDescriptor WMI objects - -Most of the functions parameters are shared with the New-AccessControlEntry -function and are used to filter only requested ACEs. The filtering parameters -can take arrays, and can be combined with other parameters to build complex -filtering conditions. - - - - Get-AccessControlEntry - - InputObject - - Specifies the security descriptor that will have an access control entry added -to it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - Audit - - A switch parameter that ensures that the security descriptor obtained from the --InputObject parameter also includes the object's system access control list -(SACL). This requires administrator privileges in most configurations. - -If the -InputObject contains a property named 'Audit', this switch parameter -is automatically set. To suppress this behavior, $false can be passed to the -switch parameter, e.g., -Audit:$false. - -If the -InputObject is already a security descriptor, this parameter is -ignored, i.e., it is only used when the -InputObject is used to get the -security descriptor, not when the security descriptor has been supplied. - - SwitchParameter - - - Inherited - - When this switch is used, only inherited ACEs will be returned. - - SwitchParameter - - - NotInherited - - When this switch is used, only explicitly defined, i.e., not -inherited, ACEs will be returned. - - SwitchParameter - - - Specific - - A switch parameter that changes the behavior of most of the filtering -conditions provided to the Get-AccessControlEntry function. - -When this switch is specified, the following behaviors change: -- Access masks (including any of the access mask enumerations, e.g., FileRights - RegistryRights, ServiceAccessRights, etc) must match exactly. By default, - a -FileRights value of 'Read' would match an ACE with an access mask of - 'Modify' because 'Read' is a right that 'Modify' contains. When -Specific is - specified, though, matching ACEs would have to have the exact value of 'Read' -- Non access mask enumerations behave the same as access masks (they are, after - all, converted to numeric values) -- When -ObjectAceType and/or -InheritedObjectAceType parameters are specified, - the default behavior of the function is to still return ACEs that don't - include ObjectAceTypes or InheritedObjectAceTypes if the returned ACEs still - technically meet the condition specified. For example, specifying an - -ObjectAceType that applies to a property would allow any ACE that allows - reading or writing of 'All Properties' would still be returned. If the - -Specific switch is specified, though, the returned ACEs would be required - to have an ObjectAceType. - - - SwitchParameter - - - ObjectAceType - - Specifies a property, property set, extended right, validated write, or class -object that matching ACEs must contain. - -The parameter takes a string, a GUID (which can also be a string), or the -output from the Get-ADObjectAceGuid function. If a string or GUID is provided, -the Get-ADObjectAceGuid function is called internally. - -If the -Specific switch is not specified, matching ACEs might not contain an -ObjectAceType. For example, if the 'Password-Reset' extended right was -provided, ACEs that allow 'All Extended Rights' (ACEs that provide the -'Extended Right' permission without an ObjectAceType) would be returned. When -the -Specific switch is provided with this parameter, all matching ACEs must -contain an ObjectAceType. - - Object[] - - - InheritedObjectAceType - - Specifies a class object that matching ACEs must apply to. - -The parameter takes a string, a GUID (which can also be a string), or the -output from the Get-ADObjectAceGuid function. If a string or GUID is provided, -the Get-ADObjectAceGuid function is called internally. - -If the -Specific switch is not specified, matching ACEs might not contain an -InheritedObjectAceType. For example, if the 'user' object was provided as -input, ACEs that have no InheritedObjectAceType would be returned since those -ACEs would apply to all objects. If the -Specific switch is specified, though, -all matching ACEs would have to have an InheritedObjectAceType property, and -they would have to be one of the inputs to the -InheritedObjectAce parameter. - - - Object[] - - - AuditFlags - - Enumeration that specifies the type of audit to filter on. Valid values are -None, Success, and Failure. More than one value can be supplied at a time. - -If the -Specific switch isn't specified, exact matches aren't required. For -example, specifying a value of 'Success' would match an ACE that had an -AuditFlags value of 'Success, Failure'. If the -Specific switch is specified, -though, the previous example would require all ACEs to have the exact -AuditFlags value of 'Success' to be returned. - - AuditFlags - - - AceType - - Specifies the type of ACEs to be returned. Valid values are AccessAllowed, -AccessDenied, and SystemAudit. More than one value can be provided. - - String[] - - - Principal - - One or more principals that matching ACEs must contain. This can be a string -representing a user, group, or SID. It can also be a -[System.Security.Principal.NTAccount] or a -[System.Security.Principal.SecurityIdentifier] object. Wildcards are also -permitted. - - - String[] - - - FileRights - - The same as -AccessMask, except with a file system specific enumeration. - - FileSystemRights - - - FolderRights - - The same as -AccessMask, except with a file system specific enumeration. - - FileSystemRights - - - RegistryRights - - The same as -AccessMask, except with a registry specific enumeration. - - RegistryRights - - - ActiveDirectoryRights - - The same as -AccessMask, except with an Active Directory specific enumeration. - - ActiveDirectoryRights - - - LogicalShareRights - - The same as -AccessMask, except with a share specific enumeration. - - LogicalShareRights - - - PrinterRights - - The same as -AccessMask, except with a printer specific enumeration. - - PrinterRights - - - WmiNameSpaceRights - - The same as -AccessMask, except with a WMI specific enumeration. - - WmiNamespaceRights - - - WsManAccessRights - - - - WsManAccessRights - - - ServiceAccessRights - - The same as -AccessMask, except with a service specific enumeration. - - ServiceAccessRights - - - ProcessAccessRights - - The same as -AccessMask, except with a process specific enumeration. - - ProcessAccessRights - - - AccessMask - - Specifies the numeric access rights that all returned ACEs must contain. This -function has several accessmask enumerations that it will take as input, but -they all are converted to their numeric values. - -If the -Specific switch isn't specified, matching access masks do not need to -exactly match the -AccessMask parameter. For example, if an -AccessMask of -131209 (numeric equivalent of -FileRights Read) is provided, an ACE with an -AccessMask of 197055 (numeric equivalent of -FileRights Modify) would match -that condition since 131209 is completely contained in 197055 (197055 -band -131209 is equal to 131209). If the -Specific switch is specified, though, -the -AccessMask provided would have to exactly match the access mask on an -ACE for the condition to be met. - - - Int32 - - - AppliesTo - - An enumeration that specifies where the returned ACEs apply. Valid values are -Object, ChildContainers, and ChildObjects. - - AppliesTo - - - OnlyApplyToThisContainer - - A switch that specifies whether or not returned ACEs must have the -NoPropagateInherit propagation flag set. - - - SwitchParameter - - - - - - InputObject - - Specifies the security descriptor that will have an access control entry added -to it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - Object - - - - - - Audit - - A switch parameter that ensures that the security descriptor obtained from the --InputObject parameter also includes the object's system access control list -(SACL). This requires administrator privileges in most configurations. - -If the -InputObject contains a property named 'Audit', this switch parameter -is automatically set. To suppress this behavior, $false can be passed to the -switch parameter, e.g., -Audit:$false. - -If the -InputObject is already a security descriptor, this parameter is -ignored, i.e., it is only used when the -InputObject is used to get the -security descriptor, not when the security descriptor has been supplied. - - SwitchParameter - - SwitchParameter - - - - - - Inherited - - When this switch is used, only inherited ACEs will be returned. - - SwitchParameter - - SwitchParameter - - - - - - NotInherited - - When this switch is used, only explicitly defined, i.e., not -inherited, ACEs will be returned. - - SwitchParameter - - SwitchParameter - - - - - - Specific - - A switch parameter that changes the behavior of most of the filtering -conditions provided to the Get-AccessControlEntry function. - -When this switch is specified, the following behaviors change: -- Access masks (including any of the access mask enumerations, e.g., FileRights - RegistryRights, ServiceAccessRights, etc) must match exactly. By default, - a -FileRights value of 'Read' would match an ACE with an access mask of - 'Modify' because 'Read' is a right that 'Modify' contains. When -Specific is - specified, though, matching ACEs would have to have the exact value of 'Read' -- Non access mask enumerations behave the same as access masks (they are, after - all, converted to numeric values) -- When -ObjectAceType and/or -InheritedObjectAceType parameters are specified, - the default behavior of the function is to still return ACEs that don't - include ObjectAceTypes or InheritedObjectAceTypes if the returned ACEs still - technically meet the condition specified. For example, specifying an - -ObjectAceType that applies to a property would allow any ACE that allows - reading or writing of 'All Properties' would still be returned. If the - -Specific switch is specified, though, the returned ACEs would be required - to have an ObjectAceType. - - - SwitchParameter - - SwitchParameter - - - - - - ObjectAceType - - Specifies a property, property set, extended right, validated write, or class -object that matching ACEs must contain. - -The parameter takes a string, a GUID (which can also be a string), or the -output from the Get-ADObjectAceGuid function. If a string or GUID is provided, -the Get-ADObjectAceGuid function is called internally. - -If the -Specific switch is not specified, matching ACEs might not contain an -ObjectAceType. For example, if the 'Password-Reset' extended right was -provided, ACEs that allow 'All Extended Rights' (ACEs that provide the -'Extended Right' permission without an ObjectAceType) would be returned. When -the -Specific switch is provided with this parameter, all matching ACEs must -contain an ObjectAceType. - - Object[] - - Object[] - - - - - - InheritedObjectAceType - - Specifies a class object that matching ACEs must apply to. - -The parameter takes a string, a GUID (which can also be a string), or the -output from the Get-ADObjectAceGuid function. If a string or GUID is provided, -the Get-ADObjectAceGuid function is called internally. - -If the -Specific switch is not specified, matching ACEs might not contain an -InheritedObjectAceType. For example, if the 'user' object was provided as -input, ACEs that have no InheritedObjectAceType would be returned since those -ACEs would apply to all objects. If the -Specific switch is specified, though, -all matching ACEs would have to have an InheritedObjectAceType property, and -they would have to be one of the inputs to the -InheritedObjectAce parameter. - - - Object[] - - Object[] - - - - - - AuditFlags - - Enumeration that specifies the type of audit to filter on. Valid values are -None, Success, and Failure. More than one value can be supplied at a time. - -If the -Specific switch isn't specified, exact matches aren't required. For -example, specifying a value of 'Success' would match an ACE that had an -AuditFlags value of 'Success, Failure'. If the -Specific switch is specified, -though, the previous example would require all ACEs to have the exact -AuditFlags value of 'Success' to be returned. - - AuditFlags - - AuditFlags - - - - - - AceType - - Specifies the type of ACEs to be returned. Valid values are AccessAllowed, -AccessDenied, and SystemAudit. More than one value can be provided. - - String[] - - String[] - - - - - - Principal - - One or more principals that matching ACEs must contain. This can be a string -representing a user, group, or SID. It can also be a -[System.Security.Principal.NTAccount] or a -[System.Security.Principal.SecurityIdentifier] object. Wildcards are also -permitted. - - - String[] - - String[] - - - - - - FileRights - - The same as -AccessMask, except with a file system specific enumeration. - - FileSystemRights - - FileSystemRights - - - - - - FolderRights - - The same as -AccessMask, except with a file system specific enumeration. - - FileSystemRights - - FileSystemRights - - - - - - RegistryRights - - The same as -AccessMask, except with a registry specific enumeration. - - RegistryRights - - RegistryRights - - - - - - ActiveDirectoryRights - - The same as -AccessMask, except with an Active Directory specific enumeration. - - ActiveDirectoryRights - - ActiveDirectoryRights - - - - - - LogicalShareRights - - The same as -AccessMask, except with a share specific enumeration. - - LogicalShareRights - - LogicalShareRights - - - - - - PrinterRights - - The same as -AccessMask, except with a printer specific enumeration. - - PrinterRights - - PrinterRights - - - - - - WmiNameSpaceRights - - The same as -AccessMask, except with a WMI specific enumeration. - - WmiNamespaceRights - - WmiNamespaceRights - - - - - - WsManAccessRights - - - - WsManAccessRights - - WsManAccessRights - - - - - - ServiceAccessRights - - The same as -AccessMask, except with a service specific enumeration. - - ServiceAccessRights - - ServiceAccessRights - - - - - - ProcessAccessRights - - The same as -AccessMask, except with a process specific enumeration. - - ProcessAccessRights - - ProcessAccessRights - - - - - - AccessMask - - Specifies the numeric access rights that all returned ACEs must contain. This -function has several accessmask enumerations that it will take as input, but -they all are converted to their numeric values. - -If the -Specific switch isn't specified, matching access masks do not need to -exactly match the -AccessMask parameter. For example, if an -AccessMask of -131209 (numeric equivalent of -FileRights Read) is provided, an ACE with an -AccessMask of 197055 (numeric equivalent of -FileRights Modify) would match -that condition since 131209 is completely contained in 197055 (197055 -band -131209 is equal to 131209). If the -Specific switch is specified, though, -the -AccessMask provided would have to exactly match the access mask on an -ACE for the condition to be met. - - - Int32 - - Int32 - - - - - - AppliesTo - - An enumeration that specifies where the returned ACEs apply. Valid values are -Object, ChildContainers, and ChildObjects. - - AppliesTo - - AppliesTo - - - - - - OnlyApplyToThisContainer - - A switch that specifies whether or not returned ACEs must have the -NoPropagateInherit propagation flag set. - - - SwitchParameter - - SwitchParameter - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -------------- Example 1 -------------- - - - - PS C:\> Get-Acl C:\Windows | Get-AccessControlEntry - - This will display all discretionary ACEs for the C:\Windows folder. To also -list the system ACEs, the -Audit switch could be provided to the Get-Acl -command. - -Get-Acl isn't required to view the ACEs for C:\Windows. The following -commands produce identical results: - -PS C:\> Get-SecurityDescriptor C:\Windows | Get-AccessControlEntry -PS C:\> Get-AccessControlEntry C:\Windows -PS C:\> "C:\Windows" | Get-AccessControlEntry -PS C:\> Get-Item C:\Windows | Get-AccessControlEntry -PS C:\> $Acl = Get-Acl C:\Windows; $Acl | Get-AccessControlEntry - -To have system ACEs also returned, the -Audit switch can be provided to the -previous commands: - -PS C:\> Get-SecurityDescriptor C:\Windows -Audit | Get-AccessControlEntry -PS C:\> Get-AccessControlEntry C:\Windows -Audit -PS C:\> "C:\Windows" | Get-AccessControlEntry -Audit -PS C:\> Get-Item C:\Windows | Get-AccessControlEntry -Audit -PS C:\> $Acl = Get-Acl C:\Windows -Audit; $Acl | Get-AccessControlEntry - - - - - - - - - -------------- Example 2 -------------- - - - - PS C:\> Get-AccessControlEntry HKLM:\Software, C:\Windows, (Get-Service bits) - - This example shows that Get-AccessControlEntry can take multiple objects, and -the object types don't have to match. The previous command would list all -discretionary ACEs for the specified registry key, folder, and service. - -The inputs could have been piped into the function, too, either as strings or -objects from Get-Item (the service was already an object). - - - - - - - - - -------------- Example 3 -------------- - - - - PS C:\> Get-Service | select -First 5 | - Get-AccessControlEntry -ServiceAccessRights Start, Stop - - This example gets the first five services returned from Get-Service and lists -the ACEs that include Start and Stop access rights. Since the -Specific switch -wasn't specified, ACEs with access rights that include more than Start and Stop -are also returned, e.g., ACEs with FullControl rights will be returned, too. - -There is no limit to the number of filtering parameters that can be used. The -following command adds on to the previous command, but it only includes ACEs -that have a principal that contains the word 'Users' and the 'Everyone' group: - -PS C:\> Get-Service | - Get-AccessControlEntry -ServiceAccessRights Start, Stop -Principal *Users*, Everyone - - - - - - - - - -------------- Example 4 -------------- - - - - PS C:\> dir C:\powershell -Recurse | - Get-AccessControlEntry -Audit -NotInherited -AceType SystemAudit -AuditFlags Failure -Specific - - This example recursively checks all subfolders and files of a directory called -'C:\powershell'. The function is being called with the -Audit switch, so the -SACL of each file or folder will be obtained. The function is also filtering -the returned ACEs so that only explicitly defined audit ACEs that are only -auditing failures will be returned. ACEs that are set to audit failures and -successes will not be returned because the -Specific switch was used. Without -that switch, those ACEs would be returned. - - - - - - - - - -------------- Example 5 -------------- - - - - PS C:\> Get-WmiObject Win32_Share | Get-AccessControlEntry -ErrorAction SilentlyContinue - - This will list the share permissions for all shares on the local computer. You -could also use the -ComputerName parameter on the Get-WmiObject cmdlet to view -the share permissions for a remote computer. - -To view the NTFS permissions of the share, the command can be modified so -that the object being piped into Get-AccessControlEntry isn't a Win32_Share -object. Either of these commands should show the NTFS permissions: - -PS C:\> Get-WmiObject Win32_Share | select Path | Get-AccessControlEntry -ErrorAction SilentlyContinue -PS C:\> Get-WmiObject Win32_Share | select -ExpandProperty Path | Get-AccessControlEntry -ErrorAction SilentlyContinue - - - - - - - - - -------------- Example 6 -------------- - - - - PS C:\> Get-SecurityDescriptor \\$env:COMPUTERNAME -ObjectType Printer | Get-AccessControlEntry - - Get-AccessControlEntry can't get every type of security descriptor. Calling -Get-SecurityDescriptor first gives you more control over the SD to retrieve. -This example gets the print server SD for the local computer. - - - - - - - - - -------------- Example 7 -------------- - - - - PS C:\> $SD = Get-ADUser $env:username | Get-SecurityDescriptor -PS C:\> $SD | Get-AccessControlEntry - - - This example requires the ActiveDirectory module as written. If you do not have -this module, you can still use either an [adsi] object, or a string -representation of the distinguished name for your user object. Simply pass -either of those to the Get-SecurityDescriptor or Get-AccessControlEntry -functions. - -The previous command will show all discretionary ACEs for the current user's -AD user object. AD objects generally have much larger ACLs than other securable -objects, so there should be several ACEs returned. - -Get-AccessControlEntry can be used to filter the returned ACEs. Here are some -examples of filtering: - -PS C:\> $SD | Get-AccessControlEntry -Principal *Admin*,Self, *Users - -That will show ACEs that apply to principals that contain the work 'Admin', the -'Self' principal, and/or principals that end in 'Users'. - -PS C:\> $SD | Get-AccessControlEntry -ObjectAceType (Get-ADObjectAceGuid -Name * -TypesToSearch ExtendedRight) - -This will show only ACEs that apply to extended rights. That includes ACEs that -apply to specific extended rights and 'All Extended Rights'. To only show ACEs -that apply to specific extended rights (not 'All Extended Rights'), include the --Specific switch. - -NOTE: The Get-AccessControlEntry function builds a custom filtering script - block based on the filtering parameters. Because of the design, filtering - using the Get-ADObjectAceGuid function as input to -ObjectAceType is not - recommended. It is recommended to supply one or more GUIDs or strings - (wildcards are allowed). This example wouldn't work if the -TypesToSearch - included 'Propery' or 'ClassObject' because the filtering script block - would be too large. - -PS C:\> $SD | Get-AccessControlEntry -ObjectAceType 00299570-246d-11d0-a768-00aa006e0529,Change-Password -InheritedObjectAceType user -PS C:\> $SD | Get-AccessControlEntry -ObjectAceType 00299570-246d-11d0-a768-00aa006e0529,Change-Password -InheritedObjectAceType user -Specific - -Those examples will show ACEs that deal with the Reset-Password extended right -(the GUID that's being passed to -ObjectAceType) and the Change-Password -extended right (technically, it will match on any -ObjectAceType that has a -friendly name of 'Change-Password' since a string was provided) and that apply -to 'user' objects. The first one will return ACEs that apply to all objects -(because all objects includes 'user' objects) and 'All Extended Rights', -FullControl, or any other access mask that includes access to extended rights -without a specific ObjectAceType. The second one (with the -Specific switch), -will exclude ACEs that apply to all objects (the ACE MUST apply only to 'user' -objects) and ACEs that don't have an ObjectAceType (so FullControl, etc ACEs -will not be included in the results). - -PS C:\> $SD | Get-AccessControlEntry -ObjectAceType "(Change|Reset)-Password" - -Returns ACEs with an ObjectAceType of Change-Password or Reset-Password, or -that have an access mask that allow 'Perform All Extended Rights'. It's an -example of using a regular expression as the input to -ObjectAceType. - - - - - - - - - - -------------- Example 8 -------------- - - - - PS C:\> Invoke-CimMethod -ClassName __SystemSecurity -MethodName GetSecurityDescriptor | - select -exp Descriptor | - Get-AccessControlEntry - - - This gets a Win32_SecurityDescriptor (technically a __SecurityDescriptor) WMI -object for the root/CIMV2 WMI namespace, and the raw WMI object is passed to -Get-AccessControlEntry. Unfortunately, the results will not show a descriptive -display name or access masks (all access masks will be numeric). - - - - - - - - - - - - about_PowerShellAccessControl_Module - - - - Get-SecurityDescriptor - - - - Get-Acl - - - - - - - - Get-ADObjectAceGuid - - Used to lookup the names and/or GUIDs of Active Directory extended rights, -properties, property sets, validated writes, and object classes. - - - - - - Get - ADObjectAceGuid - - - - - The Get-ADObjectAceGuid function is used to lookup the names and/or GUIDs of -Active Directory extended rights, properties, property sets, validated writes, -and object classes. Active Directory access control lists (ACLs) can have -object access control entries (ACEs) that deal with these special types, and -this function can be used to create or decode those ACEs. - -New-AccessControlEntry, Add-AccessControlEntry, Remove-AccessControlEntry, and -Get-AccessControlEntry will call this function internally when a string is -provided to the -ObjectAceType or -InheritedObjectAceType properties (the '*' -wildcard is allowed). - -This function can also be called directly, and in PowerShell version 3 or -higher, IntelliSense will help get a single GUID. Type the following command -in the version 3 or higher ISE, and notice the autocompletion: - -Get-ADObjectAceGuid -ExtendedRight - -NOTE: This function must be run from a computer that is joined to a domain. - - - - Get-ADObjectAceGuid - - TypesToSearch - - This parameter allows the ObjectAceType search to be limited to certain types. -By default, all types will be searched by the -Name or -Guid provided. - - - String[] - - - Name - - The friendly name of an ObjectAceType to lookup. Wildcards (*) are allowed. - - String - - - - Get-ADObjectAceGuid - - Guid - - The GUID of an ObjectAceType to lookup. - - Guid - - - TypesToSearch - - This parameter allows the ObjectAceType search to be limited to certain types. -By default, all types will be searched by the -Name or -Guid provided. - - - String[] - - - Name - - The friendly name of an ObjectAceType to lookup. Wildcards (*) are allowed. - - String - - - - Get-ADObjectAceGuid - - ExtendedRight - - A switch parameter that will cause the dynamic -Name parameter to only take -valid extended rights. When used in PowerShell version 3 or higher, tab -completion and/or IntelliSense makes this very useful. Typing this at the -command line should allow tab completion or IntelliSense to kick in (the -pipe symbol represents where the cursor should be): - -Get-ADObjectAceGuid -ExtendedRight | - - - SwitchParameter - - - Name - - The friendly name of an ObjectAceType to lookup. Wildcards (*) are allowed. - - String - - - - Get-ADObjectAceGuid - - ValidatedWrite - - A switch parameter that will cause the dynamic -Name parameter to only take -valid validated writes. When used in PowerShell version 3 or higher, tab -completion and/or IntelliSense makes this very useful. Typing this at the -command line should allow tab completion or IntelliSense to kick in (the -pipe symbol represents where the cursor should be): - -Get-ADObjectAceGuid -ValidatedWrite | - - - SwitchParameter - - - Name - - The friendly name of an ObjectAceType to lookup. Wildcards (*) are allowed. - - String - - - - Get-ADObjectAceGuid - - Property - - A switch parameter that will cause the dynamic -Name parameter to only take -valid property names. When used in PowerShell version 3 or higher, tab -completion and/or IntelliSense makes this very useful. Typing this at the -command line should allow tab completion or IntelliSense to kick in (the -pipe symbol represents where the cursor should be): - -Get-ADObjectAceGuid -Property | - - - SwitchParameter - - - Name - - The friendly name of an ObjectAceType to lookup. Wildcards (*) are allowed. - - String - - - - Get-ADObjectAceGuid - - PropertySet - - A switch parameter that will cause the dynamic -Name parameter to only take -valid property set names. When used in PowerShell version 3 or higher, tab -completion and/or IntelliSense makes this very useful. Typing this at the -command line should allow tab completion or IntelliSense to kick in (the -pipe symbol represents where the cursor should be): - -Get-ADObjectAceGuid -PropertySet | - - - SwitchParameter - - - Name - - The friendly name of an ObjectAceType to lookup. Wildcards (*) are allowed. - - String - - - - Get-ADObjectAceGuid - - ClassObject - - A switch parameter that will cause the dynamic -Name parameter to only take -valid class object names. When used in PowerShell version 3 or higher, tab -completion and/or IntelliSense makes this very useful. Typing this at the -command line should allow tab completion or IntelliSense to kick in (the -pipe symbol represents where the cursor should be): - -Get-ADObjectAceGuid -ClassObject | - - - SwitchParameter - - - Name - - The friendly name of an ObjectAceType to lookup. Wildcards (*) are allowed. - - String - - - - - - TypesToSearch - - This parameter allows the ObjectAceType search to be limited to certain types. -By default, all types will be searched by the -Name or -Guid provided. - - - String[] - - String[] - - - - - - Name - - The friendly name of an ObjectAceType to lookup. Wildcards (*) are allowed. - - String - - String - - - - - - Guid - - The GUID of an ObjectAceType to lookup. - - Guid - - Guid - - - - - - ExtendedRight - - A switch parameter that will cause the dynamic -Name parameter to only take -valid extended rights. When used in PowerShell version 3 or higher, tab -completion and/or IntelliSense makes this very useful. Typing this at the -command line should allow tab completion or IntelliSense to kick in (the -pipe symbol represents where the cursor should be): - -Get-ADObjectAceGuid -ExtendedRight | - - - SwitchParameter - - SwitchParameter - - - - - - ValidatedWrite - - A switch parameter that will cause the dynamic -Name parameter to only take -valid validated writes. When used in PowerShell version 3 or higher, tab -completion and/or IntelliSense makes this very useful. Typing this at the -command line should allow tab completion or IntelliSense to kick in (the -pipe symbol represents where the cursor should be): - -Get-ADObjectAceGuid -ValidatedWrite | - - - SwitchParameter - - SwitchParameter - - - - - - Property - - A switch parameter that will cause the dynamic -Name parameter to only take -valid property names. When used in PowerShell version 3 or higher, tab -completion and/or IntelliSense makes this very useful. Typing this at the -command line should allow tab completion or IntelliSense to kick in (the -pipe symbol represents where the cursor should be): - -Get-ADObjectAceGuid -Property | - - - SwitchParameter - - SwitchParameter - - - - - - PropertySet - - A switch parameter that will cause the dynamic -Name parameter to only take -valid property set names. When used in PowerShell version 3 or higher, tab -completion and/or IntelliSense makes this very useful. Typing this at the -command line should allow tab completion or IntelliSense to kick in (the -pipe symbol represents where the cursor should be): - -Get-ADObjectAceGuid -PropertySet | - - - SwitchParameter - - SwitchParameter - - - - - - ClassObject - - A switch parameter that will cause the dynamic -Name parameter to only take -valid class object names. When used in PowerShell version 3 or higher, tab -completion and/or IntelliSense makes this very useful. Typing this at the -command line should allow tab completion or IntelliSense to kick in (the -pipe symbol represents where the cursor should be): - -Get-ADObjectAceGuid -ClassObject | - - - SwitchParameter - - SwitchParameter - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Switch parameters control what type of lookup is performed. The 'Name' -parameter is dynamic, and its possible values change depending on the switch -provided. - - - - - - -------------- Example 1 -------------- - - - - PS C:\> Get-ADObjectAceGuid -ExtendedRight Unexpire-Password - - This looks up the ObjectAceType for the 'Unexpire-Password' extended right. The -returned object will contain the GUID, the name, and the type, which in this -example is 'ExtendedRight'. In PowerShell version 3 or higher, IntelliSense and -tab completion are available after pressing space after the -ExtendedRight -switch has been provided. - - - - - - - - - - -------------- Example 2 -------------- - - - - PS C:\> Get-ADObjectAceGuid *Password - - - This example searches for any ObjectAceTypes that end in the word 'Password'. -The results will include 'Unexpire-Password' from the previous example. There -will be several other results, not necessarily all extended rights like the -previous example. - - - - - - - - - - -------------- Example 3 -------------- - - - - PS C:\> Get-ADObjectAceGuid *Password -TypesToSearch ExtendedRight, Property - - This example searches for any ObjectAceTypes that end in the word 'Password'. -The results will only include extended rights and properties because the --TypesToSearch parameter was specified. - - - - - - - - - - - - about_PowerShellAccessControl_Module - - - - New-AccessControlEntry - - - - Add-AccessControlEntry - - - - Remove-AccessControlEntry - - - - Get-AccessControlEntry - - - - - - - - Get-EffectiveAccess - - Gets the effective access rights for a securable object. - - - - - Get - EffectiveAccess - - - - - The Get-EffectiveAccess function determines the effective access to a specified -principal for a given set of security descriptors or securable objects. By -default, the function returns a custom object that contains the display name -for the securable object (DisplayName), the principal whose access is being -checked (IdentityReference), and a string representation of the effective -rights the principal has to the securable object (EffectiveAccess). - -If the -ListAllRights switch is specified, the function's output changes. -Multiple objects are returned for each principal, each with the following -properties: the principal whose access is being checked (IdentityReference), -the display name for the securable object (DisplayName), a string -representation of a single permission from the object's access mask -enumeration (Permission), a boolean property showing whether or not the -permission is granted (Allowed), and a property showing why the permission was -denied, if it was denied (LimitedBy). - -If any -ObjectAceTypes are specified (for Active Directory objects), then extra -custom objects are returned. When the -ListAllRights switch isn't used, custom -objects will only be returned for -ObjectAceTypes that the principal is granted -access to. If -ListAllRights is used, then every ObjectAceType will produce at -least one extra custom object. - - - - Get-EffectiveAccess - - InputObject - - Specifies and object whose effective access is requested. - - Object - - - Principal - - The principal(s) that the function will use to perform the access check. This -can be a string representing a user, group, or SID. It can also be a -[System.Security.Principal.NTAccount] or a -[System.Security.Principal.SecurityIdentifier] object. - - String[] - - - ListAllRights - - Instead of returning a single string representation of the granted permissions -(and extra objects for each ObjectAcetype), multiple custom objects are -returned, one for each single permission in the securable object's access mask -enumeration, with a boolean value (Allowed) specifying whether or not the -specific permission is granted. This output resembles the 'Effective Access' -tab in the Windows ACL Editor. - - SwitchParameter - - - ObjectAceTypes - - Specifies properties, property sets, extended rights, validated writes, and/or -class objects. The principal's effective access will be checked against each -one. - -The parameter takes one or more strings, GUIDs (which can also be strings), or -output from the Get-ADObjectAceGuid function. If a string or GUID is provided, -the Get-ADObjectAceGuid function is called internally. - -Wildcards are permitted. - -NOTE: This parameter is only checked if the securable object being checked is -an Active Directory object. - - Object - - - - Get-EffectiveAccess - - Path - - Specifies the path to a resource (or resources) whose effective access is -requested. - - String[] - - - Principal - - The principal(s) that the function will use to perform the access check. This -can be a string representing a user, group, or SID. It can also be a -[System.Security.Principal.NTAccount] or a -[System.Security.Principal.SecurityIdentifier] object. - - String[] - - - ListAllRights - - Instead of returning a single string representation of the granted permissions -(and extra objects for each ObjectAcetype), multiple custom objects are -returned, one for each single permission in the securable object's access mask -enumeration, with a boolean value (Allowed) specifying whether or not the -specific permission is granted. This output resembles the 'Effective Access' -tab in the Windows ACL Editor. - - SwitchParameter - - - ObjectAceTypes - - Specifies properties, property sets, extended rights, validated writes, and/or -class objects. The principal's effective access will be checked against each -one. - -The parameter takes one or more strings, GUIDs (which can also be strings), or -output from the Get-ADObjectAceGuid function. If a string or GUID is provided, -the Get-ADObjectAceGuid function is called internally. - -Wildcards are permitted. - -NOTE: This parameter is only checked if the securable object being checked is -an Active Directory object. - - Object - - - - Get-EffectiveAccess - - LiteralPath - - Specifies the path to a resource (or resources) whose effective access is -requested. - -Unlike Path, the value of the LiteralPath parameter is used exactly as it is -typed. No characters are interpreted as wildcards. If the path includes escape -characters, enclose it in single quotation marks. Single quotation marks tell -Windows PowerShell not to interpret any characters as escape sequences. - - String[] - - - Principal - - The principal(s) that the function will use to perform the access check. This -can be a string representing a user, group, or SID. It can also be a -[System.Security.Principal.NTAccount] or a -[System.Security.Principal.SecurityIdentifier] object. - - String[] - - - ListAllRights - - Instead of returning a single string representation of the granted permissions -(and extra objects for each ObjectAcetype), multiple custom objects are -returned, one for each single permission in the securable object's access mask -enumeration, with a boolean value (Allowed) specifying whether or not the -specific permission is granted. This output resembles the 'Effective Access' -tab in the Windows ACL Editor. - - SwitchParameter - - - ObjectAceTypes - - Specifies properties, property sets, extended rights, validated writes, and/or -class objects. The principal's effective access will be checked against each -one. - -The parameter takes one or more strings, GUIDs (which can also be strings), or -output from the Get-ADObjectAceGuid function. If a string or GUID is provided, -the Get-ADObjectAceGuid function is called internally. - -Wildcards are permitted. - -NOTE: This parameter is only checked if the securable object being checked is -an Active Directory object. - - Object - - - - - - InputObject - - Specifies and object whose effective access is requested. - - Object - - Object - - - - - - Principal - - The principal(s) that the function will use to perform the access check. This -can be a string representing a user, group, or SID. It can also be a -[System.Security.Principal.NTAccount] or a -[System.Security.Principal.SecurityIdentifier] object. - - String[] - - String[] - - - - - - ListAllRights - - Instead of returning a single string representation of the granted permissions -(and extra objects for each ObjectAcetype), multiple custom objects are -returned, one for each single permission in the securable object's access mask -enumeration, with a boolean value (Allowed) specifying whether or not the -specific permission is granted. This output resembles the 'Effective Access' -tab in the Windows ACL Editor. - - SwitchParameter - - SwitchParameter - - - - - - ObjectAceTypes - - Specifies properties, property sets, extended rights, validated writes, and/or -class objects. The principal's effective access will be checked against each -one. - -The parameter takes one or more strings, GUIDs (which can also be strings), or -output from the Get-ADObjectAceGuid function. If a string or GUID is provided, -the Get-ADObjectAceGuid function is called internally. - -Wildcards are permitted. - -NOTE: This parameter is only checked if the securable object being checked is -an Active Directory object. - - Object - - Object - - - - - - Path - - Specifies the path to a resource (or resources) whose effective access is -requested. - - String[] - - String[] - - - - - - LiteralPath - - Specifies the path to a resource (or resources) whose effective access is -requested. - -Unlike Path, the value of the LiteralPath parameter is used exactly as it is -typed. No characters are interpreted as wildcards. If the path includes escape -characters, enclose it in single quotation marks. Single quotation marks tell -Windows PowerShell not to interpret any characters as escape sequences. - - String[] - - String[] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -------------- Example 1 -------------- - - - - PS C:\> Get-EffectiveAccess - - This will get the effective access of the current directory in the current -provider for the current user. - - - - - - - - - - -------------- Example 2 -------------- - - - - PS C:\> Get-EffectiveAccess -ListAllRights - - This will get the effective access of the current directory in the current -provider for the current user. The return value will break down all access -rights and show which ones were granted and which ones were not granted. - - - - - - - - - - -------------- Example 3 -------------- - - - - PS C:\> dir c:\folder | Get-EffectiveAccess - - This will get the effective access mask for the current user for all child -items under the 'C:\folder' folder. - - - - - - - - - - -------------- Example 4 -------------- - - - - PS C:\> dir c:\folder | Get-EffectiveAccess -Principal User1, User2 - - This will get the effective access mask for the User1 and User2 users for all -child items under the 'C:\folder' folder. - - - - - - - - - - -------------- Example 5 -------------- - - - - PS C:\> Get-Service | Get-EffectiveAccess - - This will get the effective access that the current user has on every service. - - - - - - - - - -------------- Example 6 -------------- - - - - PS C:\> Get-ADUser username | Get-EffectiveAccess -Principal username2 -ObjectAceType *password* - - - This will list the effective access that the 'username2' user has over the -object for the 'username' user. After the effective access is listed, one or -more effective access objects will be returned for every ObjectAceType that -'username2' has any rights for and that matches the '*password*' search string. - - - - - - - - - - - - about_PowerShellAccessControl_Module - - - - Get-AccessControlEntry - - - - - - - - Get-MandatoryIntegrityLabel - - Gets the mandatory integrity label of an object. - - - - - Get - MandatoryIntegrityLabel - - - - - The Get-MandatoryIntegrityLabel function gets the mandatory integrity label -(MIL) of an object (or multiple objects). The output of the function shows the -MIL as an ACE (similar to how Get-SecurityDescriptor returns the Access and -Audit properties). - -If a MIL is not set, the function returns null (the system would treat that -object as having medium integrity). - - - - Get-MandatoryIntegrityLabel - - Path - - Specifies the path to a resource to get the mandatory integrity label. - - String[] - - - - Get-MandatoryIntegrityLabel - - InputObject - - Specifies an object whose mandatory integrity label is retrieved. - - Object - - - - Get-MandatoryIntegrityLabel - - Path - - Specifies the path to a resource to get the mandatory integrity label. - - String[] - - - ObjectType - - Using this parameter along with the -Path parameter allows a specific object -type to be specified. Non-filesystem paths must be in a format that PowerShell -doesn't natively understand. See the 'SE_OBJECT_TYPE enumeration' link in the -RelatedLinks section for more information about the format. - - ResourceType - - - - Get-MandatoryIntegrityLabel - - LiteralPath - - Specifies the path to a resource to get the mandatory integrity label. - -Unlike Path, the value of the LiteralPath parameter is used exactly as it is -typed. No characters are interpreted as wildcards. If the path includes escape -characters, enclose it in single quotation marks. Single quotation marks tell -Windows PowerShell not to interpret any characters as escape sequences. - - String[] - - - - - - Path - - Specifies the path to a resource to get the mandatory integrity label. - - String[] - - String[] - - - - - - InputObject - - Specifies an object whose mandatory integrity label is retrieved. - - Object - - Object - - - - - - ObjectType - - Using this parameter along with the -Path parameter allows a specific object -type to be specified. Non-filesystem paths must be in a format that PowerShell -doesn't natively understand. See the 'SE_OBJECT_TYPE enumeration' link in the -RelatedLinks section for more information about the format. - - ResourceType - - ResourceType - - - - - - LiteralPath - - Specifies the path to a resource to get the mandatory integrity label. - -Unlike Path, the value of the LiteralPath parameter is used exactly as it is -typed. No characters are interpreted as wildcards. If the path includes escape -characters, enclose it in single quotation marks. Single quotation marks tell -Windows PowerShell not to interpret any characters as escape sequences. - - String[] - - String[] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -------------- Example 1 -------------- - - - - PS C:\> Get-Process -Id $pid | Get-MandatoryIntegrityLabel - - This gets the mandatory integrity label of the current PowerShell session's -process. - - - - - - - - - - -------------- Example 2 -------------- - - - - PS C:\> dir "$env:USERPROFILE\AppData\LocalLow" | Get-MandatoryIntegrityLabel - - This will get the MIL for all files/folders directly inside of the 'LocalLow' -folder. - - - - - - - - - - - - Mandatory Integrity Control - http://msdn.microsoft.com/en-us/library/windows/desktop/bb648648(v=vs.85).aspx - - - SE_OBJECT_TYPE enumeration - http://msdn.microsoft.com/en-us/library/windows/desktop/aa379593(v=vs.85).aspx - - - - - - - Get-SecurityDescriptor - - Similar to Get-Acl, the Get-SecurityDescriptor function gets the security -descriptor for a resource. It supports more objects than Get-Acl, and the SD -returned is of a different type than Get-Acl. - - - - - - Get - SecurityDescriptor - - - - - Get-SecurityDescriptor is used to get security descriptors for several -different types of objects. It is used the way that Get-Acl is used, except it -can handle a larger list of object types. - -Some of the objects this function can take as input include the following: - - System.Diagnostics.Process (returned from Get-Process) - - System.ServiceProcess.ServiceController (returned from Get-Service) - - WMI instances of certain classes: - * Win32_Printer - * Win32_Service - * Win32_Process - * Win32_Share - * Win32_LogicalShareSecuritySetting - * __SystemSecurity - * Win32_SecurityDescriptor/__SecurityDescriptor - - WsMan objects - -The function also takes specially crafted paths for several different types of -objects (see the -ObjectType parameter for details). - -For more information about the objects that are returned, see the help for the -New-AdaptedSecurityDescriptor function. - - - - - Get-SecurityDescriptor - - Path - - Specifies the path to a resource. Get-SecurityDescriptor gets the security -descriptor of the resource indicated by the path. Wildcards are permitted -(unless the -ObjectType parameter is also used). If the -Path parameter is -omitted, Get-SecurityDescriptor gets the security descriptor of the current -location of the current provider. - - - String[] - - - Audit - - By default, only the discretionary ACL (which deals with object access) is -returned. When this switch is used, the system ACL (which deals with object -auditing) is also returned. On a default Windows installation, administrator -access is required to use this switch. - - - SwitchParameter - - - - Get-SecurityDescriptor - - InputObject - - Gets the security descriptor for the specified object. Enter a variable that -contains the object or a command that gets the object. - - - Object - - - Audit - - By default, only the discretionary ACL (which deals with object access) is -returned. When this switch is used, the system ACL (which deals with object -auditing) is also returned. On a default Windows installation, administrator -access is required to use this switch. - - - SwitchParameter - - - - Get-SecurityDescriptor - - Path - - Specifies the path to a resource. Get-SecurityDescriptor gets the security -descriptor of the resource indicated by the path. Wildcards are permitted -(unless the -ObjectType parameter is also used). If the -Path parameter is -omitted, Get-SecurityDescriptor gets the security descriptor of the current -location of the current provider. - - - String[] - - - ObjectType - - Get-SecurityDescriptor attempts to determine the object type of the object -specified in the Path, LiteralPath, or InputObject. Using this parameter allows -the user to specify a specific object type. Non-filesystem paths must be in a -format that PowerShell doesn't natively understand. See the following link for -path formatting information: -http://msdn.microsoft.com/en-us/library/windows/desktop/aa379593(v=vs.85).aspx - - - ResourceType - - - Audit - - By default, only the discretionary ACL (which deals with object access) is -returned. When this switch is used, the system ACL (which deals with object -auditing) is also returned. On a default Windows installation, administrator -access is required to use this switch. - - - SwitchParameter - - - IsContainer - - When specifying the ObjectType, this parameter can also be used to specify -whether or not the security descriptor belongs to a container object, e.g., -folder, registry key, WMI namespace, etc. - - - SwitchParameter - - - - Get-SecurityDescriptor - - LiteralPath - - Specifies the path to a resource. Unlike Path, the value of the LiteralPath -parameter is used exactly as it is typed. No characters are interpreted as -wildcards. If the path includes escape characters, enclose it in single -quotation marks. Single quotation marks tell Windows PowerShell not to -interpret any characters as escape sequences. - - String[] - - - Audit - - By default, only the discretionary ACL (which deals with object access) is -returned. When this switch is used, the system ACL (which deals with object -auditing) is also returned. On a default Windows installation, administrator -access is required to use this switch. - - - SwitchParameter - - - - - - Path - - Specifies the path to a resource. Get-SecurityDescriptor gets the security -descriptor of the resource indicated by the path. Wildcards are permitted -(unless the -ObjectType parameter is also used). If the -Path parameter is -omitted, Get-SecurityDescriptor gets the security descriptor of the current -location of the current provider. - - - String[] - - String[] - - - Current location in current provider - - - Audit - - By default, only the discretionary ACL (which deals with object access) is -returned. When this switch is used, the system ACL (which deals with object -auditing) is also returned. On a default Windows installation, administrator -access is required to use this switch. - - - SwitchParameter - - SwitchParameter - - - - - - InputObject - - Gets the security descriptor for the specified object. Enter a variable that -contains the object or a command that gets the object. - - - Object - - Object - - - - - - ObjectType - - Get-SecurityDescriptor attempts to determine the object type of the object -specified in the Path, LiteralPath, or InputObject. Using this parameter allows -the user to specify a specific object type. Non-filesystem paths must be in a -format that PowerShell doesn't natively understand. See the following link for -path formatting information: -http://msdn.microsoft.com/en-us/library/windows/desktop/aa379593(v=vs.85).aspx - - - ResourceType - - ResourceType - - - - - - IsContainer - - When specifying the ObjectType, this parameter can also be used to specify -whether or not the security descriptor belongs to a container object, e.g., -folder, registry key, WMI namespace, etc. - - - SwitchParameter - - SwitchParameter - - - - - - LiteralPath - - Specifies the path to a resource. Unlike Path, the value of the LiteralPath -parameter is used exactly as it is typed. No characters are interpreted as -wildcards. If the path includes escape characters, enclose it in single -quotation marks. Single quotation marks tell Windows PowerShell not to -interpret any characters as escape sequences. - - String[] - - String[] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -------------- Example 1 -------------- - - - - PS C:\> Get-SecurityDescriptor HKCU:\Software - - This will get the security descriptor for the 'Software' key in the current user's registry hive. Since the -Audit switch was not supplied, only access entries will be returned. - - - - - - - - - -------------- Example 2 -------------- - - - - PS C:\> Get-SecurityDescriptor 'C:\Program Files' -Audit | Format-List - - This will get the security descriptor for the 'Program Files' folder. Since the -Audit switch was supplied, both access and audit entries will be returned (administrator privileges are required). The results are returned in a formatted list, which shows more information than the default table format shows. - - - - - - - - - -------------- Example 3 -------------- - - - - PS C:\> Get-Process -Id $pid | Get-SecurityDescriptor - - This will show the security descriptor for the current PowerShell session. Any process where the .Handle property is available can be viewed. - - - - - - - - - -------------- Example 4 -------------- - - - - PS C:\> dir WSMan:\localhost -Recurse | where { $_.Name -eq 'Sddl' } | Get-SecurityDescriptor - - Shows any WSMan leaf objects that contain SDDL. - - - - - - - - - -------------- Example 5 -------------- - - - - PS C:\> (Get-Service b*), (Get-Printer | select -first 1), (dir C:\Windows | select -first 3) | Get-SecurityDescriptor - - This example gets the security descriptor for all services that start with the letter 'b', for the first printer returned from Get-Printer (requires Windows 8.x), and from the first three objects returned by Get-ChildItem for the 'C:\Windows' directory. Notice that Get-SecurityDescriptor can get SDs for different types of objects in the same call. - - - - - - - - - -------------- Example 6 -------------- - - - - PS C:\> Get-SecurityDescriptor -Path \\RemoteMachine\MACHINE\Software\Adobe -ObjectType RegistryWow6432Key -IsContainer - - This must be run against a 64-bit computer. This will get the security descriptor of the HKLM:\SOFTWARE\Wow6432Node\Adobe registry key on the 'RemoteMachine' computer. Notice how the -ObjectType parameter was used. - -This could have been run against the local machine by either putting the local machine name in the first section, or removing the '\\RemoteMachine\' part of the path. - -Also, a normal registry path could have been used if the -ObjectType parameter was specified as 'RegistryKey' - - - - - - - - - -------------- Example 7 -------------- - - - - PS C:\> Get-SecurityDescriptor -Path \\ServerName\Share -ObjectType LMShare -Audit - - This gets the security descriptor for a share named 'Share' on a server named 'ServerName' (these are not the NTFS permissions). - -If the server was a Windows system, the following command would do the same thing: -Get-WmiObject Win32_Share -Filter "Name='Share'" -ComputerName ServerName | Get-SecurityInformation - - - - - - - - - -------------- Example 8 -------------- - - - - PS C:\> Get-SecurityDescriptor -Path "\\?\C:\path_longer_than_260_characters_here" -ObjectType FileObject - - This would get the security descriptor for a file or folder that has a path with more than 260 characters in it. You have to make sure to prepend '\\?\' to the path, and specify the -ObjectType for this to work. A future version of the module may take the -ObjectType and special path prefix requirement away. - - - - - - - - - - - about_PowerShellAccessControl_Module - - - - Set-SecurityDescriptor - - - - Remove-AccessControlEntry - - - - Add-AccessControlEntry - - - - Disable-AclInheritance - - - - Enable-AclInheritance - - - - Object Types - http://msdn.microsoft.com/en-us/library/windows/desktop/aa379593(v=vs.85).aspx - - - - - - - Get-Win32SecurityDescriptor - - Gets a security descriptor from a WMI/CIM object. - - - - - Get - Win32SecurityDescriptor - - - - - The Get-Win32SecurityDescriptor function gets an instance of the Win32_SecurityDescriptor class from a WMI/CIM object. The WMI/CIM object's class must have the GetSecurityDescriptor method available to it (you may find a list of these by running the following command on a V3 machine): - -Get-CimClass -MethodName GetSecurityDescriptor - -The function works with both the pre-V3 "WMI cmdlets" and the newer "CIM cmdlets". - -The function returns a custom object that always contains a Win32_SecurityDescriptor instance, and alternately contains the SDDL and/or binary representation of the security descriptor. - - - - Get-Win32SecurityDescriptor - - InputObject - - The WMI object/CIM instance to get the security descriptor from - - Object - - - Sddl - - Causes the function to also return the SDDL representation of the security descriptor. - - SwitchParameter - - - BinarySD - - Causes the function to also return the binary representation of the security descriptor. - - SwitchParameter - - - SddlOld - - Temporary (for testing) switch that returns SDDL using the Win32_SecurityDescriptorHelper WMI class (see Notes for this function) - - SwitchParameter - - - BinarySDOld - - Temporary (for testing) switch that returns the binary SD using the Win32_SecurityDescriptorHelper WMI class (see Notes for this function) - - SwitchParameter - - - - - - InputObject - - The WMI object/CIM instance to get the security descriptor from - - Object - - Object - - - - - - Sddl - - Causes the function to also return the SDDL representation of the security descriptor. - - SwitchParameter - - SwitchParameter - - - - - - BinarySD - - Causes the function to also return the binary representation of the security descriptor. - - SwitchParameter - - SwitchParameter - - - - - - SddlOld - - Temporary (for testing) switch that returns SDDL using the Win32_SecurityDescriptorHelper WMI class (see Notes for this function) - - SwitchParameter - - SwitchParameter - - - - - - BinarySDOld - - Temporary (for testing) switch that returns the binary SD using the Win32_SecurityDescriptorHelper WMI class (see Notes for this function) - - SwitchParameter - - SwitchParameter - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - There is a bug in the Win32_SecurityDescriptorHelper methods for converting to SDDL and binary formats that prevents object inheritance from being honored. If you inspect the Win32SD object for an object that has some inherited ACEs, you will notice that the AceFlags do properly show inheritance. -The SDDL or binary forms will not carry this over. Because of that, you'll notice the SddlOld and BinarySDOld switch parameters. Those use the old, buggy method (they were what I originally used for the Sddl and BinarySD switches). I'm keeping them around for a little more testing, but they are the secondary method for getting the alternate representations. They'll be removed in a future version of the PowerShellAccessControl module. - - - - - -------------- Example 1 -------------- - - - - PS C:\> Get-WmiObject Win32_Printer | Get-Win32SecurityDescriptor - - This example will get the security descriptor for each printer installed on the current machine. The descriptor object will be contained in each returned object's .Win32SD property. - - - - - - - - - -------------- Example 2 -------------- - - - - PS C:\> Get-CimInstance Win32_Printer | Get-Win32SecurityDescriptor -Sddl - - The same as example #1, except Get-CimInstance is used instead of Get-WmiObject, and an extra property containing the SDDL representation of the security descriptor will be attached to each object returned. - - - - - - - - - -------------- Example 3 -------------- - - - - PS C:\> Get-CimInstance Win32_Printer | Get-Win32SecurityDescriptor -Sddl -BinarySD - - The same as example #2, except an extra property containing the binary representation of the security descriptor will be attached to each object returned. - - - - - - - - - - - - - - - New-AccessControlEntry - - Creates a new access control entry for a securable object. It can be used to create both discretionary (access) and system (audit) entries. - - - - - New - AccessControlEntry - - - - - The New-AccessControlEntry function creates access control entries (ACEs) for -use with access control lists (ACLs) on security descriptors (SDs). - -When used with the -RegistryRights, -FolderRights, -FileRights, or --ActiveDirectoryRights parameters (without the -GenericAce switch), the ACE -returned can be used with security descriptor objects that were obtained using -the Get-Acl cmdlet or the Get-SecurityDescriptor function. When any of the -other *Rights parameters or the -AccessMask parameter is used, the ACE returned -can be used with security descriptor objects that were obtained using the -Get-SecurityDescriptor function. - -By default, the function creates an access allowed ACE. To create an access -denied ACE, supply the -AceType parameter with the string 'AccessDenied'. To -create an audit ACE, supply the -AceType parameter with the string -'SystemAudit', and use the -AuditSuccess and/or -AuditFailure switch -parameters. - -Every ACE definition must contain an access mask, except when an Active -Directory ACE is being created that contains and -ObjectAceType (more on that -below). The access mask can be a numeric value (provided through the --AccessMask parameter), or an enumeration (provided through the many *Rights -parameters). - -When creating an Active Directory ACE that contains an -ObjectAceType, the --ActiveDirectoryRights or -AcccessMask parameters are optional. If the --ObjectAceType corresponds to an extended right or a validated write, the -ExtendedRight or Self access masks are automatically used, respectively, when -no access mask is provided. If the -ObjectAceType corresponds to a class object -or a property/property set, the CreateChild or ReadProperty access masks are -automatically used, respectively, when no access mask is provided. Note that -valid access masks are CreateChild and/or DeleteChild for class objects and -ReadProperty and/or WriteProperty for properties/property sets, so it is -advisable to provide an access mask with those -ObjectAceTypes. - - - - New-AccessControlEntry - - AceType - - Specifies the type of ACE to create. Valid values are AccessAllowed, -AccessDenied, and SystemAudit. When SystemAudit is used, at least one of the --AuditSuccess or -AuditFailure switches must also be used. - - String - - - Principal - - The principal that this ACE will apply to. This can be a string representing -a user, group, or SID. It can also be a [System.Security.Principal.NTAccount] -or a [System.Security.Principal.SecurityIdentifier] object. - -To supply a principal on a remote system, provide a string the following -format: "COMPUTERNAME\PRINCIPAL STRING", e.g., Computer1\RemoteUser (account -name) or Computer1\S-1-1-0 (SID). - - Object - - - FileRights - - Specifies the access mask for the ACE using a file system specific enumeration. -The only difference between this parameter and the -FolderRighs parameter is -that -FolderRights has a different -AppliesTo default. If the -FileRights -parameter is used without an -AppliesTo parameter, the default -AppliesTo value -of Object is used. - -If this parameter is used, the object output by the function will be either a -FileSystemAccessRule or a FileSystemAuditRule type (unless the -Generic switch -is used). - - FileSystemRights - - - AppliesTo - - Controls inheritance and propagation flags for the ACE. By default, the ACE -will only apply to the object it belongs to (unless you use the -FolderRights, --RegistryRights, -WmiNamespaceRights, or -ActiveDirectoryRights parameters). - -By default, -FolderRights apply to the Object, ChildContainers, and -ChildObjects (or the folder, sub-folders and files) and -RegistryRights, --WmiNamespaceRights, and -ActiveDirectoryRights apply to the Object and -ChildContainers. - - AppliesTo - - - OnlyApplyToThisContainer - - When this switch parameter is enabled, only direct children will inherit the -ACE. Children of the direct children will not inherit it. - - SwitchParameter - - - GenericAce - - When the -FileRights, -FolderRights, -RegistryRights, or -ActiveDirectoryRights -parameters are used to provide the access mask, specialized .NET rule types are -created that can be used with security descriptor objects from the Get-Acl -cmdlet (the type depends on the parameter used). This switch will prevent the -specialized rule types from being created, though, and the ACE will be either a -CommonAce or ObjectAce object. - -The specialized rule types can be used directly with Add-AccessControlEntry, -Remove-AccessControlEntry, and the methods on security descriptor objects -returned from Get-SecurityDescriptor, so there is usually no need for users to -use this switch. It is used internally by the module to do ACE conversions. - - SwitchParameter - - - - New-AccessControlEntry - - AceType - - Specifies the type of ACE to create. Valid values are AccessAllowed, -AccessDenied, and SystemAudit. When SystemAudit is used, at least one of the --AuditSuccess or -AuditFailure switches must also be used. - - String - - - Principal - - The principal that this ACE will apply to. This can be a string representing -a user, group, or SID. It can also be a [System.Security.Principal.NTAccount] -or a [System.Security.Principal.SecurityIdentifier] object. - -To supply a principal on a remote system, provide a string the following -format: "COMPUTERNAME\PRINCIPAL STRING", e.g., Computer1\RemoteUser (account -name) or Computer1\S-1-1-0 (SID). - - Object - - - FolderRights - - Specifies the access mask for the ACE using a file system specific enumeration. -The only difference between this parameter and the -FileRighs parameter is that --FileRights has a different -AppliesTo default. If the -FolderRights parameter -is used without an -AppliesTo parameter, the default -AppliesTo value of -Object, ChildContainers, ChildObjects is used. - -If this parameter is used, the object output by the function will be either a -FileSystemAccessRule or a FileSystemAuditRule type (unless the -Generic switch -is used). - - FileSystemRights - - - AppliesTo - - Controls inheritance and propagation flags for the ACE. By default, the ACE -will only apply to the object it belongs to (unless you use the -FolderRights, --RegistryRights, -WmiNamespaceRights, or -ActiveDirectoryRights parameters). - -By default, -FolderRights apply to the Object, ChildContainers, and -ChildObjects (or the folder, sub-folders and files) and -RegistryRights, --WmiNamespaceRights, and -ActiveDirectoryRights apply to the Object and -ChildContainers. - - AppliesTo - - - OnlyApplyToThisContainer - - When this switch parameter is enabled, only direct children will inherit the -ACE. Children of the direct children will not inherit it. - - SwitchParameter - - - GenericAce - - When the -FileRights, -FolderRights, -RegistryRights, or -ActiveDirectoryRights -parameters are used to provide the access mask, specialized .NET rule types are -created that can be used with security descriptor objects from the Get-Acl -cmdlet (the type depends on the parameter used). This switch will prevent the -specialized rule types from being created, though, and the ACE will be either a -CommonAce or ObjectAce object. - -The specialized rule types can be used directly with Add-AccessControlEntry, -Remove-AccessControlEntry, and the methods on security descriptor objects -returned from Get-SecurityDescriptor, so there is usually no need for users to -use this switch. It is used internally by the module to do ACE conversions. - - SwitchParameter - - - - New-AccessControlEntry - - AceType - - Specifies the type of ACE to create. Valid values are AccessAllowed, -AccessDenied, and SystemAudit. When SystemAudit is used, at least one of the --AuditSuccess or -AuditFailure switches must also be used. - - String - - - Principal - - The principal that this ACE will apply to. This can be a string representing -a user, group, or SID. It can also be a [System.Security.Principal.NTAccount] -or a [System.Security.Principal.SecurityIdentifier] object. - -To supply a principal on a remote system, provide a string the following -format: "COMPUTERNAME\PRINCIPAL STRING", e.g., Computer1\RemoteUser (account -name) or Computer1\S-1-1-0 (SID). - - Object - - - RegistryRights - - Specifies the access mask for the ACE using a registry specific enumeration. -Using this parameter will also cause the default -AppliesTo setting to change -to the Object and ChildContainers, and the output object to be either a -RegistryAccessRule or RegistryAuditRule type (unless the -Generic switch is -used). - - RegistryRights - - - AppliesTo - - Controls inheritance and propagation flags for the ACE. By default, the ACE -will only apply to the object it belongs to (unless you use the -FolderRights, --RegistryRights, -WmiNamespaceRights, or -ActiveDirectoryRights parameters). - -By default, -FolderRights apply to the Object, ChildContainers, and -ChildObjects (or the folder, sub-folders and files) and -RegistryRights, --WmiNamespaceRights, and -ActiveDirectoryRights apply to the Object and -ChildContainers. - - AppliesTo - - - OnlyApplyToThisContainer - - When this switch parameter is enabled, only direct children will inherit the -ACE. Children of the direct children will not inherit it. - - SwitchParameter - - - GenericAce - - When the -FileRights, -FolderRights, -RegistryRights, or -ActiveDirectoryRights -parameters are used to provide the access mask, specialized .NET rule types are -created that can be used with security descriptor objects from the Get-Acl -cmdlet (the type depends on the parameter used). This switch will prevent the -specialized rule types from being created, though, and the ACE will be either a -CommonAce or ObjectAce object. - -The specialized rule types can be used directly with Add-AccessControlEntry, -Remove-AccessControlEntry, and the methods on security descriptor objects -returned from Get-SecurityDescriptor, so there is usually no need for users to -use this switch. It is used internally by the module to do ACE conversions. - - SwitchParameter - - - - New-AccessControlEntry - - AceType - - Specifies the type of ACE to create. Valid values are AccessAllowed, -AccessDenied, and SystemAudit. When SystemAudit is used, at least one of the --AuditSuccess or -AuditFailure switches must also be used. - - String - - - Principal - - The principal that this ACE will apply to. This can be a string representing -a user, group, or SID. It can also be a [System.Security.Principal.NTAccount] -or a [System.Security.Principal.SecurityIdentifier] object. - -To supply a principal on a remote system, provide a string the following -format: "COMPUTERNAME\PRINCIPAL STRING", e.g., Computer1\RemoteUser (account -name) or Computer1\S-1-1-0 (SID). - - Object - - - ActiveDirectoryRights - - Specifies the access mask for the ACE using an Active Directory specific -enumeration. Using this parameter will also cause the default -AppliesTo -setting to change to the Object and ChildContainers, and the output object to -be either an ActiveDirectoryAccessRule or ActiveDirectoryAuditRule type (unless -the -Generic switch is used). - - ActiveDirectoryRights - - - AppliesTo - - Controls inheritance and propagation flags for the ACE. By default, the ACE -will only apply to the object it belongs to (unless you use the -FolderRights, --RegistryRights, -WmiNamespaceRights, or -ActiveDirectoryRights parameters). - -By default, -FolderRights apply to the Object, ChildContainers, and -ChildObjects (or the folder, sub-folders and files) and -RegistryRights, --WmiNamespaceRights, and -ActiveDirectoryRights apply to the Object and -ChildContainers. - - AppliesTo - - - OnlyApplyToThisContainer - - When this switch parameter is enabled, only direct children will inherit the -ACE. Children of the direct children will not inherit it. - - SwitchParameter - - - ObjectAceType - - Specifies a property, property set, extended right, validated write, or class -object that this ACE will apply to. - -The parameter takes a string, a GUID (which can also be a string), or the -output from the Get-ADObjectAceGuid function. If a string or GUID is provided, -the Get-ADObjectAceGuid function is called internally. - -Wildcards are permitted. If more than one result is returned, the user will be -prompted to select the proper object ACE GUID. - -It is possible for more than one result to be returned with a string input, -even if no wildcards were specified. This can happen if the name or GUID are -shared among types (property, class object, extended right, validated write, -etc). To prevent the prompt in a script, use a call to Get-ADObjectAceGuid with -the -TypesToSearch parameter limiting the returned type. See the help for that -function for more information. - - Object - - - InheritedObjectAceType - - Specifies the type of object that this ACE will apply to, e.g., organizational -unit, user object, etc. - -The parameter takes a string, a GUID (which can also be a string), or the -output from the Get-ADObjectAceGuid function. If a string or GUID is provided, -the Get-ADObjectAceGuid function is called internally. - -Wildcards are permitted. If more than one result is returned, the user will be -prompted to select the proper object ACE GUID. - - Object - - - GenericAce - - When the -FileRights, -FolderRights, -RegistryRights, or -ActiveDirectoryRights -parameters are used to provide the access mask, specialized .NET rule types are -created that can be used with security descriptor objects from the Get-Acl -cmdlet (the type depends on the parameter used). This switch will prevent the -specialized rule types from being created, though, and the ACE will be either a -CommonAce or ObjectAce object. - -The specialized rule types can be used directly with Add-AccessControlEntry, -Remove-AccessControlEntry, and the methods on security descriptor objects -returned from Get-SecurityDescriptor, so there is usually no need for users to -use this switch. It is used internally by the module to do ACE conversions. - - SwitchParameter - - - - New-AccessControlEntry - - AceType - - Specifies the type of ACE to create. Valid values are AccessAllowed, -AccessDenied, and SystemAudit. When SystemAudit is used, at least one of the --AuditSuccess or -AuditFailure switches must also be used. - - String - - - Principal - - The principal that this ACE will apply to. This can be a string representing -a user, group, or SID. It can also be a [System.Security.Principal.NTAccount] -or a [System.Security.Principal.SecurityIdentifier] object. - -To supply a principal on a remote system, provide a string the following -format: "COMPUTERNAME\PRINCIPAL STRING", e.g., Computer1\RemoteUser (account -name) or Computer1\S-1-1-0 (SID). - - Object - - - AccessMask - - Allows for any numeric value for the AccessMask. This is usually used when -creating an ACE for an object that the PowerShellAccessControl module doesn't -already handle. - - Int32 - - - AppliesTo - - Controls inheritance and propagation flags for the ACE. By default, the ACE -will only apply to the object it belongs to (unless you use the -FolderRights, --RegistryRights, -WmiNamespaceRights, or -ActiveDirectoryRights parameters). - -By default, -FolderRights apply to the Object, ChildContainers, and -ChildObjects (or the folder, sub-folders and files) and -RegistryRights, --WmiNamespaceRights, and -ActiveDirectoryRights apply to the Object and -ChildContainers. - - AppliesTo - - - OnlyApplyToThisContainer - - When this switch parameter is enabled, only direct children will inherit the -ACE. Children of the direct children will not inherit it. - - SwitchParameter - - - ObjectAceType - - Specifies a property, property set, extended right, validated write, or class -object that this ACE will apply to. - -The parameter takes a string, a GUID (which can also be a string), or the -output from the Get-ADObjectAceGuid function. If a string or GUID is provided, -the Get-ADObjectAceGuid function is called internally. - -Wildcards are permitted. If more than one result is returned, the user will be -prompted to select the proper object ACE GUID. - -It is possible for more than one result to be returned with a string input, -even if no wildcards were specified. This can happen if the name or GUID are -shared among types (property, class object, extended right, validated write, -etc). To prevent the prompt in a script, use a call to Get-ADObjectAceGuid with -the -TypesToSearch parameter limiting the returned type. See the help for that -function for more information. - - Object - - - InheritedObjectAceType - - Specifies the type of object that this ACE will apply to, e.g., organizational -unit, user object, etc. - -The parameter takes a string, a GUID (which can also be a string), or the -output from the Get-ADObjectAceGuid function. If a string or GUID is provided, -the Get-ADObjectAceGuid function is called internally. - -Wildcards are permitted. If more than one result is returned, the user will be -prompted to select the proper object ACE GUID. - - Object - - - AceFlags - - This parameter is for advanced use only. It allows the -AppliesTo, --OnlyApplyToThisContainer, -AuditSuccess, and/or -AuditFailure parameters to be -omitted when used to define a generic access control entry. If this parameter -is provided along with the other parameters, the other parameters will take -precedence, e.g., if -AppliesTo is provided, and it specifies Object, but --AceFlags is provided and it specifies that the ACE should apply to the Object -and ChildContainers, the resulting ACE will use the -AppliesTo variable, and -will apply only to the Object. - - AceFlags - - - GenericAce - - When the -FileRights, -FolderRights, -RegistryRights, or -ActiveDirectoryRights -parameters are used to provide the access mask, specialized .NET rule types are -created that can be used with security descriptor objects from the Get-Acl -cmdlet (the type depends on the parameter used). This switch will prevent the -specialized rule types from being created, though, and the ACE will be either a -CommonAce or ObjectAce object. - -The specialized rule types can be used directly with Add-AccessControlEntry, -Remove-AccessControlEntry, and the methods on security descriptor objects -returned from Get-SecurityDescriptor, so there is usually no need for users to -use this switch. It is used internally by the module to do ACE conversions. - - SwitchParameter - - - - New-AccessControlEntry - - AceType - - Specifies the type of ACE to create. Valid values are AccessAllowed, -AccessDenied, and SystemAudit. When SystemAudit is used, at least one of the --AuditSuccess or -AuditFailure switches must also be used. - - String - - - Principal - - The principal that this ACE will apply to. This can be a string representing -a user, group, or SID. It can also be a [System.Security.Principal.NTAccount] -or a [System.Security.Principal.SecurityIdentifier] object. - -To supply a principal on a remote system, provide a string the following -format: "COMPUTERNAME\PRINCIPAL STRING", e.g., Computer1\RemoteUser (account -name) or Computer1\S-1-1-0 (SID). - - Object - - - AppliesTo - - Controls inheritance and propagation flags for the ACE. By default, the ACE -will only apply to the object it belongs to (unless you use the -FolderRights, --RegistryRights, -WmiNamespaceRights, or -ActiveDirectoryRights parameters). - -By default, -FolderRights apply to the Object, ChildContainers, and -ChildObjects (or the folder, sub-folders and files) and -RegistryRights, --WmiNamespaceRights, and -ActiveDirectoryRights apply to the Object and -ChildContainers. - - AppliesTo - - - OnlyApplyToThisContainer - - When this switch parameter is enabled, only direct children will inherit the -ACE. Children of the direct children will not inherit it. - - SwitchParameter - - - ObjectAceType - - Specifies a property, property set, extended right, validated write, or class -object that this ACE will apply to. - -The parameter takes a string, a GUID (which can also be a string), or the -output from the Get-ADObjectAceGuid function. If a string or GUID is provided, -the Get-ADObjectAceGuid function is called internally. - -Wildcards are permitted. If more than one result is returned, the user will be -prompted to select the proper object ACE GUID. - -It is possible for more than one result to be returned with a string input, -even if no wildcards were specified. This can happen if the name or GUID are -shared among types (property, class object, extended right, validated write, -etc). To prevent the prompt in a script, use a call to Get-ADObjectAceGuid with -the -TypesToSearch parameter limiting the returned type. See the help for that -function for more information. - - Object - - - InheritedObjectAceType - - Specifies the type of object that this ACE will apply to, e.g., organizational -unit, user object, etc. - -The parameter takes a string, a GUID (which can also be a string), or the -output from the Get-ADObjectAceGuid function. If a string or GUID is provided, -the Get-ADObjectAceGuid function is called internally. - -Wildcards are permitted. If more than one result is returned, the user will be -prompted to select the proper object ACE GUID. - - Object - - - - New-AccessControlEntry - - AceType - - Specifies the type of ACE to create. Valid values are AccessAllowed, -AccessDenied, and SystemAudit. When SystemAudit is used, at least one of the --AuditSuccess or -AuditFailure switches must also be used. - - String - - - Principal - - The principal that this ACE will apply to. This can be a string representing -a user, group, or SID. It can also be a [System.Security.Principal.NTAccount] -or a [System.Security.Principal.SecurityIdentifier] object. - -To supply a principal on a remote system, provide a string the following -format: "COMPUTERNAME\PRINCIPAL STRING", e.g., Computer1\RemoteUser (account -name) or Computer1\S-1-1-0 (SID). - - Object - - - AppliesTo - - Controls inheritance and propagation flags for the ACE. By default, the ACE -will only apply to the object it belongs to (unless you use the -FolderRights, --RegistryRights, -WmiNamespaceRights, or -ActiveDirectoryRights parameters). - -By default, -FolderRights apply to the Object, ChildContainers, and -ChildObjects (or the folder, sub-folders and files) and -RegistryRights, --WmiNamespaceRights, and -ActiveDirectoryRights apply to the Object and -ChildContainers. - - AppliesTo - - - OnlyApplyToThisContainer - - When this switch parameter is enabled, only direct children will inherit the -ACE. Children of the direct children will not inherit it. - - SwitchParameter - - - LogicalShareRights - - Specifies the access mask for the ACE using a share specific enumeration. - - LogicalShareRights - - - - New-AccessControlEntry - - AceType - - Specifies the type of ACE to create. Valid values are AccessAllowed, -AccessDenied, and SystemAudit. When SystemAudit is used, at least one of the --AuditSuccess or -AuditFailure switches must also be used. - - String - - - Principal - - The principal that this ACE will apply to. This can be a string representing -a user, group, or SID. It can also be a [System.Security.Principal.NTAccount] -or a [System.Security.Principal.SecurityIdentifier] object. - -To supply a principal on a remote system, provide a string the following -format: "COMPUTERNAME\PRINCIPAL STRING", e.g., Computer1\RemoteUser (account -name) or Computer1\S-1-1-0 (SID). - - Object - - - AppliesTo - - Controls inheritance and propagation flags for the ACE. By default, the ACE -will only apply to the object it belongs to (unless you use the -FolderRights, --RegistryRights, -WmiNamespaceRights, or -ActiveDirectoryRights parameters). - -By default, -FolderRights apply to the Object, ChildContainers, and -ChildObjects (or the folder, sub-folders and files) and -RegistryRights, --WmiNamespaceRights, and -ActiveDirectoryRights apply to the Object and -ChildContainers. - - AppliesTo - - - OnlyApplyToThisContainer - - When this switch parameter is enabled, only direct children will inherit the -ACE. Children of the direct children will not inherit it. - - SwitchParameter - - - PrinterRights - - Specifies the access mask for the ACE using a printer specific enumeration. - - PrinterRights - - - - New-AccessControlEntry - - AceType - - Specifies the type of ACE to create. Valid values are AccessAllowed, -AccessDenied, and SystemAudit. When SystemAudit is used, at least one of the --AuditSuccess or -AuditFailure switches must also be used. - - String - - - Principal - - The principal that this ACE will apply to. This can be a string representing -a user, group, or SID. It can also be a [System.Security.Principal.NTAccount] -or a [System.Security.Principal.SecurityIdentifier] object. - -To supply a principal on a remote system, provide a string the following -format: "COMPUTERNAME\PRINCIPAL STRING", e.g., Computer1\RemoteUser (account -name) or Computer1\S-1-1-0 (SID). - - Object - - - AppliesTo - - Controls inheritance and propagation flags for the ACE. By default, the ACE -will only apply to the object it belongs to (unless you use the -FolderRights, --RegistryRights, -WmiNamespaceRights, or -ActiveDirectoryRights parameters). - -By default, -FolderRights apply to the Object, ChildContainers, and -ChildObjects (or the folder, sub-folders and files) and -RegistryRights, --WmiNamespaceRights, and -ActiveDirectoryRights apply to the Object and -ChildContainers. - - AppliesTo - - - OnlyApplyToThisContainer - - When this switch parameter is enabled, only direct children will inherit the -ACE. Children of the direct children will not inherit it. - - SwitchParameter - - - WmiNamespaceRights - - Specifies the access mask for the ACE using a WMI specific enumeration. Using -this parameter will also cause the default -AppliesTo setting to change to the -Object and ChildContainers. - - WmiNamespaceRights - - - - New-AccessControlEntry - - AceType - - Specifies the type of ACE to create. Valid values are AccessAllowed, -AccessDenied, and SystemAudit. When SystemAudit is used, at least one of the --AuditSuccess or -AuditFailure switches must also be used. - - String - - - Principal - - The principal that this ACE will apply to. This can be a string representing -a user, group, or SID. It can also be a [System.Security.Principal.NTAccount] -or a [System.Security.Principal.SecurityIdentifier] object. - -To supply a principal on a remote system, provide a string the following -format: "COMPUTERNAME\PRINCIPAL STRING", e.g., Computer1\RemoteUser (account -name) or Computer1\S-1-1-0 (SID). - - Object - - - AppliesTo - - Controls inheritance and propagation flags for the ACE. By default, the ACE -will only apply to the object it belongs to (unless you use the -FolderRights, --RegistryRights, -WmiNamespaceRights, or -ActiveDirectoryRights parameters). - -By default, -FolderRights apply to the Object, ChildContainers, and -ChildObjects (or the folder, sub-folders and files) and -RegistryRights, --WmiNamespaceRights, and -ActiveDirectoryRights apply to the Object and -ChildContainers. - - AppliesTo - - - OnlyApplyToThisContainer - - When this switch parameter is enabled, only direct children will inherit the -ACE. Children of the direct children will not inherit it. - - SwitchParameter - - - WsManAccessRights - - Specifies the access mask for the ACE using a WsMan specific enumeration. - - WsManAccessRights - - - - New-AccessControlEntry - - AceType - - Specifies the type of ACE to create. Valid values are AccessAllowed, -AccessDenied, and SystemAudit. When SystemAudit is used, at least one of the --AuditSuccess or -AuditFailure switches must also be used. - - String - - - Principal - - The principal that this ACE will apply to. This can be a string representing -a user, group, or SID. It can also be a [System.Security.Principal.NTAccount] -or a [System.Security.Principal.SecurityIdentifier] object. - -To supply a principal on a remote system, provide a string the following -format: "COMPUTERNAME\PRINCIPAL STRING", e.g., Computer1\RemoteUser (account -name) or Computer1\S-1-1-0 (SID). - - Object - - - AppliesTo - - Controls inheritance and propagation flags for the ACE. By default, the ACE -will only apply to the object it belongs to (unless you use the -FolderRights, --RegistryRights, -WmiNamespaceRights, or -ActiveDirectoryRights parameters). - -By default, -FolderRights apply to the Object, ChildContainers, and -ChildObjects (or the folder, sub-folders and files) and -RegistryRights, --WmiNamespaceRights, and -ActiveDirectoryRights apply to the Object and -ChildContainers. - - AppliesTo - - - OnlyApplyToThisContainer - - When this switch parameter is enabled, only direct children will inherit the -ACE. Children of the direct children will not inherit it. - - SwitchParameter - - - ServiceAccessRights - - Specifies the access mask for the ACE using a service specific enumeration. - - ServiceAccessRights - - - - New-AccessControlEntry - - AceType - - Specifies the type of ACE to create. Valid values are AccessAllowed, -AccessDenied, and SystemAudit. When SystemAudit is used, at least one of the --AuditSuccess or -AuditFailure switches must also be used. - - String - - - Principal - - The principal that this ACE will apply to. This can be a string representing -a user, group, or SID. It can also be a [System.Security.Principal.NTAccount] -or a [System.Security.Principal.SecurityIdentifier] object. - -To supply a principal on a remote system, provide a string the following -format: "COMPUTERNAME\PRINCIPAL STRING", e.g., Computer1\RemoteUser (account -name) or Computer1\S-1-1-0 (SID). - - Object - - - AppliesTo - - Controls inheritance and propagation flags for the ACE. By default, the ACE -will only apply to the object it belongs to (unless you use the -FolderRights, --RegistryRights, -WmiNamespaceRights, or -ActiveDirectoryRights parameters). - -By default, -FolderRights apply to the Object, ChildContainers, and -ChildObjects (or the folder, sub-folders and files) and -RegistryRights, --WmiNamespaceRights, and -ActiveDirectoryRights apply to the Object and -ChildContainers. - - AppliesTo - - - OnlyApplyToThisContainer - - When this switch parameter is enabled, only direct children will inherit the -ACE. Children of the direct children will not inherit it. - - SwitchParameter - - - GenericAceRights - - Specifies the access mask for the ACE using the generic access rights enumeration. - - GenericAceRights - - - - New-AccessControlEntry - - AceType - - Specifies the type of ACE to create. Valid values are AccessAllowed, -AccessDenied, and SystemAudit. When SystemAudit is used, at least one of the --AuditSuccess or -AuditFailure switches must also be used. - - String - - - Principal - - The principal that this ACE will apply to. This can be a string representing -a user, group, or SID. It can also be a [System.Security.Principal.NTAccount] -or a [System.Security.Principal.SecurityIdentifier] object. - -To supply a principal on a remote system, provide a string the following -format: "COMPUTERNAME\PRINCIPAL STRING", e.g., Computer1\RemoteUser (account -name) or Computer1\S-1-1-0 (SID). - - Object - - - AppliesTo - - Controls inheritance and propagation flags for the ACE. By default, the ACE -will only apply to the object it belongs to (unless you use the -FolderRights, --RegistryRights, -WmiNamespaceRights, or -ActiveDirectoryRights parameters). - -By default, -FolderRights apply to the Object, ChildContainers, and -ChildObjects (or the folder, sub-folders and files) and -RegistryRights, --WmiNamespaceRights, and -ActiveDirectoryRights apply to the Object and -ChildContainers. - - AppliesTo - - - OnlyApplyToThisContainer - - When this switch parameter is enabled, only direct children will inherit the -ACE. Children of the direct children will not inherit it. - - SwitchParameter - - - StandardAccessRights - - Specifies the access mask for the ACE using the standard access rights enumeration. - - StandardAccessRights - - - - New-AccessControlEntry - - AceType - - Specifies the type of ACE to create. Valid values are AccessAllowed, -AccessDenied, and SystemAudit. When SystemAudit is used, at least one of the --AuditSuccess or -AuditFailure switches must also be used. - - String - - - Principal - - The principal that this ACE will apply to. This can be a string representing -a user, group, or SID. It can also be a [System.Security.Principal.NTAccount] -or a [System.Security.Principal.SecurityIdentifier] object. - -To supply a principal on a remote system, provide a string the following -format: "COMPUTERNAME\PRINCIPAL STRING", e.g., Computer1\RemoteUser (account -name) or Computer1\S-1-1-0 (SID). - - Object - - - AppliesTo - - Controls inheritance and propagation flags for the ACE. By default, the ACE -will only apply to the object it belongs to (unless you use the -FolderRights, --RegistryRights, -WmiNamespaceRights, or -ActiveDirectoryRights parameters). - -By default, -FolderRights apply to the Object, ChildContainers, and -ChildObjects (or the folder, sub-folders and files) and -RegistryRights, --WmiNamespaceRights, and -ActiveDirectoryRights apply to the Object and -ChildContainers. - - AppliesTo - - - OnlyApplyToThisContainer - - When this switch parameter is enabled, only direct children will inherit the -ACE. Children of the direct children will not inherit it. - - SwitchParameter - - - ProcessAccessRights - - Specifies the access mask for the ACE using a process specific enumeration. - - ProcessAccessRights - - - - - - AceType - - Specifies the type of ACE to create. Valid values are AccessAllowed, -AccessDenied, and SystemAudit. When SystemAudit is used, at least one of the --AuditSuccess or -AuditFailure switches must also be used. - - String - - String - - - AccessAllowed - - - Principal - - The principal that this ACE will apply to. This can be a string representing -a user, group, or SID. It can also be a [System.Security.Principal.NTAccount] -or a [System.Security.Principal.SecurityIdentifier] object. - -To supply a principal on a remote system, provide a string the following -format: "COMPUTERNAME\PRINCIPAL STRING", e.g., Computer1\RemoteUser (account -name) or Computer1\S-1-1-0 (SID). - - Object - - Object - - - - - - FileRights - - Specifies the access mask for the ACE using a file system specific enumeration. -The only difference between this parameter and the -FolderRighs parameter is -that -FolderRights has a different -AppliesTo default. If the -FileRights -parameter is used without an -AppliesTo parameter, the default -AppliesTo value -of Object is used. - -If this parameter is used, the object output by the function will be either a -FileSystemAccessRule or a FileSystemAuditRule type (unless the -Generic switch -is used). - - FileSystemRights - - FileSystemRights - - - - - - AppliesTo - - Controls inheritance and propagation flags for the ACE. By default, the ACE -will only apply to the object it belongs to (unless you use the -FolderRights, --RegistryRights, -WmiNamespaceRights, or -ActiveDirectoryRights parameters). - -By default, -FolderRights apply to the Object, ChildContainers, and -ChildObjects (or the folder, sub-folders and files) and -RegistryRights, --WmiNamespaceRights, and -ActiveDirectoryRights apply to the Object and -ChildContainers. - - AppliesTo - - AppliesTo - - - - - - OnlyApplyToThisContainer - - When this switch parameter is enabled, only direct children will inherit the -ACE. Children of the direct children will not inherit it. - - SwitchParameter - - SwitchParameter - - - - - - GenericAce - - When the -FileRights, -FolderRights, -RegistryRights, or -ActiveDirectoryRights -parameters are used to provide the access mask, specialized .NET rule types are -created that can be used with security descriptor objects from the Get-Acl -cmdlet (the type depends on the parameter used). This switch will prevent the -specialized rule types from being created, though, and the ACE will be either a -CommonAce or ObjectAce object. - -The specialized rule types can be used directly with Add-AccessControlEntry, -Remove-AccessControlEntry, and the methods on security descriptor objects -returned from Get-SecurityDescriptor, so there is usually no need for users to -use this switch. It is used internally by the module to do ACE conversions. - - SwitchParameter - - SwitchParameter - - - - - - FolderRights - - Specifies the access mask for the ACE using a file system specific enumeration. -The only difference between this parameter and the -FileRighs parameter is that --FileRights has a different -AppliesTo default. If the -FolderRights parameter -is used without an -AppliesTo parameter, the default -AppliesTo value of -Object, ChildContainers, ChildObjects is used. - -If this parameter is used, the object output by the function will be either a -FileSystemAccessRule or a FileSystemAuditRule type (unless the -Generic switch -is used). - - FileSystemRights - - FileSystemRights - - - - - - RegistryRights - - Specifies the access mask for the ACE using a registry specific enumeration. -Using this parameter will also cause the default -AppliesTo setting to change -to the Object and ChildContainers, and the output object to be either a -RegistryAccessRule or RegistryAuditRule type (unless the -Generic switch is -used). - - RegistryRights - - RegistryRights - - - - - - ActiveDirectoryRights - - Specifies the access mask for the ACE using an Active Directory specific -enumeration. Using this parameter will also cause the default -AppliesTo -setting to change to the Object and ChildContainers, and the output object to -be either an ActiveDirectoryAccessRule or ActiveDirectoryAuditRule type (unless -the -Generic switch is used). - - ActiveDirectoryRights - - ActiveDirectoryRights - - - - - - ObjectAceType - - Specifies a property, property set, extended right, validated write, or class -object that this ACE will apply to. - -The parameter takes a string, a GUID (which can also be a string), or the -output from the Get-ADObjectAceGuid function. If a string or GUID is provided, -the Get-ADObjectAceGuid function is called internally. - -Wildcards are permitted. If more than one result is returned, the user will be -prompted to select the proper object ACE GUID. - -It is possible for more than one result to be returned with a string input, -even if no wildcards were specified. This can happen if the name or GUID are -shared among types (property, class object, extended right, validated write, -etc). To prevent the prompt in a script, use a call to Get-ADObjectAceGuid with -the -TypesToSearch parameter limiting the returned type. See the help for that -function for more information. - - Object - - Object - - - - - - InheritedObjectAceType - - Specifies the type of object that this ACE will apply to, e.g., organizational -unit, user object, etc. - -The parameter takes a string, a GUID (which can also be a string), or the -output from the Get-ADObjectAceGuid function. If a string or GUID is provided, -the Get-ADObjectAceGuid function is called internally. - -Wildcards are permitted. If more than one result is returned, the user will be -prompted to select the proper object ACE GUID. - - Object - - Object - - - - - - AccessMask - - Allows for any numeric value for the AccessMask. This is usually used when -creating an ACE for an object that the PowerShellAccessControl module doesn't -already handle. - - Int32 - - Int32 - - - - - - AceFlags - - This parameter is for advanced use only. It allows the -AppliesTo, --OnlyApplyToThisContainer, -AuditSuccess, and/or -AuditFailure parameters to be -omitted when used to define a generic access control entry. If this parameter -is provided along with the other parameters, the other parameters will take -precedence, e.g., if -AppliesTo is provided, and it specifies Object, but --AceFlags is provided and it specifies that the ACE should apply to the Object -and ChildContainers, the resulting ACE will use the -AppliesTo variable, and -will apply only to the Object. - - AceFlags - - AceFlags - - - - - - LogicalShareRights - - Specifies the access mask for the ACE using a share specific enumeration. - - LogicalShareRights - - LogicalShareRights - - - - - - PrinterRights - - Specifies the access mask for the ACE using a printer specific enumeration. - - PrinterRights - - PrinterRights - - - - - - WmiNamespaceRights - - Specifies the access mask for the ACE using a WMI specific enumeration. Using -this parameter will also cause the default -AppliesTo setting to change to the -Object and ChildContainers. - - WmiNamespaceRights - - WmiNamespaceRights - - - - - - WsManAccessRights - - Specifies the access mask for the ACE using a WsMan specific enumeration. - - WsManAccessRights - - WsManAccessRights - - - - - - ServiceAccessRights - - Specifies the access mask for the ACE using a service specific enumeration. - - ServiceAccessRights - - ServiceAccessRights - - - - - - GenericAceRights - - Specifies the access mask for the ACE using the generic access rights enumeration. - - GenericAceRights - - GenericAceRights - - - - - - StandardAccessRights - - Specifies the access mask for the ACE using the standard access rights enumeration. - - StandardAccessRights - - StandardAccessRights - - - - - - ProcessAccessRights - - Specifies the access mask for the ACE using a process specific enumeration. - - ProcessAccessRights - - ProcessAccessRights - - - - - - - - - - - - - - - - - - - - - - - - The return type varies depending on the parameters. If the -Generic switch is used, or any access mask parameter other than -FileRights, -FolderRights, -RegistryRights, or -ActiveDirectoryRights is used, the return type is -System.Security.AccessControl.CommonAce (or System.Security.AccessControl.ObjectAce when certain Active Directory ACEs are created). - -Otherwise, the return type is listed below (the parameter for the access mask is listed on the left, and the return types are listed on the right): -FileRights or FolderRights -> FileSystemAccessRule/FileSystemAuditRule - -RegistryRights -> RegistryAccessRule/RegistryAuditRule - -ActiveDirectoryRights -> ActiveDirectoryAccessRule/ActiveDirectoryAuditRule - - - - - - - - - - - This function can be used to create ACEs that can be directly used with .NET -security descriptor objects obtained from Get-Acl. - - - - - -------------- Example 1 -------------- - - - - PS C:\> $SD = Get-Acl -Audit C:\powershell -$access = New-AccessControlEntry -FolderRights Modify -Principal Users -$audit = New-AccessControlEntry -AceType SystemAudit -FolderRights FullControl -Principal Users -AuditFailure -$SD.AddAccessRule($access) -$SD.AddAuditRule($audit) -$SD.Access -$SD.Audit - - These commands get the security descriptor for a folder named 'c:\powershell' using the native Get-Acl cmdlet (the Get-SecurityDescriptor function could be used instead). Then two ACEs are created: one to allow Modify rights for the Users group, the other to audit failures for any access. Then the rules are added to the SD, and finally the ACLs are listed to show that the SDs have been modified. Note that this example does not set the SD on the file (think of this as opening the permissions GUI in explorer and not clicking Apply). Set-Acl would be required to make the changes permanent. - -NOTE: Because of the -Audit switch parameter, the user must be an administrator. You can leave the audit changes out of the example if you're not running this as an administrator. - - - - - - - - - -------------- Example 2 -------------- - - - - PS C:\> $SD = Get-SecurityDescriptor -Audit C:\powershell\file.txt -$access = New-AccessControlEntry -FileRights Modify -Principal Users -$audit = New-AccessControlEntry -AceType SystemAudit -FileRights FullControl -Principal Users -AuditFailure -$SD.AddAccessRule($access) -$SD.AddAuditRule($audit) -$SD.Access -$SD.Audit -$SD | Format-List - - Very similar to example #1, except Get-SecurityDescriptor is used (see help on that function for more info). Also, the ACEs are created by using -FileRights parameter instead of -FolderRights. This changes what the ACE applies to by default (you can explicitly change this behavior by using the -AppliesTo parameter). - - - - - - - - - -------------- Example 3 -------------- - - - - PS C:\> $SD = Get-Item HKCU:\SOFTWARE | Get-SecurityDescriptor -$SD.AddAccessRule((New-AccessControlEntry -RegistryRights FullControl -Principal Users -OnlyApplyToThisContainer -AceType AccessDenied)) -$SD # View the ACL -$SD.Access # View the ACL with more detail - - This command adds a Deny ACE for the Users group that will apply only to the current key (subkeys won't inherit the ACE) to the DACL. It then displays the DACL two different ways. - -NOTE: This doesn't actually modify the SD that was obtained in the first line. It simply modifies the copy in memory. You still have to apply the SD back to the object. See Set-Acl or Set-SecurityDescriptor for more info. - - - - - - - - - -------------- Example 4 -------------- - - - - PS C:\> New-AccessControlEntry -AceType SystemAudit -ServiceAccessRights Start, Stop -Principal Users -AuditSuccess -AuditFailure - - This command creates an ACE that will audit successful and failed start and stop attempts by the Users group for the 'BITS' service. - - - - - - - - - -------------- Example 5 -------------- - - - - PS C:\> New-AccessControlEntry -WmiNamespaceRights RemoteEnable -Principal $env:USERNAME -OnlyApplyToThisContainer - - This example creates an ACE with the WMI 'Remote Enable' access mask for the current user. The ACE will only be applied to the object and direct child objects. Grandchild object will not inherit this entry. - - - - - - - - - -------------- Example 6 -------------- - - - - PS C:\> $SD = Get-ADUser $env:USERNAME | Get-SecurityDescriptor -PS C:\> $SD | Get-AccessControlEntry - - - This example requires the ActiveDirectory module as written. If you do not have -this module, you can still use either an [adsi] object, or a string -representation of the distinguished name for your user object. Simply pass -either of those to the Get-AccessControlEntry function. - -The previous command will show all discretionary ACEs for the current user's -AD user object. AD objects generally have much larger ACLs than other securable -objects, so there should be several ACEs returned. - -Get-AccessControlEntry can be used to filter the returned ACEs. Here are some -examples of filtering (make sure that $SD has been defined): - -PS C:\> $SD | Get-AccessControlEntry -InheritedObjectAceType user - -PS C:\> $SD | Get-AccessControlEntry -InheritedObjectAceType user -Specific - -PS C:\> $SD | Get-AccessControlEntry -ObjectAceType *password* -PS C:\> $SD | Get-AccessControlEntry -ObjectAceType (Get-ADObjectAceGuid) - - - - - - - - - - - - about_PowerShellAccessControl_Module - - - - Get-ADObjectAceGuid - - - - Get-SecurityDescriptor - - - - Get-Acl - - - - Set-SecurityDescriptor - - - - - - - - New-AdaptedSecurityDescriptor - - Creates an adapted view of a security descriptor from its SDDL or binary form. - - - - - New - AdaptedSecurityDescriptor - - - - - New-AdaptedSecurityDescriptor attempts to take the SDDL or binary form of a security descriptor and provide an object that resembles the objects returned from calls to Get-Acl. - -This function is for advanced use when Get-SecurityDescriptor can't handle the object you're using. - -The following properties/methods are created on the SD object: - * Path - The path to the object that the SD belongs to - * DisplayName - A description of the object that the security descriptor belongs to (sometimes the same as the Path property) - * SecurityDescriptor - The underlying SecurityDescriptor object - * AddAccessRule() - Adds a rule that was created using New-AccessControlEntry - * AddAuditRule() - See AddAccessRule() - * GetAccessMaskEnumeration() - Gets the access mask enumeration - * GetSecurityDescriptorBinaryForm() - Gets the SD in binary form - * RemoveAccessRule() - Removes a specific access or audit rule (the ACE is supplied as a parameter) - * RemoveAuditRule() - See RemoveAccessRule() - * Access - Provide a list of the ACEs in the DACL - * Audit - Provide a list of the ACEs in the SACL - * AccessToString - Provide a string that contains some of the Access informaton - * AuditToString - Provide a string that contains some of the Audit information - * Group - The owning group (not really used) - * Owner - The owner of the object - * Sddl - The SDDL representaton of the SD - -When the default formatting is used, the following information is shown for each ACE: - - The type (AccessAllowed, AccessDenied, Success Audit, Failure Audit) - - The IdentityReference - - The access mask - - Whether or not the ACE is inherited - - What the ACE applies to (the formatting system shows a shorthand for this): - O = This object, e.g., a folder object - CC = child containers, e.g., sub folder objects - CO = child leaf objects, e.g., files - - Whether or not the ACE only applies to direct children - - - - New-AdaptedSecurityDescriptor - - Sddl - - SDDL form of security descriptor - - String - - - AccessMaskEnumeration - - An enumeration that is used to translate the numeric access mask to friendly text when viewing the access and/or audit entries of the security descriptor. - - Type - - - Path - - The path to the security descriptor. This is used for identifying the object that the security descriptor belongs to. - - String - - - ObjectType - - This keeps track of the type of object that the security descriptor belongs to. This property (and the -SdPath property) is important for the Set-SecurityDescriptor function. If the security descriptor isn't going to be saved, then this property isn't as important. - - ResourceType - - - SdPath - - This keeps track of the path to the object that the security descriptor belongs to. This property (and the -ObjectType property) is important for the Set-SecurityDescriptor function. If the security descriptor isn't going to be saved, then this property isn't as important. This property differs from the -Path property because some ObjectTypes have different path formats than the PowerShell providers can handle. - - Object - - - DisplayName - - A friendly name for the object that the security descriptor belongs to. - - String - - - IsContainer - - Specifies whether or not the security descriptor belongs to a container, e.g., folder, registry key, WMI namespace, or any other securable object that can have children. If this isn't specified, it's assumed that the security descriptor belongs to an object that is not a container. - - SwitchParameter - - - IsDsObject - - - - SwitchParameter - - - DsObjectClass - - - - String - - - - New-AdaptedSecurityDescriptor - - BinarySD - - Binary form of security descriptor - - Byte[] - - - AccessMaskEnumeration - - An enumeration that is used to translate the numeric access mask to friendly text when viewing the access and/or audit entries of the security descriptor. - - Type - - - Path - - The path to the security descriptor. This is used for identifying the object that the security descriptor belongs to. - - String - - - ObjectType - - This keeps track of the type of object that the security descriptor belongs to. This property (and the -SdPath property) is important for the Set-SecurityDescriptor function. If the security descriptor isn't going to be saved, then this property isn't as important. - - ResourceType - - - SdPath - - This keeps track of the path to the object that the security descriptor belongs to. This property (and the -ObjectType property) is important for the Set-SecurityDescriptor function. If the security descriptor isn't going to be saved, then this property isn't as important. This property differs from the -Path property because some ObjectTypes have different path formats than the PowerShell providers can handle. - - Object - - - DisplayName - - A friendly name for the object that the security descriptor belongs to. - - String - - - IsContainer - - Specifies whether or not the security descriptor belongs to a container, e.g., folder, registry key, WMI namespace, or any other securable object that can have children. If this isn't specified, it's assumed that the security descriptor belongs to an object that is not a container. - - SwitchParameter - - - IsDsObject - - - - SwitchParameter - - - DsObjectClass - - - - String - - - - - - Sddl - - SDDL form of security descriptor - - String - - String - - - - - - AccessMaskEnumeration - - An enumeration that is used to translate the numeric access mask to friendly text when viewing the access and/or audit entries of the security descriptor. - - Type - - Type - - - - - - Path - - The path to the security descriptor. This is used for identifying the object that the security descriptor belongs to. - - String - - String - - - - - - ObjectType - - This keeps track of the type of object that the security descriptor belongs to. This property (and the -SdPath property) is important for the Set-SecurityDescriptor function. If the security descriptor isn't going to be saved, then this property isn't as important. - - ResourceType - - ResourceType - - - - - - SdPath - - This keeps track of the path to the object that the security descriptor belongs to. This property (and the -ObjectType property) is important for the Set-SecurityDescriptor function. If the security descriptor isn't going to be saved, then this property isn't as important. This property differs from the -Path property because some ObjectTypes have different path formats than the PowerShell providers can handle. - - Object - - Object - - - - - - DisplayName - - A friendly name for the object that the security descriptor belongs to. - - String - - String - - - - - - IsContainer - - Specifies whether or not the security descriptor belongs to a container, e.g., folder, registry key, WMI namespace, or any other securable object that can have children. If this isn't specified, it's assumed that the security descriptor belongs to an object that is not a container. - - SwitchParameter - - SwitchParameter - - - - - - IsDsObject - - - - SwitchParameter - - SwitchParameter - - - - - - DsObjectClass - - - - String - - String - - - - - - BinarySD - - Binary form of security descriptor - - Byte[] - - Byte[] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -------------- Example 1 -------------- - - - - PS C:\> Get-CimInstance Win32_LogicalShareSecuritySetting | Get-Win32SecurityDescriptor -Sddl | New-AdaptedSecurityDescriptor - - This will get a list of all shares on the computer, and get an "adapted" security descriptor for each one. Since no extra information was provided, there will be no path information or display name associated with the security descriptor. Also, the access control entries will show numeric access masks since an access mask enumeration wasn't supplied. See example #2 for an example where this information is provided. - - - - - - - - - -------------- Example 2 -------------- - - - - PS C:\> Get-CimInstance Win32_LogicalShareSecuritySetting | Get-Win32SecurityDescriptor -Sddl | foreach { New-AdaptedSecurityDescriptor -AccessMaskEnumeration ([PowerShellAccessControl.LogicalShareRights]) -Path $_.Path -Sddl $_.Sddl } - - This is the same as example #1, except the resulting security descriptors will be easier to read, and they will have path information that shows the object that owns the security descriptor. - -NOTE: The Get-SecurityDescriptor function should be used to get share information instead of New-AdaptedSecurityDescriptor - - - - - - - - - -------------- Example 3 -------------- - - - - PS C:\> New-AdaptedSecurityDescriptor -BinarySD (gp HKLM:\SOFTWARE\Microsoft\Ole | select -exp MachineAccessRestriction) - - This is an example of converting a binary security descriptor into a more readable security descriptor. - - - - - - - - - - - about_PowerShellAccessControl_Module - - - - - - - - Remove-AccessControlEntry - - Remove an access control entry to a security descriptor. - - - - - Remove - AccessControlEntry - - - - - Remove-AccessControlEntry allows the removal of access control entries (ACEs) from either the discretionary access control list (DACL), which deals with object access, or the system access control list (SACL), which deals with object auditing). - -The function will automatically determine which ACL to modify by inspecting the ACE object. - -There are four major ways to use this function: -1. Remove a specific set of permissions from any existing matching ACEs - This is the default behavior when you supply a security object and an ACE (which can be specified - through the -AceObject parameter, through the ACE creation parameters (which resemble - New-AccessControlEntry), or from output from the Get-AccessControlEntry function. - - An example would be to remove 'Write' allow access from the 'Users' group when an existing ACE that - grants 'Read' and 'Write' access already exists. After running this function, the existing ACE would - only grant 'Read' access. See the examples section for more information. - -2. Remove a specific ACE - This is the same as #1 above, except the -Specific switch is applied. Using the example mentioned, - running the function with the -Specific switch wouldn't modify the ACL since the supplied ACE with - 'Write' permission wouldn't match the existing ACE with 'Read' and 'Write' permission. See the - examples section for more information. - -3. Remove a specific principal from an ACL - To remove a specific principal from either ACL, provide a user/group name or a security identifier to - the -PurgePrincipal parameter. You can also specify the -PurgeAccessRules and/or the -PurgeAuditRules - to specify which ACLs to remove the principal from (if neither is specified, the function behaves as - if -PurgeAccessRules was specified). - -4. Remove all ACEs from an ACL - To clear all entries from an ACL, specify the -RemoveAllAccessEntries and/or -RemoveAllAuditEntries - switch parameters. It is possible to use one at a time, or both at the same time. - -The function determines which ACL to remove the ACE from by looking at the ACE's AceType (either AccessAllowed, AccessDenied, or SystemAudit). It can also look at some other specific rule types, e.g., FileSystemAccessRules, FileSystemAuditRules, RegistryAccessRules, and RegistryAuditRules, and determine which ACL to remove them from. - -The function has several different usage scenarios. It will always need to be able to determine two parameters: the SDObject and the AceObject. For more information, please read the detailed parameter information for each in the 'Parameters' section. The 'Examples' section also provides some examples of each scenario. - - - - Remove-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry -removed from it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - AceObject - - This is one or more ACEs to be removed from the security descriptor. Each ACE -will be removed from each security descriptor in the -SDObject parameter (which -means more than one -AceObject and/or -SDObject can be provided). - -The -AceObject objects can be created via the New-AccessControlEntry, they can -come from the Access and/or Audit properties of a security descriptor, or they -can come from Get-AccessControlEntry. - - Object[] - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Specific - - Only remove an ACE if it exactly matches the ACE provided in -AceObject or -through the ACE creation parameters. By default, the function will remove the -specific access rights from an existing ACE that matches the principal and ACE -type. For example, under the default behavior, if an ACE granting 'FullControl' -exists for the 'Users' principal, and the -AceObject passed to this function -has access of 'Write', then only the 'Write' access will be removed from the -ACE that exists. If the -Specific switch is specified, though, the example -presented wouldn't make a change since the 'FullConrol' ACE doesn't match the -'Write' access mask. - - SwitchParameter - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Remove-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry -removed from it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - RemoveAllAccessEntries - - Remove all discretionary ACEs from the security descriptor. - - SwitchParameter - - - RemoveAllAuditEntries - - Remove all system ACEs from the security descriptor. - - SwitchParameter - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Remove-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry -removed from it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - PurgeAccessRules - - Removes every discretionary (Access) ACE that applies to the principal -specified in the -Principal parameter. - - - SwitchParameter - - - PurgeAuditRules - - Removes every system (Audit) ACE that applies to the principal -specified in the -Principal parameter. - - SwitchParameter - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Remove-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry -removed from it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Specific - - Only remove an ACE if it exactly matches the ACE provided in -AceObject or -through the ACE creation parameters. By default, the function will remove the -specific access rights from an existing ACE that matches the principal and ACE -type. For example, under the default behavior, if an ACE granting 'FullControl' -exists for the 'Users' principal, and the -AceObject passed to this function -has access of 'Write', then only the 'Write' access will be removed from the -ACE that exists. If the -Specific switch is specified, though, the example -presented wouldn't make a change since the 'FullConrol' ACE doesn't match the -'Write' access mask. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - WsManAccessRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - WsManAccessRights - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Remove-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry -removed from it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Specific - - Only remove an ACE if it exactly matches the ACE provided in -AceObject or -through the ACE creation parameters. By default, the function will remove the -specific access rights from an existing ACE that matches the principal and ACE -type. For example, under the default behavior, if an ACE granting 'FullControl' -exists for the 'Users' principal, and the -AceObject passed to this function -has access of 'Write', then only the 'Write' access will be removed from the -ACE that exists. If the -Specific switch is specified, though, the example -presented wouldn't make a change since the 'FullConrol' ACE doesn't match the -'Write' access mask. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - ProcessAccessRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - ProcessAccessRights - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Remove-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry -removed from it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Specific - - Only remove an ACE if it exactly matches the ACE provided in -AceObject or -through the ACE creation parameters. By default, the function will remove the -specific access rights from an existing ACE that matches the principal and ACE -type. For example, under the default behavior, if an ACE granting 'FullControl' -exists for the 'Users' principal, and the -AceObject passed to this function -has access of 'Write', then only the 'Write' access will be removed from the -ACE that exists. If the -Specific switch is specified, though, the example -presented wouldn't make a change since the 'FullConrol' ACE doesn't match the -'Write' access mask. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - ServiceAccessRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - ServiceAccessRights - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Remove-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry -removed from it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Specific - - Only remove an ACE if it exactly matches the ACE provided in -AceObject or -through the ACE creation parameters. By default, the function will remove the -specific access rights from an existing ACE that matches the principal and ACE -type. For example, under the default behavior, if an ACE granting 'FullControl' -exists for the 'Users' principal, and the -AceObject passed to this function -has access of 'Write', then only the 'Write' access will be removed from the -ACE that exists. If the -Specific switch is specified, though, the example -presented wouldn't make a change since the 'FullConrol' ACE doesn't match the -'Write' access mask. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - WmiNameSpaceRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - WmiNamespaceRights - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Remove-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry -removed from it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Specific - - Only remove an ACE if it exactly matches the ACE provided in -AceObject or -through the ACE creation parameters. By default, the function will remove the -specific access rights from an existing ACE that matches the principal and ACE -type. For example, under the default behavior, if an ACE granting 'FullControl' -exists for the 'Users' principal, and the -AceObject passed to this function -has access of 'Write', then only the 'Write' access will be removed from the -ACE that exists. If the -Specific switch is specified, though, the example -presented wouldn't make a change since the 'FullConrol' ACE doesn't match the -'Write' access mask. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - PrinterRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - PrinterRights - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Remove-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry -removed from it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Specific - - Only remove an ACE if it exactly matches the ACE provided in -AceObject or -through the ACE creation parameters. By default, the function will remove the -specific access rights from an existing ACE that matches the principal and ACE -type. For example, under the default behavior, if an ACE granting 'FullControl' -exists for the 'Users' principal, and the -AceObject passed to this function -has access of 'Write', then only the 'Write' access will be removed from the -ACE that exists. If the -Specific switch is specified, though, the example -presented wouldn't make a change since the 'FullConrol' ACE doesn't match the -'Write' access mask. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - LogicalShareRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - LogicalShareRights - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Remove-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry -removed from it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Specific - - Only remove an ACE if it exactly matches the ACE provided in -AceObject or -through the ACE creation parameters. By default, the function will remove the -specific access rights from an existing ACE that matches the principal and ACE -type. For example, under the default behavior, if an ACE granting 'FullControl' -exists for the 'Users' principal, and the -AceObject passed to this function -has access of 'Write', then only the 'Write' access will be removed from the -ACE that exists. If the -Specific switch is specified, though, the example -presented wouldn't make a change since the 'FullConrol' ACE doesn't match the -'Write' access mask. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - ObjectAceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - InheritedObjectAceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Remove-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry -removed from it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Specific - - Only remove an ACE if it exactly matches the ACE provided in -AceObject or -through the ACE creation parameters. By default, the function will remove the -specific access rights from an existing ACE that matches the principal and ACE -type. For example, under the default behavior, if an ACE granting 'FullControl' -exists for the 'Users' principal, and the -AceObject passed to this function -has access of 'Write', then only the 'Write' access will be removed from the -ACE that exists. If the -Specific switch is specified, though, the example -presented wouldn't make a change since the 'FullConrol' ACE doesn't match the -'Write' access mask. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - ActiveDirectoryRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - ActiveDirectoryRights - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - ObjectAceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - InheritedObjectAceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Remove-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry -removed from it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Specific - - Only remove an ACE if it exactly matches the ACE provided in -AceObject or -through the ACE creation parameters. By default, the function will remove the -specific access rights from an existing ACE that matches the principal and ACE -type. For example, under the default behavior, if an ACE granting 'FullControl' -exists for the 'Users' principal, and the -AceObject passed to this function -has access of 'Write', then only the 'Write' access will be removed from the -ACE that exists. If the -Specific switch is specified, though, the example -presented wouldn't make a change since the 'FullConrol' ACE doesn't match the -'Write' access mask. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - RegistryRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - RegistryRights - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Remove-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry -removed from it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Specific - - Only remove an ACE if it exactly matches the ACE provided in -AceObject or -through the ACE creation parameters. By default, the function will remove the -specific access rights from an existing ACE that matches the principal and ACE -type. For example, under the default behavior, if an ACE granting 'FullControl' -exists for the 'Users' principal, and the -AceObject passed to this function -has access of 'Write', then only the 'Write' access will be removed from the -ACE that exists. If the -Specific switch is specified, though, the example -presented wouldn't make a change since the 'FullConrol' ACE doesn't match the -'Write' access mask. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - FolderRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - FileSystemRights - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Remove-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry -removed from it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Specific - - Only remove an ACE if it exactly matches the ACE provided in -AceObject or -through the ACE creation parameters. By default, the function will remove the -specific access rights from an existing ACE that matches the principal and ACE -type. For example, under the default behavior, if an ACE granting 'FullControl' -exists for the 'Users' principal, and the -AceObject passed to this function -has access of 'Write', then only the 'Write' access will be removed from the -ACE that exists. If the -Specific switch is specified, though, the example -presented wouldn't make a change since the 'FullConrol' ACE doesn't match the -'Write' access mask. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - FileRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - FileSystemRights - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - Remove-AccessControlEntry - - SDObject - - Specifies the security descriptor that will have an access control entry -removed from it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - - Specific - - Only remove an ACE if it exactly matches the ACE provided in -AceObject or -through the ACE creation parameters. By default, the function will remove the -specific access rights from an existing ACE that matches the principal and ACE -type. For example, under the default behavior, if an ACE granting 'FullControl' -exists for the 'Users' principal, and the -AceObject passed to this function -has access of 'Write', then only the 'Write' access will be removed from the -ACE that exists. If the -Specific switch is specified, though, the example -presented wouldn't make a change since the 'FullConrol' ACE doesn't match the -'Write' access mask. - - SwitchParameter - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - AccessMask - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Int32 - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - - ObjectAceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - InheritedObjectAceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - - - - - SDObject - - Specifies the security descriptor that will have an access control entry -removed from it. - -This parameter can be any combination of one or more of the following objects: -1. A security descriptor object obtained through the Get-Acl cmdlet -2. A security descriptor object obtained through the Get-SecurityDescriptor or - New-AdaptedSecurityDescriptor functions -3. An object (including a path string) that the Get-SecurityDescriptor function - knows how to handle. - - Object - - Object - - - - - - AceObject - - This is one or more ACEs to be removed from the security descriptor. Each ACE -will be removed from each security descriptor in the -SDObject parameter (which -means more than one -AceObject and/or -SDObject can be provided). - -The -AceObject objects can be created via the New-AccessControlEntry, they can -come from the Access and/or Audit properties of a security descriptor, or they -can come from Get-AccessControlEntry. - - Object[] - - Object[] - - - - - - Apply - - Causes the security descriptor to be saved to the securable object. By default, -when a security descriptor object is provided as input to the SDObject -parameter, the in memory security descriptor is changed, and a separate call to -Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the -change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input and the -PassThru -switch is not specified, the default behavior is to set this switch and prompt -the user before saving the security descriptor (the -Force parameter would -suppress the prompt). - - SwitchParameter - - SwitchParameter - - - - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts -about saving the security descriptor. - - SwitchParameter - - SwitchParameter - - - - - - PassThru - - Returns the modified security descriptor object. By default, this function does -not generate any output. This parameter is useful when multiple security -descriptor modifications need to be made in a single line (each call can be -piped to the next one). - - SwitchParameter - - SwitchParameter - - - - - - Specific - - Only remove an ACE if it exactly matches the ACE provided in -AceObject or -through the ACE creation parameters. By default, the function will remove the -specific access rights from an existing ACE that matches the principal and ACE -type. For example, under the default behavior, if an ACE granting 'FullControl' -exists for the 'Users' principal, and the -AceObject passed to this function -has access of 'Write', then only the 'Write' access will be removed from the -ACE that exists. If the -Specific switch is specified, though, the example -presented wouldn't make a change since the 'FullConrol' ACE doesn't match the -'Write' access mask. - - SwitchParameter - - SwitchParameter - - - - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - SwitchParameter - - - - - - Confirm - - Causes the function to prompt for confirmation before making any changes. - - SwitchParameter - - SwitchParameter - - - - - - RemoveAllAccessEntries - - Remove all discretionary ACEs from the security descriptor. - - SwitchParameter - - SwitchParameter - - - - - - RemoveAllAuditEntries - - Remove all system ACEs from the security descriptor. - - SwitchParameter - - SwitchParameter - - - - - - PurgeAccessRules - - Removes every discretionary (Access) ACE that applies to the principal -specified in the -Principal parameter. - - - SwitchParameter - - SwitchParameter - - - - - - PurgeAuditRules - - Removes every system (Audit) ACE that applies to the principal -specified in the -Principal parameter. - - SwitchParameter - - SwitchParameter - - - - - - Principal - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - Object - - - - - - AceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - String - - String - - - - - - AppliesTo - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - AppliesTo - - AppliesTo - - - - - - OnlyApplyToThisContainer - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - SwitchParameter - - SwitchParameter - - - - - - WsManAccessRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - WsManAccessRights - - WsManAccessRights - - - - - - ProcessAccessRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - ProcessAccessRights - - ProcessAccessRights - - - - - - ServiceAccessRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - ServiceAccessRights - - ServiceAccessRights - - - - - - WmiNameSpaceRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - WmiNamespaceRights - - WmiNamespaceRights - - - - - - PrinterRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - PrinterRights - - PrinterRights - - - - - - LogicalShareRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - LogicalShareRights - - LogicalShareRights - - - - - - ObjectAceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - Object - - - - - - InheritedObjectAceType - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Object - - Object - - - - - - ActiveDirectoryRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - ActiveDirectoryRights - - ActiveDirectoryRights - - - - - - RegistryRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - RegistryRights - - RegistryRights - - - - - - FolderRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - FileSystemRights - - FileSystemRights - - - - - - FileRights - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - FileSystemRights - - FileSystemRights - - - - - - AccessMask - - This parameter is passed directly to the New-AccessControlEntry function. -Please see the help for that function for more information. - - Int32 - - Int32 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -------------- Example 1 -------------- - - - - PS C:\> dir C:\folder -recurse | Get-SecurityDescriptor -Audit | Remove-AccessControlEntry -RemoveAllAccessEntries -RemoveAllAuditEntries -PassThru | Enable-AclInheritance -DiscretionaryAcl -SystemAcl -PassThru | Set-SecurityDescriptor - - This will reset the security descriptors for all files and folders under the C:\folder folder. All explicitly defined discretionary and system ACEs will be removed, and any entries that apply to child containers and objects from c:\folder are propagated. - - - - - - - - - -------------- Example 2 -------------- - - - - PS C:\> $TargetFolder = 'C:\Folder1' - -PS C:\> $TargetFolder | Remove-AccessControlEntry -RemoveAllAccessEntries - -PS C:\> $TargetFolder | Get-AccessControlEntry -NotInherited | Remove-AccessControlEntry - - This will remove all explicitly defined discretionary ACEs from the 'C:\Folder1' folder. The last two lines show two different ways to do this. - - - - - - - - - -------------- Example 3 -------------- - - - - PS C:\> gwmi Win32_Share | Get-AccessControlEntry -LogicalShareRights FullControl -ErrorAction SilentlyContinue | Remove-AccessControlEntry -WhatIf - - NOTE: This probably wouldn't be a good command to run without the -WhatIf parameter, since it will remove any ACEs with share rights of 'Full Control' (even though they could be added back). The example uses -WhatIf, so it should be safe. - -This example will get all of the shares on the machine (it can be run against a remote machine if the -ComputerName parameter is passed to Get-WmiObject), and searches for any ACEs with the 'Full Control' share rights. Any entries that are found are removed from the share(s). - - - - - - - - - -------------- Example 4 -------------- - - - - PS C:\> Get-Service b* | Remove-AccessControlEntry (New-AccessControlEntry -Principal Users -ServiceAccessRights Start, Stop) -WhatIf - -Get-Service b* | Remove-AccessControlEntry -Principal Users -ServiceAccessRights Start, Stop -WhatIf - - - - - - - - - - - -------------- Example 5 -------------- - - - - PS C:\> $Demo = New-Item -Path "$env:TEMP\pac_demo" -ItemType directory -PS C:\> $Demo | Add-AccessControlEntry -Principal Users -FolderRights Modify -Force -PS C:\> $Demo | Remove-AccessControlEntry -Principal Users -FolderRights Write,Delete - - This example creates a new folder under the current user's temp directory. Then it adds an ACE that gives 'Users' modify rights to the folder. Next, it removes the 'Write' and 'Delete' rights for the 'Users' group, which will leave an ACE with 'ReadAndExecute' rights. - - - - - - - - - -------------- Example 6 -------------- - - - - PS C:\> $Demo = New-Item -Path "$env:TEMP\pac_demo" -ItemType directory -PS C:\> $Demo | Add-AccessControlEntry -Principal Users -FolderRights Modify -Force -PS C:\> $Demo | Remove-AccessControlEntry -Principal Users -FolderRights Write,Delete -Specific - - This is the same as the previous example, except the call to Remove-AccessControlEntry won't remove anything since there is no ACE that has only 'Write' and 'Delete' permissions. If the -FolderRights parameter were changed to 'Modify', then the ACE that was created by using Add-AccessControlEntry would be deleted. - - - - - - - - - -------------- Example 7 -------------- - - - - PS C:\> $Demo = New-Item -Path "$env:TEMP\pac_demo" -ItemType directory -PS C:\> $Demo | Add-AccessControlEntry -Principal Users -FolderRights Modify -Force -PS C:\> $Demo | Remove-AccessControlEntry -PurgePrincipal Users - - This is similar to the previous to examples, except it uses the -PurgePrincipal parameter. Since 'Users' was passed to it, it will remove any ACE that applies to 'Users' (Allow or Deny) from the discretionary ACL. The -PurgeAuditRules switch could have also been used. - - - - - - - - - - - about_PowerShellAccessControl_Module - - - - Get-SecurityDescriptor - - - - Set-SecurityDescriptor - - - - New-AccessControlEntry - - - - Add-AccessControlEntry - - - - Get-Acl - - - - - - - - Repair-AclCanonicalOrder - - Repairs a discretionary ACL's ACE order. - - - - - Repair - AclCanonicalOrder - - - - - The Repair-AclCanonicalOrder function repairs a DACL whose ACEs are not in canonical ordering. The example sections shows an example of how ACE entries can lose canonical ordering. - - - - Repair-AclCanonicalOrder - - InputObject - - This can be either a security descriptor object obtained from Get-SecurityDescriptor, or an object that owns the security descriptor whose DACL is to be reordered. If it is an object that owns the security descriptor, Get-SecurityDescriptor will be called against it internally. - - Object - - - DiscretionaryAcl - - Causes the DACL to be re-ordered for the specified object/security descriptor. This switch can be used at the same time as the -SystemAcl switch. - - SwitchParameter - - - SystemAcl - - Causes the SACL to be re-ordered for the specified object/security descriptor. This switch can be used at the same time as the -DiscretionaryAcl switch. - - SwitchParameter - - - Apply - - Causes the security descriptor to be saved. By default, when a security descriptor object is provided as input to the InputObject parameter, the in memory security descriptor is changed, and a separate call to Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input, and the -PassThru switch is not specified, the default behavior is to set this switch and prompt the user before saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the newly modified security descriptor object. By default, this function does not generate any output. - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts about saving the security descriptor. - - SwitchParameter - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Prompts you for confirmation before making any changes. - - SwitchParameter - - - - Repair-AclCanonicalOrder - - Path - - Specifies the path to a resource whose DACL is to be changed. - - String[] - - - DiscretionaryAcl - - Causes the DACL to be re-ordered for the specified object/security descriptor. This switch can be used at the same time as the -SystemAcl switch. - - SwitchParameter - - - SystemAcl - - Causes the SACL to be re-ordered for the specified object/security descriptor. This switch can be used at the same time as the -DiscretionaryAcl switch. - - SwitchParameter - - - Apply - - Causes the security descriptor to be saved. By default, when a security descriptor object is provided as input to the InputObject parameter, the in memory security descriptor is changed, and a separate call to Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input, and the -PassThru switch is not specified, the default behavior is to set this switch and prompt the user before saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the newly modified security descriptor object. By default, this function does not generate any output. - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts about saving the security descriptor. - - SwitchParameter - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Prompts you for confirmation before making any changes. - - SwitchParameter - - - - Repair-AclCanonicalOrder - - LiteralPath - - Specifies the path to a resource whose DACL is to be changed. - -Unlike Path, the value of the LiteralPath parameter is used exactly as it is typed. No characters are interpreted as wildcards. If the path includes escape characters, enclose it in single quotation marks. Single quotation marks tell Windows PowerShell not to interpret any characters as escape sequences. - - String[] - - - DiscretionaryAcl - - Causes the DACL to be re-ordered for the specified object/security descriptor. This switch can be used at the same time as the -SystemAcl switch. - - SwitchParameter - - - SystemAcl - - Causes the SACL to be re-ordered for the specified object/security descriptor. This switch can be used at the same time as the -DiscretionaryAcl switch. - - SwitchParameter - - - Apply - - Causes the security descriptor to be saved. By default, when a security descriptor object is provided as input to the InputObject parameter, the in memory security descriptor is changed, and a separate call to Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input, and the -PassThru switch is not specified, the default behavior is to set this switch and prompt the user before saving the security descriptor. - - SwitchParameter - - - PassThru - - Returns the newly modified security descriptor object. By default, this function does not generate any output. - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts about saving the security descriptor. - - SwitchParameter - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Prompts you for confirmation before making any changes. - - SwitchParameter - - - - - - InputObject - - This can be either a security descriptor object obtained from Get-SecurityDescriptor, or an object that owns the security descriptor whose DACL is to be reordered. If it is an object that owns the security descriptor, Get-SecurityDescriptor will be called against it internally. - - Object - - Object - - - - - - DiscretionaryAcl - - Causes the DACL to be re-ordered for the specified object/security descriptor. This switch can be used at the same time as the -SystemAcl switch. - - SwitchParameter - - SwitchParameter - - - - - - SystemAcl - - Causes the SACL to be re-ordered for the specified object/security descriptor. This switch can be used at the same time as the -DiscretionaryAcl switch. - - SwitchParameter - - SwitchParameter - - - - - - Apply - - Causes the security descriptor to be saved. By default, when a security descriptor object is provided as input to the InputObject parameter, the in memory security descriptor is changed, and a separate call to Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the change to be made without a separate call to Set-SecurityDescriptor. - -If a non security descriptor object is provided as input, and the -PassThru switch is not specified, the default behavior is to set this switch and prompt the user before saving the security descriptor. - - SwitchParameter - - SwitchParameter - - - - - - PassThru - - Returns the newly modified security descriptor object. By default, this function does not generate any output. - - SwitchParameter - - SwitchParameter - - - - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts about saving the security descriptor. - - SwitchParameter - - SwitchParameter - - - - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - SwitchParameter - - - - - - Confirm - - Prompts you for confirmation before making any changes. - - SwitchParameter - - SwitchParameter - - - - - - Path - - Specifies the path to a resource whose DACL is to be changed. - - String[] - - String[] - - - - - - LiteralPath - - Specifies the path to a resource whose DACL is to be changed. - -Unlike Path, the value of the LiteralPath parameter is used exactly as it is typed. No characters are interpreted as wildcards. If the path includes escape characters, enclose it in single quotation marks. Single quotation marks tell Windows PowerShell not to interpret any characters as escape sequences. - - String[] - - String[] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -------------- Example 1 -------------- - - - - PS C:\> # Create folders: -PS C:\> $DemoParent = New-Item -Path "$env:temp\break_canonical_order" -ItemType directory -PS C:\> $DemoChild = New-Item -Path "$DemoParent\child_folder" -ItemType directory - -# Set permissions to break canonical ordering: -PS C:\> $DemoParent | Add-AccessControlEntry -Principal Guests -FolderRights FullControl -AceType AccessDenied -Force -PS C:\> $DemoChild | Add-AccessControlEntry -Principal Users -FolderRights Read -PassThru | Disable-AclInheritance -PreserveExistingAces -Apply -Force - -# Confirm DACL is not in canonical order: -PS C:\> $DemoChild | Get-SecurityDescriptor | fl AccessToString, AreAccessRulesCanonical - -# Fix it and confirm: -PS C:\> $DemoChild | Repair-AclCanonicalOrder -PS C:\> $DemoChild | Get-SecurityDescriptor | fl AccessToString, AreAccessRulesCanonical - - This example will set up a folder whose DACL is not in canonical order, and then it will fix it. - - - - - - - - - - - - - - - Set-Owner - - Changes the owner of a securable object. - - - - - Set - Owner - - - - - Set-Owner allows the changing of a securable object's owner. An administrator can take ownership or assign ownership to another user or group (as long as they have the proper privileges). A regular user can take ownership of an object in certain circumstances (specifically if they have the WRITE_DAC access right assigned, which should be contained in a FullControl ACE). - - - - Set-Owner - - Principal - - The new owner of the object. This can be a string representing a user, group, or SID. It can also be a [System.Security.Principal.NTAccount] or a [System.Security.Principal.SecurityIdentifier] object. - - Object - - - Path - - Specifies the path to a resource whose owner should be changed. Wildcards are -permitted (unless the -ObjectType parameter is also used). - - String[] - - - Apply - - Causes the modified owner information to be saved. By default, when a security descriptor object is provided as input to the SDObject parameter, the in memory security descriptor is changed, and a separate call to Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the change to be made without a separate call to Set-SecurityDescriptor. It will also only attempt to set the owner (any DACL and/or SACL changes will be ignored). - -If a non security descriptor object is provided as input, and the -PassThru switch is not specified, the default behavior is to set this switch and prompt the user before saving the security descriptor. - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts about saving the owner. - - SwitchParameter - - - PassThru - - Returns the newly modified security descriptor object. By default, this function does not generate any output. - - SwitchParameter - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Prompts you for confirmation before making any changes. - - SwitchParameter - - - - Set-Owner - - Principal - - The new owner of the object. This can be a string representing a user, group, or SID. It can also be a [System.Security.Principal.NTAccount] or a [System.Security.Principal.SecurityIdentifier] object. - - Object - - - InputObject - - - - Object - - - Apply - - Causes the modified owner information to be saved. By default, when a security descriptor object is provided as input to the SDObject parameter, the in memory security descriptor is changed, and a separate call to Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the change to be made without a separate call to Set-SecurityDescriptor. It will also only attempt to set the owner (any DACL and/or SACL changes will be ignored). - -If a non security descriptor object is provided as input, and the -PassThru switch is not specified, the default behavior is to set this switch and prompt the user before saving the security descriptor. - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts about saving the owner. - - SwitchParameter - - - PassThru - - Returns the newly modified security descriptor object. By default, this function does not generate any output. - - SwitchParameter - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Prompts you for confirmation before making any changes. - - SwitchParameter - - - - Set-Owner - - Principal - - The new owner of the object. This can be a string representing a user, group, or SID. It can also be a [System.Security.Principal.NTAccount] or a [System.Security.Principal.SecurityIdentifier] object. - - Object - - - Path - - Specifies the path to a resource whose owner should be changed. Wildcards are -permitted (unless the -ObjectType parameter is also used). - - String[] - - - ObjectType - - When a security descriptor object isn't specified to Set-Owner, the function will call Get-SecurityDescriptor, which will attempt to determine the object type of the object specified in the Path, LiteralPath, or SDObject. Using this parameter allows you to specify a specific object type. Non-filesystem paths must be in a format that PowerShell doesn't natively understand. See the following link for path formatting information: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379593(v=vs.85).aspx - - ResourceType - - - IsContainer - - - - SwitchParameter - - - Apply - - Causes the modified owner information to be saved. By default, when a security descriptor object is provided as input to the SDObject parameter, the in memory security descriptor is changed, and a separate call to Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the change to be made without a separate call to Set-SecurityDescriptor. It will also only attempt to set the owner (any DACL and/or SACL changes will be ignored). - -If a non security descriptor object is provided as input, and the -PassThru switch is not specified, the default behavior is to set this switch and prompt the user before saving the security descriptor. - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts about saving the owner. - - SwitchParameter - - - PassThru - - Returns the newly modified security descriptor object. By default, this function does not generate any output. - - SwitchParameter - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Prompts you for confirmation before making any changes. - - SwitchParameter - - - - Set-Owner - - Principal - - The new owner of the object. This can be a string representing a user, group, or SID. It can also be a [System.Security.Principal.NTAccount] or a [System.Security.Principal.SecurityIdentifier] object. - - Object - - - LiteralPath - - Specifies the path to a resource whose owner should be changed. - -Unlike Path, the value of the LiteralPath parameter is used exactly as it is -typed. No characters are interpreted as wildcards. If the path includes escape -characters, enclose it in single quotation marks. Single quotation marks tell -Windows PowerShell not to interpret any characters as escape sequences. - - String[] - - - Apply - - Causes the modified owner information to be saved. By default, when a security descriptor object is provided as input to the SDObject parameter, the in memory security descriptor is changed, and a separate call to Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the change to be made without a separate call to Set-SecurityDescriptor. It will also only attempt to set the owner (any DACL and/or SACL changes will be ignored). - -If a non security descriptor object is provided as input, and the -PassThru switch is not specified, the default behavior is to set this switch and prompt the user before saving the security descriptor. - - SwitchParameter - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts about saving the owner. - - SwitchParameter - - - PassThru - - Returns the newly modified security descriptor object. By default, this function does not generate any output. - - SwitchParameter - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Prompts you for confirmation before making any changes. - - SwitchParameter - - - - - - Principal - - The new owner of the object. This can be a string representing a user, group, or SID. It can also be a [System.Security.Principal.NTAccount] or a [System.Security.Principal.SecurityIdentifier] object. - - Object - - Object - - - - - - Path - - Specifies the path to a resource whose owner should be changed. Wildcards are -permitted (unless the -ObjectType parameter is also used). - - String[] - - String[] - - - - - - Apply - - Causes the modified owner information to be saved. By default, when a security descriptor object is provided as input to the SDObject parameter, the in memory security descriptor is changed, and a separate call to Set-SecurityDescriptor saves the changes. Using the -Apply switch causes the change to be made without a separate call to Set-SecurityDescriptor. It will also only attempt to set the owner (any DACL and/or SACL changes will be ignored). - -If a non security descriptor object is provided as input, and the -PassThru switch is not specified, the default behavior is to set this switch and prompt the user before saving the security descriptor. - - SwitchParameter - - SwitchParameter - - - - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts about saving the owner. - - SwitchParameter - - SwitchParameter - - - - - - PassThru - - Returns the newly modified security descriptor object. By default, this function does not generate any output. - - SwitchParameter - - SwitchParameter - - - - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - SwitchParameter - - - - - - Confirm - - Prompts you for confirmation before making any changes. - - SwitchParameter - - SwitchParameter - - - - - - InputObject - - - - Object - - Object - - - - - - ObjectType - - When a security descriptor object isn't specified to Set-Owner, the function will call Get-SecurityDescriptor, which will attempt to determine the object type of the object specified in the Path, LiteralPath, or SDObject. Using this parameter allows you to specify a specific object type. Non-filesystem paths must be in a format that PowerShell doesn't natively understand. See the following link for path formatting information: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379593(v=vs.85).aspx - - ResourceType - - ResourceType - - - - - - IsContainer - - - - SwitchParameter - - SwitchParameter - - - - - - LiteralPath - - Specifies the path to a resource whose owner should be changed. - -Unlike Path, the value of the LiteralPath parameter is used exactly as it is -typed. No characters are interpreted as wildcards. If the path includes escape -characters, enclose it in single quotation marks. Single quotation marks tell -Windows PowerShell not to interpret any characters as escape sequences. - - String[] - - String[] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -------------- Example 1 -------------- - - - - PS C:\> Set-Owner -Path c:\folder -Principal $env:username - - This is an example of taking ownership of a folder. If an administrator were to run this command, it should always succeed (assuming the administrator can see the folder). If a regular user were to run the command, they would need FullControl rights over the folder. - -Since the function has been given a path, it will attempt to save the new owner immediately. Set-SecurityDescriptor will be called internally, and the user will be prompted about the change. - - - - - - - - - -------------- Example 2 -------------- - - - - PS C:\> dir C:\folder -Recurse | Set-Owner -Principal testuser -WhatIf - - This command will list all files and folders in the C:\folder folder, and attempt to assign the 'testuser' as the owner of all of the objects (or it would if the -WhatIf switch weren't supplied) - - - - - - - - - -------------- Example 3 -------------- - - - - PS C:\> Set-Owner -Path \\RemoteMachine\MACHINE\Software\Adobe -ObjectType RegistryWow6432Key -Principal testuser - - This set - - - - - - - - - - - Get-SecurityDescriptor - - - - Set-SecurityDescriptor - - - - Object Types - http://msdn.microsoft.com/en-us/library/windows/desktop/aa379593(v=vs.85).aspx - - - - - - - Set-SecurityDescriptor - - Changes the security descriptor of a specified object. - - - - - Set - SecurityDescriptor - - - - - The Set-SecurityDescriptor function changes the security descriptor of a specified object. For a list of objects that can be used, please see the help for 'Get-SecurityDescriptor' - -To use the function, use the -SDObject parameter to identify the object whose security descriptor will be changed, along with the new security descriptor. The -Sections parameter can optionally be used to control exactly which sections from the descriptor contained in SDObject to apply. - -Alternatively, the Path, LiteralPath, or InputObject parameters may be used to identify the object whose security descriptor will be changed (the security descriptor that will be applied will still come from the -SDObject parameter). - - - - Set-SecurityDescriptor - - SDObject - - Specifies a security descriptor object with the desired sections. Set-SecurityDescriptor changes the security descriptor of the object specified by the Path, LiteralPath, or InputObject parameter to match the sections in this security descriptor object. - - Object - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts about saving the security descriptor. - - SwitchParameter - - - Sections - - Specifies the security descriptor sections that should be written. - - AccessControlSections - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Prompts you for confirmation before making any changes. - - SwitchParameter - - - - Set-SecurityDescriptor - - SDObject - - Specifies a security descriptor object with the desired sections. Set-SecurityDescriptor changes the security descriptor of the object specified by the Path, LiteralPath, or InputObject parameter to match the sections in this security descriptor object. - - Object - - - InputObject - - The object whose security descriptor should be changed. - - Object - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts about saving the security descriptor. - - SwitchParameter - - - Sections - - Specifies the security descriptor sections that should be written. - - AccessControlSections - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Prompts you for confirmation before making any changes. - - SwitchParameter - - - - Set-SecurityDescriptor - - SDObject - - Specifies a security descriptor object with the desired sections. Set-SecurityDescriptor changes the security descriptor of the object specified by the Path, LiteralPath, or InputObject parameter to match the sections in this security descriptor object. - - Object - - - Path - - Specifies the path to an object whose security descriptor should be changed. Wildcards are permitted. - - String[] - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts about saving the security descriptor. - - SwitchParameter - - - Sections - - Specifies the security descriptor sections that should be written. - - AccessControlSections - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Prompts you for confirmation before making any changes. - - SwitchParameter - - - - Set-SecurityDescriptor - - SDObject - - Specifies a security descriptor object with the desired sections. Set-SecurityDescriptor changes the security descriptor of the object specified by the Path, LiteralPath, or InputObject parameter to match the sections in this security descriptor object. - - Object - - - LiteralPath - - Changes the security descriptor of the specified object. Unlike Path, the value of the LiteralPath parameter is used exactly as it is typed. No characters are interpreted as wildcards. If the path includes escape characters, enclose it in single quotation marks. Single quotation marks tell Windows PowerShell not to interpret any characters as escape sequences. - - String[] - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts about saving the security descriptor. - - SwitchParameter - - - Sections - - Specifies the security descriptor sections that should be written. - - AccessControlSections - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - - Confirm - - Prompts you for confirmation before making any changes. - - SwitchParameter - - - - - - SDObject - - Specifies a security descriptor object with the desired sections. Set-SecurityDescriptor changes the security descriptor of the object specified by the Path, LiteralPath, or InputObject parameter to match the sections in this security descriptor object. - - Object - - Object - - - - - - Force - - When the -Apply switch is used, this switch parameter suppresses any prompts about saving the security descriptor. - - SwitchParameter - - SwitchParameter - - - - - - Sections - - Specifies the security descriptor sections that should be written. - - AccessControlSections - - AccessControlSections - - - Access, Audit - - - WhatIf - - Shows what would happen if the function were to make changes. No changes are made. - - SwitchParameter - - SwitchParameter - - - - - - Confirm - - Prompts you for confirmation before making any changes. - - SwitchParameter - - SwitchParameter - - - - - - InputObject - - The object whose security descriptor should be changed. - - Object - - Object - - - - - - Path - - Specifies the path to an object whose security descriptor should be changed. Wildcards are permitted. - - String[] - - String[] - - - - - - LiteralPath - - Changes the security descriptor of the specified object. Unlike Path, the value of the LiteralPath parameter is used exactly as it is typed. No characters are interpreted as wildcards. If the path includes escape characters, enclose it in single quotation marks. Single quotation marks tell Windows PowerShell not to interpret any characters as escape sequences. - - String[] - - String[] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -------------- Example 1 -------------- - - - - PS C:\> Get-SecurityDescriptor C:\file1.txt | Set-SecurityDescriptor -Path C:\subfolder\file2.txt - - This will take the security descriptor from file1.txt and apply it to file2.txt. - -Note that if ACL inheritance is enabled on file1.txt, the final security descriptor might not match on the two files due to inherited permissions coming from each of the parent folders. - - - - - - - - - -------------- Example 2 -------------- - - - - PS C:\> Get-SecurityDescriptor C:\file1.txt | Set-SecurityDescriptor -Path C:\subfolder\file2.txt, C:\subfolder\file3.txt - - This does the same thing as example #1 except that the security descriptor is copied onto two files instead of just one. You can pass an array of paths or InputObjects go apply the security descriptor to multiple objects at the same time. - - - - - - - - - -------------- Example 3 -------------- - - - - PS C:\> Get-SecurityDescriptor C:\file1.txt | Disable-AclInheritance -PreserveExistingAces -Apply -PS C:\> Get-SecurityDescriptor C:\file1.txt | Set-SecurityDescriptor -Path C:\subfolder\file2.txt,C:\subfolder\file3.txt - - This is similar to example #1, except that file1.txt has inheritance turned off for the discretionary ACL first. When the security descriptor is applied to file2.txt (and file3.txt in this example), the SD is truly copied this time since there is no inheritance involved. - - - - - - - - - -------------- Example 4 -------------- - - - - PS C:\> Get-SecurityDescriptor C:\file1.txt -Audit | Set-SecurityDescriptor -Path C:\subfolder\file2.txt -Sections Audit - - This command gets the security descriptor for the file1.txt file (including the system ACL, which controls auditing), and saves only the system ACL to the file2.txt file. Using the -Sections parameter causes any sections not provided to be ignored by the Set-SecurityDescriptor function. The owner, group, and/or DACL could have been modified on the security descriptor that is being supplied to the function, but only the SACL will be saved to the file2.txt file. - - - - - - - - - -------------- Example 5 -------------- - - - - PS C:\> Get-Service bits | Get-SecurityDescriptor | Add-AccessControlEntry -Principal Users -ServiceAccessRights Start -PassThru | Set-SecurityDescriptor -WhatIf - - This long one-liner does the following: -1. Get a service object for the BITS service -2. Get the security descriptor for the BITS service -3. Add a discretionary (access) ACE that allows Users to start the service -4. Call Set-SecurityDescriptor with the -WhatIf parameter to show what would happen if the security descriptor were saved. - -NOTE: This command can be shortened. See the help for Add-AccessControlEntry to see how to shorten the command. - - - - - - - - - - - about_PowerShellAccessControl_Module - - - - Get-SecurityDescriptor - - - - Add-AccessControlEntry - - - - Remove-AccessControlEntry - - - - Enable-AclInheritance - - - - Disable-AclInheritance - - - - Set-Owner - - - - Unknown - - - - Get-Acl - - - - - \ No newline at end of file diff --git a/Resources/PowerShellAccessControl/en-US/about_PowerShellAccessControl_DscResources.help.txt b/Resources/PowerShellAccessControl/en-US/about_PowerShellAccessControl_DscResources.help.txt deleted file mode 100644 index 2abcde0..0000000 --- a/Resources/PowerShellAccessControl/en-US/about_PowerShellAccessControl_DscResources.help.txt +++ /dev/null @@ -1,127 +0,0 @@ -TOPIC - PowerShell Access Control DSC Resources - -SHORT DESCRIPTION - Overview of the DSC resources found in the PowerShell Access Control module - -LONG DESCRIPTION - NOTE: As of version 3.0 of the PowerShell Access Control module, the DSC - resources are still very much in a testing phase. Be aware that - future versions of the module may behave differently and/or have - different resources and parameters. The documentation in future - versions should reflect any changes, though. - - The PowerShell Access Control module contains three Desired State - Configuration (DSC) resources: - 1. cAccessControlEntry - 2. cSecurityDescriptor - 3. cSecurityDescriptorSddl - - All three resources are able to make modification to a securable object's - security descriptor (SD). They all share the following required parameters: - - Path: A string describing the location of the securable object. - Combined with ObjectType, this parameter helps to uniquely identify - the securable object. The path syntax for each object type is listed - below. - - ObjectType: A string describing the type of the securable object. For - now, the following types are supported: - - o File - The path points to a file object. The path should - be in the same format as a path to Get-Item or - Get-ChildItem, e.g., C:\Temp. - - o Directory - The path points to a directory object. The path - should be in the same format as a File object. - - o RegistryKey - The path points to a registry key. The format - should be in the same PS provider format as a - registry path to Get-Item or Get-ChildItem, e.g., - HKLM:\SOFTWARE. - - o Service - The path points to a service. The format of the - path is the service name, e.g., 'bits'. - - o WmiNamespace - The path points to a WMI namespace. The format - of the path is the same as the -Namespace used in - a call to Get-WmiObject or Get-CimInstance, e.g., - 'root/cimv2'. - - More information about each DSC resource can be found in the below - sections. - - -cAccessControlEntry -------------------- -This resource provides the ability to ensure specific access control entries (ACEs) are present or absent from a securable object. A few simple examples of what can be checked: -- Make sure that 'Users' have the ability to Stop and Stop the 'bits' service -- Make sure that 'Users' does not have the 'Delete' right over the 'C:\Temp' folder -- Make sure that 'Users' have a deny access ACE for the 'Delete' right over the 'C:\Temp' folder -- Make sure that 'Everyone' has all failed file accesses audited for the 'C:\Temp' folder - -It has the following inputs (required inputs have an asterisk before their name): -- *Path: See the beginning of the help topic for more information. -- *ObjectType: See the beginning of the help topic for more information. -- *AceType: Describes the type of the ACE that is tested/set. -- *Principal: The trustee (user, group, computer, etc) that is listed in the ACE. -- Ensure: Describes whether or not ACE should be present. Valid values are 'Present' or 'Absent'. Default is 'Present'. -- AccessMask (required if -Ensure is set to 'Present'): Describes the rights that are granted/denied/audited. This must be an int or a value that can be cast to an int, e.g., [FileSystemRights]::Delete would work, but not simply 'Delete'. If no -AccessMask is present when -Ensure is set to 'Absent', then the object will have no access for the -Principal. If -Ensure is set to 'Present' (or not provided), then an error will be generated (-AccessMask is required in that scenario). -- AppliesTo: A string value that is used to control where the ACE will apply. This is only useful for container objects (folders, registry keys, WMI namespaces, etc). Any of the following strings can be used: Object, ChildContainers, ChildObjects. Multiple values can be used as long as they are comma separated. If this string isn't provided, a default value is used for each type, e.g., folders will have a default of all three values, registry keys of "Object, ChildContainers", etc. -- OnlyApplyToThisContainer: A boolean value that specifies whether the ACE will only apply to the container it belongs to. The default is 'False'. -- Specific (Only valid when -Ensure is set to 'Absent'): A boolean value that controls whether or not an ACE must match exactly in order to fail the test/be removed from the object. This controls whether or not the -Specific switch is sent to Remove-AccessControlEntry. - - - - -cSecurityDescriptor -------------------- - - - - - -cSecurityDescriptorSddl ------------------------ -This resource provides the same functionality as cSecurityDescriptor, but it only has three inputs (all are required): -- *Path: See the beginning of the help topic for more information. -- *ObjectType: See the beginning of the help topic for more information. -- *Sddl: A string providing the parts of the SD to test/set. - -The SDDL string can provide any number of the following sections: Owner, Group, Discretionary ACL, System ACL. The SDDL string will also control whether or not an ACL is set to inherit entries from the parent object. - -The get a valid SDDL string, you can use a security descriptor object from the PowerShell Access Control module (from Get-SecurityDescriptor or New-AdaptedSecurityDescriptor). After getting a security descriptor object, you can use the security descriptor modification functions to make it look the way you'd like, then use the [SD Object].SecurityDescriptor.GetSddlForm() method to get the parts of the SDDL you're interested in: - -# Get security descriptor -PS> $SD = Get-SecurityDescriptor c:\windows -Audit - -# If this is how you'd like the SD to look, then start calling the GetSddlForm() -# If not, make changes to the $SD object (you don't have the save them). - -# Get full SDDL -PS> $SD.Sddl - -# Get owner only -PS> $SD.SecurityDescriptor.GetSddlForm("Owner") - -# Get Owner, DACL, and SACL -PS> $SD.SecurityDescriptor.GetSddlForm("Owner, Access, Audit") - -# Get full SDDL (alternate) -PS> $SD.SecurityDescriptor.GetSddlForm("Owner, Group, Access, Audit") -# or -PS> $SD.SecurityDescriptor.GetSddlForm("All") - -Like cSecurityDescriptor, the only parts of the target object's security descriptor that will be check/modified are the parts specified in the DSC node. So if you have an SDDL string that only contains an owner section, only the owner section of the target's SD will be tested/modified. - - - - -SEE ALSO - about_PowerShellAccessControl_DscResources - Add-AccessControlEntry - Disable-AclInheritance - Enable-AclInheritance - Get-AccessControlEntry - Get-SecurityDescriptor - New-AccessControlEntry - Remove-AccessControlEntry - Set-SecurityDescriptor diff --git a/Resources/PowerShellAccessControl/en-US/about_PowerShellAccessControl_Module.help.txt b/Resources/PowerShellAccessControl/en-US/about_PowerShellAccessControl_Module.help.txt deleted file mode 100644 index 00ee745..0000000 --- a/Resources/PowerShellAccessControl/en-US/about_PowerShellAccessControl_Module.help.txt +++ /dev/null @@ -1,165 +0,0 @@ -TOPIC - PowerShell Access Control Module - -SHORT DESCRIPTION - Module for managing security descriptors in PowerShell. - -LONG DESCRIPTION - The PowerShell Access Control Module is a module written for Windows - PowerShell version 2.0 and higher. It can be used as a supplement or - a full replacement to the native Get-Acl and Set-Acl cmdlets. - - -SUPPLEMENT TO NATIVE CMDLETS ----------------------------- - Modifying security descriptors for objects that Get-Acl supports generally - follows this pattern: - - 1. Call Get-Acl to get the security descriptor: - - PS> $Acl = Get-Acl C:\temp - - 2. View the Access and/or Audit properties to view currentl ACLs: - - PS> $Acl.Access - - 3. Use .NET object constructors to build an access control entry (the - object type varies depending on the object being secured: - - PS> $Ace = New-Object System.Security.AccessControl.FileSystemAccessRule ( - "Everyone", - "Modify", - "ContainerInherit, ObjectInherit", - "None", - "Allow" - ) - - 4. Use .NET methods on the security descriptor object to add/remove/modify - access control lists (either discretionary or system ACLs) with the ACE - created in step 2: - - PS> $Acl.AddAccessRule($Ace) - - 5. Call Set-Acl to commit the changes (or call SetAccessControl() .NET - method): - - PS> $Acl | Set-Acl - # or - PS> [System.IO.File]::SetAccessControl($Acl.Path, $Acl) - - - When used as a supplement to the native cmdlets, the PowerShell Access - Control module can be used to simplify or completely remove step 3 above. - Using the New-AccessControlEntry function, step #3 above can become the - following: - - PS> $Ace = New-AccessControlEntry -Principal Everyone -FolderRights Modify - - - See the help for the New-AccessControlEntry to see how to set other - properties of the ACE, such as the type and what it applies to. - - Instead of using the AddAccessRule() .NET method in step #4, the - Add-AccessConrolEntry can be used: - - PS> $Acl | Add-AccessControlEntry -AceObject $Ace - - - Instead of doing that, steps #3 and #4 can actually be combined: - - PS> $Acl | Add-AccessControlEnry -Principal Everyone -FolderRights Modify - - - That single line will take care of steps #3 and #4 above. See the help for - the Add-AccessControlEntry and Remove-AccessControlEntry for more - information about modifying access control lists. - - The Get-AccessControlEntry function can be used to replace step #2: - - PS> $Acl | Get-AccessControlEntry - - - See the help for that function to see other options, including how to - filter ACEs that are displayed. - - The module can also be used to change access and audit rule protection with - the Enable-AclInheritance and Disable-AclInheritance functions. - - -REPLACEMENT FOR NATIVE CMDLETS ------------------------------- - The PowerShell Access Control module has two functions that replace Get-Acl - and Set-Acl: Get-SecurityDescriptor and Set-SecurityDescriptor. Please see - the help sections for each function for more information about them. - - The Get/Modify/Set pattern mentioned above can still be used with the - module. Look at the following example, where the 'Everyone' group is given - modify rights over the 'c:\temp' folder (except it can't delete the folder - itself): - - PS> $SD = Get-SecurityDescriptor c:\temp - PS> $SD | Add-AccessControlEntry -Principal Everyone -FolderRights Modify - PS> $SD | Remove-AccessControlEntry -Principal Everyon -FolderRights Delete -AppliesTo Object - PS> $SD | Set-SecurityDescriptor - - - The first and last steps can actually be skipped, though. Each of the SD - modification functions will attempt to call Get-SecurityDescriptor on any - non-SD object, e.g., a path string, a service object, a printer object, an - AD object, etc. If a non-SD object is provided, the SD modification - functions will attempt to call Set-SecurityDescriptor (the function behaves - as if the -Apply switch was passed). If in the previous example we just - wanted to call the Add-AccessControlEntry function, the following would add - the ACE in one step: - - PS> Add-AccessControlentry -Path c:\temp -Principal Everyone -FolderRights Modify - - Note that you will be prompted before saving the security descriptor unless - the -Force switch is provided. Also, the following two commands will do the - same thing: - - PS> "c:\temp" | Add-AccessControlentry -Principal Everyone -FolderRights Modify - PS> Get-Item c:\temp | Add-AccessControlentry -Principal Everyone -FolderRights Modify - - - To make more than one change to the security descriptor, multiple functions - can be chained together by using the -PassThru switch. The -PassThru switch - makes the functions output the security descriptor (normally there is no - output). So the previous Get-SecurityDescriptor/Set-SecurityDescriptor - example could be taken care of with the following one-line command: - - PS> Get-Item c:\temp | - Add-AccessControlentry -Principal Everyone -FolderRights Modify -PassThru | - Remove-AccessControlEntry -Principal Everyon -FolderRights Delete -AppliesTo Object -Apply - - Note that the -Apply switch was provided to the last function call. Since - that function received a security descriptor as input, -Apply was not the - default action. - - For more information, please see the help topics for each of the security - descriptor modification functions. - - -DESIRED STATE CONFIGURATION ---------------------------- -Please see the about_PowerShellAccessControl_DscResources help topic. - - -SEE ALSO - about_PowerShellAccessControl_DscResources - Add-AccessControlEntry - ConvertTo-Win32SecurityDescriptor - Disable-AclInheritance - Enable-AclInheritance - Get-AccessControlEntry - Get-ADObjectAceGuid - Get-EffectiveAccess - Get-MandatoryIntegrityLabel - Get-SecurityDescriptor - Get-Win32SecurityDescriptor - New-AccessControlEntry - New-AdaptedSecurityDescriptor - Remove-AccessControlEntry - Repair-AclCanonicalOrder - Set-Owner - Set-SecurityDescriptor diff --git a/Resources/PowerShellAccessControl/examples/dsc/cAccessControlEntry.ps1 b/Resources/PowerShellAccessControl/examples/dsc/cAccessControlEntry.ps1 deleted file mode 100644 index f4aa132..0000000 --- a/Resources/PowerShellAccessControl/examples/dsc/cAccessControlEntry.ps1 +++ /dev/null @@ -1,72 +0,0 @@ -# Needed for ServiceAccessRights enumeration -Import-Module PowerShellAccessControl - -Configuration TestAceResource { - param( - [string[]] $ComputerName = "localhost" - ) - - Import-DscResource -Module PowerShellAccessControl - - $TestFolder = "C:\powershell\deleteme\dsc_test" - $TestKey = "HKLM:\SOFTWARE\Dsc_Test" - - Node $ComputerName { - - File TestFolder { - Ensure = "Present" - Type = "Directory" - DestinationPath = $TestFolder - } - - # Here's where resource provider to control modifying ACL protection would go - - cAccessControlEntry EveryoneModifyTestFolder { - Ensure = "Present" - Path = $TestFolder - AceType = "AccessAllowed" - ObjectType = "Directory" - AccessMask = ([System.Security.AccessControl.FileSystemRights]::Modify) - Principal = "Everyone" - DependsOn = "[File]TestFolder" - } - - cAccessControlEntry EveryoneAuditTestFolder { - Ensure = "Present" - Path = $TestFolder - AceType = "SystemAudit" - ObjectType = "Directory" - AccessMask = ([System.Security.AccessControl.FileSystemRights]::FullControl) - Principal = "Everyone" - AuditSuccess = $true - AuditFailure = $true - DependsOn = "[File]TestFolder" - } - - Registry TestKey { - Ensure = "Present" - Key = $TestKey - ValueName= "" - } - - cAccessControlEntry EveryoneFullControlTestKey { - Ensure = "Present" - Path = $TestKey - ObjectType = "RegistryKey" - AceType = "AccessAllowed" - AccessMask = ([System.Security.AccessControl.RegistryRights]::ReadPermissions) - Principal = "Everyone" - DependsOn = "[Registry]TestKey" - } - - - cAccessControlEntry UsersRestartBitsService { - Ensure = "Present" - Path = "bits" - ObjectType = "Service" - AceType = "AccessAllowed" - AccessMask = ([PowerShellAccessControl.ServiceAccessRights] "Start, Stop") - Principal = "Everyone" - } - } -} \ No newline at end of file diff --git a/Resources/PowerShellAccessControl/examples/dsc/cSecurityDescriptor.ps1 b/Resources/PowerShellAccessControl/examples/dsc/cSecurityDescriptor.ps1 deleted file mode 100644 index e63891b..0000000 --- a/Resources/PowerShellAccessControl/examples/dsc/cSecurityDescriptor.ps1 +++ /dev/null @@ -1,93 +0,0 @@ -# Needed for ServiceAccessRights enumeration -Import-Module PowerShellAccessControl - -Configuration TestSecurityDescriptorResource { - param( - [string[]] $ComputerName = "localhost" - ) - - Import-DscResource -Module PowerShellAccessControl - - $TestFolderOwner = "C:\powershell\deleteme\dsc_test_sd_owner" - $TestFolderSacl = "C:\powershell\deleteme\dsc_test_sd_sacl" - $TestFolderDacl = "C:\powershell\deleteme\dsc_test_sd_dacl" - $TestKey = "HKLM:\SOFTWARE\Dsc_Test_sd" - - Node $ComputerName { - - File TestFolderOwner { - Ensure = "Present" - Type = "Directory" - DestinationPath = $TestFolderOwner - } - - File TestFolderSacl { - Ensure = "Present" - Type = "Directory" - DestinationPath = $TestFolderSacl - } - - File TestFolderDacl { - Ensure = "Present" - Type = "Directory" - DestinationPath = $TestFolderDacl - } - - cSecurityDescriptor TestFolderSdOwner { # This sets the owner to Administrators - Path = $TestFolderOwner - ObjectType = "Directory" - Owner = "Administrators" - DependsOn = "[File]TestFolderOwner" - } - - cSecurityDescriptor TestFolderSdSacl { - Path = $TestFolderSacl - ObjectType = "Directory" - AuditInheritance = "Enabled" - Audit = @" - AceType,Principal,FolderRights,AuditSuccess,AuditFailure - SystemAudit,Everyone,FullControl,false,true - SystemAudit,Users,Delete,true,true -"@ - DependsOn = "[File]TestFolderSacl" - } - - cSecurityDescriptor TestFolderSdDacl { - Path = $TestFolderDacl - ObjectType = "Directory" - AccessInheritance = "Disabled" - Access = @" - AceType,Principal,FolderRights,AppliesTo,OnlyApplyToThisContainer - AccessAllowed,Administrators,FullControl - AccessAllowed,Users,Modify - AccessDenied,Users,Delete,Object - AccessDenied,Everyone,CreateDirectories,ChildContainers,true -"@ - DependsOn = "[File]TestFolderDacl" - } - - Registry TestKey { - Ensure = "Present" - Key = $TestKey - ValueName= "" - } - - cSecurityDescriptor TestKeyFullSd { - Path = $TestKey - ObjectType = "RegistryKey" - Owner = "Administrators" - Group = "Administrators" - Access = @" - Principal,RegistryRights - Administrators,FullControl - Users,ReadKey -"@ - Audit = @" - AceType,Principal,RegistryRights,AuditFailure - SystemAudit,Everyone,FullControl,true -"@ - DependsOn = "[Registry]TestKey" - } - - } -} \ No newline at end of file diff --git a/Resources/PowerShellAccessControl/examples/dsc/cSecurityDescriptorSddl.ps1 b/Resources/PowerShellAccessControl/examples/dsc/cSecurityDescriptorSddl.ps1 deleted file mode 100644 index ab77011..0000000 --- a/Resources/PowerShellAccessControl/examples/dsc/cSecurityDescriptorSddl.ps1 +++ /dev/null @@ -1,70 +0,0 @@ -# Needed for ServiceAccessRights enumeration -Import-Module PowerShellAccessControl - -Configuration TestSecurityDescriptorSddlResource { - param( - [string[]] $ComputerName = "localhost" - ) - - Import-DscResource -Module PowerShellAccessControl - - $TestFolderOwner = "C:\powershell\deleteme\dsc_test_sddl_owner" - $TestFolderSacl = "C:\powershell\deleteme\dsc_test_sddl_sacl" - $TestFolderDacl = "C:\powershell\deleteme\dsc_test_sddl_dacl" - $TestKey = "HKLM:\SOFTWARE\Dsc_Test_sddl" - - Node $ComputerName { - - File TestFolderOwner { - Ensure = "Present" - Type = "Directory" - DestinationPath = $TestFolderOwner - } - - File TestFolderSacl { - Ensure = "Present" - Type = "Directory" - DestinationPath = $TestFolderSacl - } - - File TestFolderDacl { - Ensure = "Present" - Type = "Directory" - DestinationPath = $TestFolderDacl - } - - cSecurityDescriptorSddl TestFolderSdOwner { # This sets the owner to Administrators - Path = $TestFolderOwner - ObjectType = "Directory" - Sddl = "O:BA" - DependsOn = "[File]TestFolderOwner" - } - - cSecurityDescriptorSddl TestFolderSdSacl { # Some auditing (2 not inherited; 1 inherited; only 2 non inherited should count) - Path = $TestFolderSacl - ObjectType = "Directory" - Sddl = "S:AI(AU;OICISAFA;FA;;;WD)(AU;OICISA;WD;;;SY)(AU;OICIIDSA;FA;;;WD)" - DependsOn = "[File]TestFolderSacl" - } - - cSecurityDescriptorSddl TestFolderSdDacl { # Protected DACL from Windows folder (so this should disable inheritance) - Path = $TestFolderDacl - ObjectType = "Directory" - Sddl = "D:PAI(A;OICIIO;GA;;;CO)(A;OICIIO;GA;;;SY)(A;;0x1301bf;;;SY)(A;OICIIO;GA;;;BA)(A;;0x1301bf;;;BA)(A;OICIIO;GXGR;;;BU)(A;;0x1200a9;;;BU)(A;CIIO;GA;;;S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464)(A;;FA;;;S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464)" - DependsOn = "[File]TestFolderDacl" - } - - Registry TestKey { - Ensure = "Present" - Key = $TestKey - ValueName= "" - } - - cSecurityDescriptorSddl TestKeyFullSd { # Instead of splitting the SD parts, use an SD with all parts - Path = $TestKey - ObjectType = "RegistryKey" - Sddl = "O:BAG:SYD:PAI(A;OICI;KR;;;RC)(A;OICI;KA;;;SY)(A;OICI;KA;;;BA)(A;CI;KA;;;BU)" - DependsOn = "[Registry]TestKey" - } - } -} \ No newline at end of file diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_CertificateStore/StackExchange_CertificateStore.psd1 b/Resources/StackExchangeResources/DSCResources/StackExchange_CertificateStore/StackExchange_CertificateStore.psd1 deleted file mode 100644 index eaa673c..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_CertificateStore/StackExchange_CertificateStore.psd1 +++ /dev/null @@ -1,98 +0,0 @@ -# -# Module manifest for module 'CertificateStore' -# -# Generated by: Steven Murawski -# -# Generated on: 12/30/2013 -# - -@{ - -# Script module or binary module file associated with this manifest. -RootModule = 'StackExchange_CertificateStore.psm1' - -# Version number of this module. -ModuleVersion = '1.0' - -# ID used to uniquely identify this module -GUID = '6e7cd6d9-c42b-4810-98a7-c78a2b8dddd9' - -# Author of this module -Author = 'Steven Murawski' - -# Company or vendor of this module -CompanyName = 'Stack Exchange' - -# Copyright statement for this module -Copyright = '(c) 2013 Steven Murawski. All rights reserved.' - -# Description of the functionality provided by this module -# Description = '' - -# Minimum version of the Windows PowerShell engine required by this module -# PowerShellVersion = '' - -# Name of the Windows PowerShell host required by this module -# PowerShellHostName = '' - -# Minimum version of the Windows PowerShell host required by this module -# PowerShellHostVersion = '' - -# Minimum version of Microsoft .NET Framework required by this module -# DotNetFrameworkVersion = '' - -# Minimum version of the common language runtime (CLR) required by this module -# CLRVersion = '' - -# Processor architecture (None, X86, Amd64) required by this module -# ProcessorArchitecture = '' - -# Modules that must be imported into the global environment prior to importing this module -# RequiredModules = @() - -# Assemblies that must be loaded prior to importing this module -# RequiredAssemblies = @() - -# Script files (.ps1) that are run in the caller's environment prior to importing this module. -# ScriptsToProcess = @() - -# Type files (.ps1xml) to be loaded when importing this module -# TypesToProcess = @() - -# Format files (.ps1xml) to be loaded when importing this module -# FormatsToProcess = @() - -# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess -# NestedModules = @() - -# Functions to export from this module -FunctionsToExport = 'Get-TargetResource', 'Set-TargetResource', 'Test-TargetResource' - -# Cmdlets to export from this module -CmdletsToExport = '*' - -# Variables to export from this module -VariablesToExport = '*' - -# Aliases to export from this module -AliasesToExport = '*' - -# List of all modules packaged with this module -# ModuleList = @() - -# List of all files packaged with this module -# FileList = @() - -# Private data to pass to the module specified in RootModule/ModuleToProcess -# PrivateData = '' - -# HelpInfo URI of this module -# HelpInfoURI = '' - -# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. -# DefaultCommandPrefix = '' - -} - - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_CertificateStore/StackExchange_CertificateStore.psm1 b/Resources/StackExchangeResources/DSCResources/StackExchange_CertificateStore/StackExchange_CertificateStore.psm1 deleted file mode 100644 index c77a39e..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_CertificateStore/StackExchange_CertificateStore.psm1 +++ /dev/null @@ -1,151 +0,0 @@ - - -function Get-TargetResource -{ - [OutputType([Hashtable])] - param ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $Name, - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $Path, - [parameter()] - [ValidateSet('LocalMachine','CurrentUser')] - [string] - $Location = 'LocalMachine', - [parameter()] - [string] - $Store = 'My', - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - - #Needs to return a hashtable that returns the current - #status of the configuration component - $Ensure = 'Present' - - if (Test-TargetResource @PSBoundParameters) - { - $Ensure = 'Present' - } - else - { - $Ensure = 'Absent' - } - - $Configuration = @{ - Name = $Name - Path = $Path - Location = $Location - Store = $Store - Ensure = $Ensure - } - - return $Configuration -} - -function Set-TargetResource -{ - param ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $Name, - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $Path, - [parameter()] - [ValidateSet('LocalMachine','CurrentUser')] - [string] - $Location = 'LocalMachine', - [parameter()] - [string] - $Store = 'My', - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - - $CertificateBaseLocation = "cert:\$Location\$Store" - - if ($Ensure -like 'Present') - { - Write-Verbose "Adding $path to $CertificateBaseLocation." - Import-PfxCertificate -CertStoreLocation $CertificateBaseLocation -FilePath $Path - } - else - { - $CertificateLocation = Join-path $CertificateBaseLocation $Name - Write-Verbose "Removing $CertificateLocation." - dir $CertificateLocation | Remove-Item -Force -Confirm:$false - } -} - -function Test-TargetResource -{ - [OutputType([boolean])] - param ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $Name, - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $Path, - [parameter()] - [ValidateSet('LocalMachine','CurrentUser')] - [string] - $Location = 'LocalMachine', - [parameter()] - [string] - $Store = 'My', - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - - $IsValid = $false - - $CertificateLocation = "cert:\$Location\$Store\$Name" - - if ($Ensure -like 'Present') - { - Write-Verbose "Checking for $Name to be present in the $location store under $store." - if (Test-Path $CertificateLocation) - { - Write-Verbose "Found a matching certficate at $CertificateLocation" - $IsValid = $true - } - else - { - Write-Verbose "Unable to find a matching certficate at $CertificateLocation" - } - } - else - { - Write-Verbose "Checking for $Name to be absent in the $location store under $store." - if (Test-Path $CertificateLocation) - { - Write-Verbose "Found a matching certficate at $CertificateLocation" - } - else - { - Write-Verbose "Unable to find a matching certficate at $CertificateLocation" - $IsValid = $true - } - } - - #Needs to return a boolean - return $IsValid -} - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_CertificateStore/StackExchange_CertificateStore.schema.mof b/Resources/StackExchangeResources/DSCResources/StackExchange_CertificateStore/StackExchange_CertificateStore.schema.mof deleted file mode 100644 index e32f64f..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_CertificateStore/StackExchange_CertificateStore.schema.mof +++ /dev/null @@ -1,11 +0,0 @@ -[ClassVersion("1.0"), FriendlyName("CertificateStore")] -class StackExchange_CertificateStore : OMI_BaseResource -{ -[Key] string Name; -[Key] string Path; -[write,ValueMap{"LocalMachine", "CurrentUser"},Values{"LocalMachine", "CurrentUser"}] string Location; -[write] string Store; -[write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; -}; - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_FirewallRule/StackExchange_FirewallRule.psd1 b/Resources/StackExchangeResources/DSCResources/StackExchange_FirewallRule/StackExchange_FirewallRule.psd1 deleted file mode 100644 index e5779cb..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_FirewallRule/StackExchange_FirewallRule.psd1 +++ /dev/null @@ -1,98 +0,0 @@ -# -# Module manifest for module 'FirewallRule' -# -# Generated by: Steven Murawski -# -# Generated on: 12/13/2013 -# - -@{ - -# Script module or binary module file associated with this manifest. -RootModule = 'StackExchange_FirewallRule.psm1' - -# Version number of this module. -ModuleVersion = '1.7' - -# ID used to uniquely identify this module -GUID = '8f3ea446-27ee-4416-85c3-a6590ca05f03' - -# Author of this module -Author = 'Steven Murawski' - -# Company or vendor of this module -CompanyName = 'Stack Exchange' - -# Copyright statement for this module -Copyright = '(c) 2013 Steven Murawski. All rights reserved.' - -# Description of the functionality provided by this module -# Description = '' - -# Minimum version of the Windows PowerShell engine required by this module -# PowerShellVersion = '' - -# Name of the Windows PowerShell host required by this module -# PowerShellHostName = '' - -# Minimum version of the Windows PowerShell host required by this module -# PowerShellHostVersion = '' - -# Minimum version of Microsoft .NET Framework required by this module -# DotNetFrameworkVersion = '' - -# Minimum version of the common language runtime (CLR) required by this module -# CLRVersion = '' - -# Processor architecture (None, X86, Amd64) required by this module -# ProcessorArchitecture = '' - -# Modules that must be imported into the global environment prior to importing this module -# RequiredModules = @() - -# Assemblies that must be loaded prior to importing this module -# RequiredAssemblies = @() - -# Script files (.ps1) that are run in the caller's environment prior to importing this module. -# ScriptsToProcess = @() - -# Type files (.ps1xml) to be loaded when importing this module -# TypesToProcess = @() - -# Format files (.ps1xml) to be loaded when importing this module -# FormatsToProcess = @() - -# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess -# NestedModules = @() - -# Functions to export from this module -FunctionsToExport = 'Get-TargetResource', 'Test-TargetResource', 'Set-TargetResource' - -# Cmdlets to export from this module -CmdletsToExport = '*' - -# Variables to export from this module -VariablesToExport = '*' - -# Aliases to export from this module -AliasesToExport = '*' - -# List of all modules packaged with this module -# ModuleList = @() - -# List of all files packaged with this module -# FileList = @() - -# Private data to pass to the module specified in RootModule/ModuleToProcess -# PrivateData = '' - -# HelpInfo URI of this module -# HelpInfoURI = '' - -# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. -# DefaultCommandPrefix = '' - -} - - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_FirewallRule/StackExchange_FirewallRule.psm1 b/Resources/StackExchangeResources/DSCResources/StackExchange_FirewallRule/StackExchange_FirewallRule.psm1 deleted file mode 100644 index f76bbb0..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_FirewallRule/StackExchange_FirewallRule.psm1 +++ /dev/null @@ -1,385 +0,0 @@ -function Get-TargetResource -{ - [OutputType([Hashtable])] - param ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [Alias('Name')] - [string] - $DisplayName, - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present', - [parameter()] - [ValidateSet('Allow','Block')] - [string] - $Action, - [parameter()] - [string] - $Description, - [parameter()] - [ValidateSet('Inbound','Outbound')] - [string] - $Direction, - [parameter()] - [ValidateSet('Any','ProximityApps', 'ProximitySharing')] - [string] - $DynamicTransport, - [parameter()] - [ValidateSet('Block', 'Allow', 'DeferToUser','DeferToApp')] - [string] - $EdgeTraversalPolicy, - [parameter()] - [ValidateSet('True','False')] - [string] - $Enabled, - [parameter()] - [ValidateSet('NotRequired','Required','Dynamic')] - [string] - $Encryption, - [parameter()] - [string[]] - $IcmpType, - [parameter()] - [string[]] - $InterfaceAlias, - [parameter()] - [ValidateSet('Any','Wired','Wireless', 'RemoteAccess')] - [string] - $InterfaceType, - [parameter()] - [string[]] - $LocalAddress, - [parameter()] - [string[]] - $LocalPort, - [parameter()] - [string] - $LocalUser, - [parameter()] - [ValidateSet('Any', 'Domain','Private','Public', 'NotApplicable')] - [string] - $Profile, - [parameter()] - [string] - $Program, - [parameter()] - [string] - $Protocol, - [parameter()] - [string[]] - $RemoteAddress, - [parameter()] - [string] - $RemoteMachine, - [parameter()] - [string] - $RemoteUser, - [parameter()] - [string] - $Service - ) - - #Needs to return a hashtable that returns the current - #status of the configuration component - $Configuration = @{ - DisplayName = $DisplayName - } - - $Rule = Get-NetFirewallRule -DisplayName $DisplayName -ErrorAction SilentlyContinue | - ForEach-Object { - New-Object PSObject -Property @{ - SourceRule = $_ - AddressFilter = $_ | Get-NetFirewallAddressFilter - ApplicationFilter = $_ | Get-NetFirewallApplicationFilter - InterfaceFilter = $_ | Get-NetFirewallInterfaceFilter - InterfaceTypeFilter = $_ | Get-NetFirewallInterfaceTypeFilter - PortFilter = $_ | Get-NetFirewallPortFilter - SecurityFilter = $_ | Get-NetFirewallSecurityFilter - ServiceFilter = $_ | Get-NetFirewallServiceFilter - } - } - - if ($Rule) - { - $Configuration.Ensure = 'Present' - - } - else - { - $Configuration.Ensure = 'Absent' - } - throw "To do yet" - return $Configuration -} - -function Set-TargetResource -{ - param ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [Alias('Name')] - [string] - $DisplayName, - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present', - [parameter()] - [ValidateSet('Allow','Block')] - [string] - $Action, - [parameter()] - [string] - $Description, - [parameter()] - [ValidateSet('Inbound','Outbound')] - [string] - $Direction, - [parameter()] - [ValidateSet('Any','ProximityApps', 'ProximitySharing')] - [string] - $DynamicTransport, - [parameter()] - [ValidateSet('Block', 'Allow', 'DeferToUser','DeferToApp')] - [string] - $EdgeTraversalPolicy, - [parameter()] - [ValidateSet('True','False')] - [string] - $Enabled, - [parameter()] - [ValidateSet('NotRequired','Required','Dynamic')] - [string] - $Encryption, - [parameter()] - [string[]] - $IcmpType, - [parameter()] - [string[]] - $InterfaceAlias, - [parameter()] - [ValidateSet('Any','Wired','Wireless', 'RemoteAccess')] - [string] - $InterfaceType, - [parameter()] - [string[]] - $LocalAddress, - [parameter()] - [string[]] - $LocalPort, - [parameter()] - [string] - $LocalUser, - [parameter()] - [ValidateSet('Any', 'Domain','Private','Public', 'NotApplicable')] - [string] - $Profile, - [parameter()] - [string] - $Program, - [parameter()] - [string] - $Protocol, - [parameter()] - [string[]] - $RemoteAddress, - [parameter()] - [string] - $RemoteMachine, - [parameter()] - [string] - $RemoteUser, - [parameter()] - [string] - $Service - ) - - if ($PSBoundParameters.ContainsKey('Debug')) - { - $PSBoundParameters.Remove('Debug') - } - if ($PSBoundParameters.ContainsKey('Ensure')) - { - $PSBoundParameters.Remove('Ensure') | Out-Null - } - - if ($Ensure -like 'Present') - { - Write-Verbose "Checking for an existing rule $DisplayName." - $Rule = Get-NetFirewallRule -DisplayName $DisplayName -ErrorAction SilentlyContinue - if ($rule) - { - Set-NetFirewallRule @PSBoundParameters - } - else - { - New-NetFirewallRule @PSBoundParameters - } - } - else - { - Remove-NetFirewallRule -DisplayName $DisplayName -Confirm:$false - } - -} - -function Test-TargetResource -{ - [OutputType([Boolean])] - param ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [Alias('Name')] - [string] - $DisplayName, - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present', - [parameter()] - [ValidateSet('Allow','Block')] - [string] - $Action = 'Allow', - [parameter()] - [string] - $Description = '', - [parameter()] - [ValidateSet('Inbound','Outbound')] - [string] - $Direction = 'Inbound', - [parameter()] - [ValidateSet('Any','ProximityApps', 'ProximitySharing')] - [string] - $DynamicTransport, - [parameter()] - [ValidateSet('Block', 'Allow', 'DeferToUser','DeferToApp')] - [string] - $EdgeTraversalPolicy = 'Block', - [parameter()] - [ValidateSet('True','False')] - [string] - $Enabled = 'True', - [parameter()] - [ValidateSet('NotRequired','Required','Dynamic')] - [string] - $Encryption = 'NotRequired', - [parameter()] - [string[]] - $IcmpType = 'Any', - [parameter()] - [string[]] - $InterfaceAlias, - [parameter()] - [ValidateSet('Any','Wired','Wireless', 'RemoteAccess')] - [string] - $InterfaceType, - [parameter()] - [string[]] - $LocalAddress, - [parameter()] - [string[]] - $LocalPort, - [parameter()] - [string] - $LocalUser, - [parameter()] - [ValidateSet('Any', 'Domain','Private','Public', 'NotApplicable')] - [string] - $Profile, - [parameter()] - [string] - $Program, - [parameter()] - [string] - $Protocol, - [parameter()] - [string[]] - $RemoteAddress, - [parameter()] - [string] - $RemoteMachine, - [parameter()] - [string] - $RemoteUser, - [parameter()] - [string] - $Service - ) - $Rule = Get-NetFirewallRule -DisplayName $DisplayName -ErrorAction SilentlyContinue | - ForEach-Object { - New-Object PSObject -Property @{ - SourceRule = $_ - AddressFilter = $_ | Get-NetFirewallAddressFilter - ApplicationFilter = $_ | Get-NetFirewallApplicationFilter - InterfaceFilter = $_ | Get-NetFirewallInterfaceFilter - InterfaceTypeFilter = $_ | Get-NetFirewallInterfaceTypeFilter - PortFilter = $_ | Get-NetFirewallPortFilter - SecurityFilter = $_ | Get-NetFirewallSecurityFilter - ServiceFilter = $_ | Get-NetFirewallServiceFilter - } - } - - $ConfigMatches = $true - if ($Ensure -like 'Present') - { - if ($Rule) - { - $ConfigMatches = $ConfigMatches -and ($Rule.SourceRule.Action -like $Action) - $ConfigMatches = $ConfigMatches -and ($Rule.SourceRule.Description -like $Description) - $ConfigMatches = $ConfigMatches -and ($Rule.SourceRule.Direction -like $Direction) - $ConfigMatches = $ConfigMatches -and ($Rule.SourceRule.EdgeTraversalPolicy -like $EdgeTraversalPolicy) - $ConfigMatches = $ConfigMatches -and ($Rule.SourceRule.Enabled -like $Enabled) - - if ($DynamicTransport) - { - $ConfigMatches = $ConfigMatches -and ($Rule.SourceRule.DynamicTransport -like $DynamicTransport) - } - if ($LocalPort) - { - $ConfigMatches = $ConfigMatches -and ($Rule.PortFilter.LocalPort -like $LocalPort) - $ConfigMatches = $ConfigMatches -and ($Rule.PortFilter.Protocol -like $Protocol) - } - if ($LocalAddress) - { - $ConfigMatches = $ConfigMatches -and ($Rule.AddressFilter.LocalAddress -like $LocalAddress) - } - if ($RemoteAddress) - { - $ConfigMatches = $ConfigMatches -and ($Rule.AddressFilter.RemoteAddress -like $RemoteAddress) - } - if ($Program) - { - $ConfigMatches = $ConfigMatches -and ($Rule.ApplicationFilter.Program -like $Program) - } - - if ($ConfigMatches) - { - Write-Verbose "$DisplayName is present and valid." - } - else - { - Write-Verbose "$DisplayName is not present or not valid." - } - } - else - { - Write-Verbose "$DisplayName is not present or not valid." - $ConfigMatches = $false - } - } - else - { - if ($rule) - { - Write-Verbose "$DisplayName is present and not valid." - $ConfigMatches = $false - } - Write-Verbose "$DisplayName is not present and valid." - } - - return $ConfigMatches -} - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_FirewallRule/StackExchange_FirewallRule.schema.mof b/Resources/StackExchangeResources/DSCResources/StackExchange_FirewallRule/StackExchange_FirewallRule.schema.mof deleted file mode 100644 index b11e707..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_FirewallRule/StackExchange_FirewallRule.schema.mof +++ /dev/null @@ -1,28 +0,0 @@ -[ClassVersion("1.0.0"), FriendlyName("FirewallRule")] -class StackExchange_FirewallRule : OMI_BaseResource -{ - [Key] string DisplayName; - [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; - [write,ValueMap{"Allow", "Block"},Values{"Allow", "Block"}] string Action; - [write] string Description; - [write,ValueMap{"Inbound", "Outbound"},Values{"Inbound", "Outbound"}] string Direction; - [write,ValueMap{"Any", "ProximityApps", "ProximitySharing"},Values{"Any", "ProximityApps", "ProximitySharing"}] string DynamicTransport; - [write,ValueMap{"Block", "Allow", "DeferToUser", "DeferToApp"},Values{"Block", "Allow", "DeferToUser", "DeferToApp"}] string EdgeTraversalPolicy; - [write,ValueMap{"True", "False"},Values{"True", "False"}] string Enabled; - [write,ValueMap{"NotRequired", "Required", "Dynamic"},Values{"NotRequired", "Required", "Dynamic"}] string Encryption; - [write] string IcmpType[]; - [write] string InterfaceAlias[]; - [write,ValueMap{"Any", "Wired", "Wireless", "RemoteAccess"},Values{"Any", "Wired", "Wireless", "RemoteAccess"}] string InterfaceType; - [write] string LocalAddress[]; - [write] string LocalPort[]; - [write] string LocalUser; - [write,ValueMap{"Any", "Domain", "Private", "Public", "NotApplicable"},Values{"Any", "Domain", "Private", "Public", "NotApplicable"}] string Profile; - [write] string Program; - [write] string Protocol; - [write] string RemoteAddress[]; - [write] string RemoteMachine; - [write] string RemoteUser; - [write] string Service; -}; - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_NetworkAdapter/StackExchange_NetworkAdapter.Tests.ps1 b/Resources/StackExchangeResources/DSCResources/StackExchange_NetworkAdapter/StackExchange_NetworkAdapter.Tests.ps1 deleted file mode 100644 index 7ccec4f..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_NetworkAdapter/StackExchange_NetworkAdapter.Tests.ps1 +++ /dev/null @@ -1,455 +0,0 @@ -$here = Split-Path -Parent $MyInvocation.MyCommand.Path -$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.ps1", ".psm1") -$pathtosut = join-path $here $sut - -iex ( gc $pathtosut -Raw ) - -#region Set-TargetResource -Describe 'how Set-TargetResource with Ensure = Absent responds' { - $TargetResourceParams = @{ - Name = 'MyAdapter' - Description = 'MyDescribedAdapter' - Ensure = 'Absent' - } - - Context 'when network adapter is named correctly and not in a team. ' { - Mock -verifiable -commandName Test-NetAdapterName -mockWith {$true} - Mock -verifiable -commandName Rename-NetAdapterWithWait -mockWith {} - Mock -verifiable -commandName Remove-MismatchedNetLbfoTeamMember -mockWith {} - Mock -verifiable -commandName Get-NetAdapter -mockWith { - return ([pscustomobject]@{Name = 'MyAdapter'}) - } - - $result = Set-TargetResource @TargetResourceParams - - It 'should call Test-NetAdapterName' { - Assert-MockCalled -commandName Test-NetAdapterName -times 1 -Exactly - } - It 'should call Rename-NetAdapterWithWait once, to rename to a temporary name' { - Assert-MockCalled -commandName Rename-NetAdapterWithWait -times 1 -Exactly -parameterFilter { - ($NewName -like 'Temp-*') -and ($Name -like $TargetResourceParams['Name']) - } - Assert-MockCalled -commandName Rename-NetAdapterWithWait -times 0 -Exactly -parameterFilter { - $NewName -like $TargetResourceParams['Name'] - } - } - It 'should call Remove-MismatchedNetLbfoTeamMember once, with MyAdapter as the name' { - Assert-MockCalled -commandName Remove-MismatchedNetLbfoTeamMember -times 1 -Exactly -parameterFilter { - $Name -like 'MyAdapter' - } - } - } - Context 'when network adapter is not named correctly and the name is not in use and it is not in a team. ' { - Mock -verifiable -commandName Test-NetAdapterName -mockWith {$false} - Mock -verifiable -commandName Rename-NetAdapterWithWait -mockWith {} - Mock -verifiable -commandName Remove-MismatchedNetLbfoTeamMember -mockWith {} - Mock -verifiable -commandName Get-NetAdapter -mockWith { - return ([pscustomobject]@{Name = 'SomeOtherName'}) - } - - $result = Set-TargetResource @TargetResourceParams - - It 'should call Test-NetAdapterName' { - Assert-MockCalled -commandName Test-NetAdapterName -times 1 -Exactly - } - It 'should not call Rename-NetAdapterWithWait' { - Assert-MockCalled -commandName Rename-NetAdapterWithWait -times 0 -Exactly - } - It 'should call Remove-MismatchedNetLbfoTeamMember once, with SomeOtherName as the name' { - Assert-MockCalled -commandName Remove-MismatchedNetLbfoTeamMember -times 1 -Exactly -parameterFilter { - $Name -like 'SomeOtherName' - } - } - } -} -Describe 'how Set-TargetResource with Ensure = Present responds' { - $TargetResourceParams = @{ - Name = 'MyAdapter' - Description = 'MyDescribedAdapter' - Ensure = 'Present' - } - - Context 'when network adapter is named correctly and not in a team. ' { - Mock -verifiable -commandName Test-NetAdapterName -mockWith {$true} - Mock -verifiable -commandName Rename-NetAdapterWithWait -mockWith {} - - $result = Set-TargetResource @TargetResourceParams - - It 'should call Test-NetAdapterName' { - Assert-MockCalled -commandName Test-NetAdapterName -times 1 -Exactly - } - It 'should not call Rename-NetAdapterWithWait' { - Assert-MockCalled -commandName Rename-NetAdapterWithWait -times 0 -Exactly - } - } - Context 'when network adapter is not named correctly and the name is not in use and it is not in a team. ' { - Mock -verifiable -commandName Test-NetAdapterName -mockWith {$false} - Mock -verifiable -commandName Rename-NetAdapterWithWait -mockWith {} - Mock -verifiable -commandName Get-NetAdapter -mockWith { - return ([pscustomobject]@{Name = 'SomeOtherName'}) - } - - $result = Set-TargetResource @TargetResourceParams - - It 'should call Test-NetAdapterName' { - Assert-MockCalled -commandName Test-NetAdapterName -times 1 -Exactly - } - It 'should call Rename-NetAdapterWithWait once for the desired name' { - Assert-MockCalled -commandName Rename-NetAdapterWithWait -times 1 -Exactly -parameterFilter { - $NewName -like $TargetResourceParams['Name'] - } - } - } - Context 'when network adapter is named correctly and it is not in a team. ' { - Mock -verifiable -commandName Test-NetAdapterName -mockWith {$true} - Mock -verifiable -commandName Test-NetAdapterTeamMembership -mockWith {$true} - Mock -verifiable -commandName Remove-MismatchedNetLbfoTeamMember -mockWith {} - Mock -verifiable -commandName New-NetLbfoTeamMember -mockWith {} - - $result = Set-TargetResource @TargetResourceParams - - It 'should call Test-NetAdapterName and Test-NetAdapterTeamMembership' { - Assert-MockCalled -commandName Test-NetAdapterName -times 1 -Exactly - Assert-MockCalled -commandName Test-NetAdapterTeamMembership -times 1 -Exactly - } - It 'should not call Clear-MismatchedNetLbfoTeamMember and New-NetLbfoTeamMember' { - Assert-MockCalled -commandName Remove-MismatchedNetLbfoTeamMember -times 0 -Exactly - Assert-MockCalled -commandName New-NetLbfoTeamMember -times 0 -Exactly - } - } - Context 'when network adapter is named correctly and is added to a team. ' { - Mock -verifiable -commandName Test-NetAdapterName -mockWith {$true} - Mock -verifiable -commandName Test-NetAdapterTeamMembership -mockWith {$false} - Mock -verifiable -commandName Remove-MismatchedNetLbfoTeamMember -mockWith {} - Mock -verifiable -commandName New-NetLbfoTeamMember -mockWith {} - - $result = Set-TargetResource @TargetResourceParams - - It 'should call Test-NetAdapterName and Test-NetAdapterTeamMembership' { - Assert-MockCalled -commandName Test-NetAdapterName -times 1 -Exactly - Assert-MockCalled -commandName Test-NetAdapterTeamMembership -times 1 -Exactly - } - It 'should call Clear-MismatchedNetLbfoTeamMember and New-NetLbfoTeamMember once each' { - Assert-MockCalled -commandName Remove-MismatchedNetLbfoTeamMember -times 1 -Exactly - Assert-MockCalled -commandName New-NetLbfoTeamMember -times 1 -Exactly - } - } -} -#endregion - -#region Test-TargetResource -Describe 'how Test-TargetResource responds with Ensure = Present' { - $TargetResourceParams = @{ - Name = 'MyAdapter' - Description = 'MyDescribedAdapter' - Ensure = 'Present' - } - Context 'when adapter is exists and is named correctly ' { - Mock -verifiable -commandName Test-NetAdapterExists -mockWith {return $true} - Mock -verifiable -commandName Test-NetAdapterName -mockWith {return $true} - Mock -verifiable -commandName Test-NetAdapterTeamMembership -mockWith {return $true} - - $result = Test-TargetResource @TargetResourceParams - - It "should call all the mocks" { - Assert-VerifiableMocks - } - It 'should return true' { - $result | should be ($true) - } - } - Context 'when adapter is exists and is not named correctly ' { - Mock -verifiable -commandName Test-NetAdapterExists -mockWith {return $true} - Mock -verifiable -commandName Test-NetAdapterName -mockWith {return $false} - Mock -verifiable -commandName Test-NetAdapterTeamMembership -mockWith {return $true} - - $result = Test-TargetResource @TargetResourceParams - - It "should call all the mocks" { - Assert-VerifiableMocks - } - It 'should return false' { - $result | should be ($false) - } - } - Context 'when adapter is does not exist ' { - Mock -verifiable -commandName Test-NetAdapterExists -mockWith {throw 'No Adapter'} - Mock -commandName Test-NetAdapterName -mockWith {return $false} - Mock -commandName Test-NetAdapterTeamMembership -mockWith {return $true} - - $result = $false - try - { - Test-TargetResource @TargetResourceParams - } - catch - { - $result = $true - } - - It "should call all the mocks" { - Assert-VerifiableMocks - } - It 'should return throw an error' { - $result | should be ($true) - } - } - Context 'when adapter is exists, is named correctly, and not in a team ' { - Mock -verifiable -commandName Test-NetAdapterExists -mockWith {return $true} - Mock -verifiable -commandName Test-NetAdapterName -mockWith {return $false} - Mock -verifiable -commandName Test-NetAdapterTeamMembership -mockWith {return $true} - - $result = Test-TargetResource @TargetResourceParams - - It "should call all the mocks" { - Assert-VerifiableMocks - } - It 'should return false' { - $result | should be ($false) - } - } -} - -Describe 'how Test-TargetResource responds with Ensure = Absent' { - $TargetResourceParams = @{ - Name = 'MyAdapter' - Description = 'MyDescribedAdapter' - Ensure = 'Absent' - } - Context 'when adapter is exists and is named correctly ' { - Mock -verifiable -commandName Test-NetAdapterExists -mockWith {return $true} - Mock -verifiable -commandName Test-NetAdapterName -mockWith {return $true} - Mock -verifiable -commandName Test-NetAdapterTeamMembership -mockWith {return $true} - - $result = Test-TargetResource @TargetResourceParams - - It "should call all the mocks" { - Assert-VerifiableMocks - } - It 'should return false' { - $result | should be ($false) - } - } - Context 'when adapter is exists and is not named correctly ' { - Mock -verifiable -commandName Test-NetAdapterExists -mockWith {return $true} - Mock -verifiable -commandName Test-NetAdapterName -mockWith {return $false} - Mock -verifiable -commandName Test-NetAdapterTeamMembership -mockWith {return $true} - - $result = Test-TargetResource @TargetResourceParams - - It "should call all the mocks" { - Assert-VerifiableMocks - } - It 'should return true' { - $result | should be ($true) - } - } - Context 'when adapter is does not exist ' { - Mock -verifiable -commandName Test-NetAdapterExists -mockWith {throw 'No Adapter'} - Mock -commandName Test-NetAdapterName -mockWith {return $false} - Mock -commandName Test-NetAdapterTeamMembership -mockWith {return $true} - - $result = $false - try - { - Test-TargetResource @TargetResourceParams - } - catch - { - $result = $true - } - - It "should call all the mocks" { - Assert-VerifiableMocks - } - It 'should thow an error' { - $result | should be ($true) - } - } -} - -#endregion - -#region Test-NetAdapterName -Describe 'how Test-NetAdapterName responds' { - Context 'when adapter is in named correctly' { - Mock -verifiable -commandName Get-NetAdapter -mockWith { - return ([pscustomobject]@{InterfaceDescription = 'MyAdapter'}) - } - - $result = Test-NetAdapterName -Name 'Adapter' -Description 'MyAdapter' - - It "should call all the mocks" { - Assert-VerifiableMocks - } - It 'should return true' { - $result | should be ($true) - } - } - - Context 'when wrong adapter has the name' { - Mock -verifiable -commandName Get-NetAdapter -mockWith { - return ([pscustomobject]@{InterfaceDescription = 'MyOtherAdapter'}) - } - - $result = Test-NetAdapterName -Name 'Adapter' -Description 'MyAdapter' - - It "should call all the mocks" { - Assert-VerifiableMocks - } - It 'should return false' { - $result | should be ($false) - } - } - - Context 'when the adapter name is not present' { - Mock -verifiable -commandName Get-NetAdapter -mockWith {} - - $result = Test-NetAdapterName -Name 'Adapter' -Description 'MyAdapter' - - It "should call all the mocks" { - Assert-VerifiableMocks - } - It 'should return false' { - $result | should be ($false) - } - } -} -#endregion - -#region Test-NetAdapterTeamMembership -Describe 'how Test-NetAdapterTeamMembership responds' { - Context 'when adapter is in team' { - Mock -commandName Get-NetLbfoTeamMember -mockWith { - return ([pscustomobject]@{Team = 'MyTeam'}) - } - - $result = Test-NetAdapterTeamMembership -TeamName 'MyTeam' -Name 'Something' - - It "should call all the mocks" { - Assert-VerifiableMocks - } - It 'should be true' { - $result | Should Be ($true) - } - } - - Context 'when adapter is in team and should not be' { - Mock -commandName Get-NetLbfoTeamMember -mockWith { - return ([pscustomobject]@{Team = 'MyOtherTeam'}) - } - - $result = Test-NetAdapterTeamMembership -TeamName 'MyTeam' -Name 'Something' - - It "should call all the mocks" { - Assert-VerifiableMocks - } - It 'should be false' { - $result | Should Be ($false) - } - } - - Context 'when TeamName is empty' { - - $result = Test-NetAdapterTeamMembership -TeamName '' - - It 'should be true' { - $result | Should Be ($true) - } - } - - Context 'when TeamName Does Not Exist' { - Mock -verifiable -commandName Get-NetLbfoTeamMember -mockWith {} - - $result = Test-NetAdapterTeamMembership -TeamName 'NoTeamHere' - - It "should call all the mocks" { - Assert-VerifiableMocks - } - It 'should be false' { - $result | should be ($false) - } - } -} -#endregion - -#region Remove-MismatchedNetLbfoTeamMember -Describe 'how Remove-MismatchedNetLbfoTeamMember responds' { - - Context 'when adapter exists in desired team ' { - Mock -commandName Remove-NetLbfoTeamMember -mockWith {} - Mock -commandName Remove-NetLbfoTeam -mockWith {} - Mock -commandName Get-NetLbfoTeamMember -mockWith { - return ([pscustomobject]@{Name = 'MyAdapter';Team = 'MyTeam'}) - } - - Remove-MismatchedNetLbfoTeamMember -Name 'MyAdapter' -Team 'MyTeam' - - It "should not call Remove-NetLbfoTeamMember or Remove-NetLbfoTeam" { - Assert-MockCalled -commandName Remove-NetLbfoTeamMember -times 0 -Exactly - Assert-MockCalled -commandName Remove-NetLbfoTeam -times 0 -Exactly - } - } - Context 'when adapter exists in desired team but RemoveFromAll is specfied' { - Mock -commandName Remove-NetLbfoTeamMember -mockWith {} - Mock -commandName Remove-NetLbfoTeam -mockWith {} - Mock -commandName Get-NetLbfoTeamMember -mockWith { - return ([pscustomobject]@{Name = 'MyAdapter';Team = 'MyTeam'}) - } - - Remove-MismatchedNetLbfoTeamMember -Name 'MyAdapter' -Team 'MyTeam' -RemoveFromAll - - It "should call Remove-NetLbfoTeamMember and not Remove-NetLbfoTeam" { - Assert-MockCalled -commandName Remove-NetLbfoTeamMember -times 1 -Exactly - Assert-MockCalled -commandName Remove-NetLbfoTeam -times 0 -Exactly - } - } - Context 'when adapter exists in different team and is only Nic in that team.' { - Mock -commandName Remove-NetLbfoTeamMember -mockWith { throw 'not me' } - Mock -commandName Remove-NetLbfoTeam -mockWith {} - Mock -commandName Get-NetLbfoTeamMember -mockWith { - return ([pscustomobject]@{Name = 'MyAdapter';Team = 'MyOtherTeam'}) - } - - Remove-MismatchedNetLbfoTeamMember -Name 'MyAdapter' -Team 'MyTeam' - - It "should call Remove-NetLbfoTeamMember, error, and Remove-NetLbfoTeam" { - Assert-MockCalled -commandName Remove-NetLbfoTeamMember -times 1 -Exactly - Assert-MockCalled -commandName Remove-NetLbfoTeam -times 1 -Exactly -parameterFilter { - $Name -like 'MyOtherTeam' - } - } - } -} -#endregion - -#region New-NetLbfoTeamMember -Describe 'how New-NetLbfoTeamMember responds' { - Context 'when the team exists' { - Mock -commandName Get-NetLbfoTeam -mockWith { return 1} - Mock -commandName Add-NetLbfoTeamMember -mockWith {} - Mock -commandName New-NetLbfoTeam -mockWith {} - - New-NetLbfoTeamMember -Name 'MyAdapter' -TeamName 'MyTeam' - - It 'should call Add-NetLbfoTeamMember and not New-NetLbfoTeam' { - Assert-MockCalled -commandName Add-NetLbfoTeamMember -times 1 -Exactly - Assert-MockCalled -commandName New-NetLbfoTeam -times 0 -Exactly - } - } - Context 'when the team does not exist' { - Mock -commandName Get-NetLbfoTeam -mockWith {} - Mock -commandName Add-NetLbfoTeamMember -mockWith {} - Mock -commandName New-NetLbfoTeam -mockWith {} - - New-NetLbfoTeamMember -Name 'MyAdapter' -TeamName 'MyTeam' - - It 'should call New-NetLbfoTeam and not Add-NetLbfoTeamMember' { - Assert-MockCalled -commandName Add-NetLbfoTeamMember -times 0 -Exactly - Assert-MockCalled -commandName New-NetLbfoTeam -times 1 -Exactly - } - } -} -#endregion - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_NetworkAdapter/StackExchange_NetworkAdapter.psd1 b/Resources/StackExchangeResources/DSCResources/StackExchange_NetworkAdapter/StackExchange_NetworkAdapter.psd1 deleted file mode 100644 index a5684b6..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_NetworkAdapter/StackExchange_NetworkAdapter.psd1 +++ /dev/null @@ -1,98 +0,0 @@ -# -# Module manifest for module 'NetworkAdapter' -# -# Generated by: Steven Murawski -# -# Generated on: 12/13/2013 -# - -@{ - -# Script module or binary module file associated with this manifest. -RootModule = 'StackExchange_NetworkAdapter.psm1' - -# Version number of this module. -ModuleVersion = '1.7' - -# ID used to uniquely identify this module -GUID = 'ee710f4c-f5d8-48d8-9677-9e36a40850dd' - -# Author of this module -Author = 'Steven Murawski' - -# Company or vendor of this module -CompanyName = 'Stack Exchange' - -# Copyright statement for this module -Copyright = '(c) 2013 Steven Murawski. All rights reserved.' - -# Description of the functionality provided by this module -# Description = '' - -# Minimum version of the Windows PowerShell engine required by this module -# PowerShellVersion = '' - -# Name of the Windows PowerShell host required by this module -# PowerShellHostName = '' - -# Minimum version of the Windows PowerShell host required by this module -# PowerShellHostVersion = '' - -# Minimum version of Microsoft .NET Framework required by this module -# DotNetFrameworkVersion = '' - -# Minimum version of the common language runtime (CLR) required by this module -# CLRVersion = '' - -# Processor architecture (None, X86, Amd64) required by this module -# ProcessorArchitecture = '' - -# Modules that must be imported into the global environment prior to importing this module -# RequiredModules = @() - -# Assemblies that must be loaded prior to importing this module -# RequiredAssemblies = @() - -# Script files (.ps1) that are run in the caller's environment prior to importing this module. -# ScriptsToProcess = @() - -# Type files (.ps1xml) to be loaded when importing this module -# TypesToProcess = @() - -# Format files (.ps1xml) to be loaded when importing this module -# FormatsToProcess = @() - -# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess -# NestedModules = @() - -# Functions to export from this module -FunctionsToExport = 'Get-TargetResource', 'Test-TargetResource', 'Set-TargetResource' - -# Cmdlets to export from this module -CmdletsToExport = '*' - -# Variables to export from this module -VariablesToExport = '*' - -# Aliases to export from this module -AliasesToExport = '*' - -# List of all modules packaged with this module -# ModuleList = @() - -# List of all files packaged with this module -# FileList = @() - -# Private data to pass to the module specified in RootModule/ModuleToProcess -# PrivateData = '' - -# HelpInfo URI of this module -# HelpInfoURI = '' - -# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. -# DefaultCommandPrefix = '' - -} - - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_NetworkAdapter/StackExchange_NetworkAdapter.psm1 b/Resources/StackExchangeResources/DSCResources/StackExchange_NetworkAdapter/StackExchange_NetworkAdapter.psm1 deleted file mode 100644 index 683705b..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_NetworkAdapter/StackExchange_NetworkAdapter.psm1 +++ /dev/null @@ -1,336 +0,0 @@ - - -function Get-TargetResource -{ - [OutputType([Hashtable])] - param ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $Name, - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $Description, - [parameter()] - [ValidateNotNullOrEmpty()] - [string] - $TeamName, - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - - #Needs to return a hashtable that returns the current - #status of the configuration component - $Adapter = Get-NetAdapter -InterfaceDescription $Description - if (($Adapter.Name -like $Name) -and ($Adapter.InterfaceDescription -like $Description)) - { - $Ensure = 'Present' - } - else - { - $Ensure = 'Absent' - } - - $Configuration = @{ - Name = $Name - Ensure = $Ensure - Description = $Description - } - - return $Configuration -} - -function Set-TargetResource -{ - param ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $Name, - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $Description, - [parameter()] - [ValidateNotNullOrEmpty()] - [string] - $TeamName, - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - if ($Ensure -like 'Present') - { - if (Test-NetAdapterName -Name $Name -Description $Description) - { - Write-Verbose "Adapter with $Description already named Correctly." - } - else - { - Write-Verbose "If the adapter name is already used, rename it to a temporary name." - Rename-NetAdapterWithWait -Name $Name -NewName "Temp-$(Get-Random -min 1 -max 100)" - Write-Verbose "Rename the network adapter." - Rename-NetAdapterWithWait -Name (Get-NetAdapter -InterfaceDescription $Description).Name -NewName $Name - } - - if (Test-NetAdapterTeamMembership -Name $Name -TeamName $TeamName) - { - Write-Verbose "Network adapter is correctly configured for teaming." - } - else - { - Remove-MismatchedNetLbfoTeamMember -TeamName $TeamName -Name $Name - New-NetLbfoTeamMember -TeamName $TeamName -Name $Name - } - } - else - { - if (Test-NetAdapterName -Name $Name -Description $Description) - { - Write-Verbose "Adapter should not be named $Name." - Write-Verbose "renaming it to a temporary name." - Rename-NetAdapterWithWait -Name $Name -NewName "Temp-$(Get-Random -min 1 -max 100)" - } - else - { - Write-Verbose "Adapter with description $Description is not named $Name." - } - Write-Verbose "Clearing team membership." - Remove-MismatchedNetLbfoTeamMember -TeamName $TeamName -Name (Get-NetAdapter -InterfaceDescription $Description).Name -RemoveFromAll - } -} - -function Test-TargetResource -{ - [OutputType([boolean])] - param ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $Name, - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $Description, - [parameter()] - [ValidateNotNullOrEmpty()] - [string] - $TeamName = '', - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - $IsValid = $true - Write-Verbose "Checking if network adapter with $Description exists." - $IsValid = (Test-NetAdapterExists -Description $Description) -and $IsValid - Write-Verbose "Checking if network adapter is named correctly." - $IsValid = (Test-NetAdapterName -Name $Name -Description $Description) -and $IsValid - Write-Verbose "Checking if network adapter is teamed correctly." - $IsValid = (Test-NetAdapterTeamMembership -TeamName $TeamName -Name $Name) -and $IsValid - - - if ($Ensure -like 'Absent') - { - Write-Verbose "Adapter $Description should not have $Name." - $IsValid = -not $IsValid - } - - Write-Verbose "Network adapter status is" - return $IsValid -} - -#region Support Functions -function Test-NetAdapterExists -{ - [cmdletbinding()] - param ( - [string]$Description - ) - if (Get-NetAdapter -InterfaceDescription $Description) - { - Write-Verbose "Network adapter with $Description exists." - return $true - } - else - { - throw "No adapter matching that description." - } - -} - -function Test-NetAdapterName -{ - [cmdletbinding()] - param ( - [string]$Name, - [string]$Description - ) - $Adapter = Get-NetAdapter -Name $Name -ErrorAction SilentlyContinue - - if ( $Adapter | Where-Object {$_.InterfaceDescription -like $Description} ) - { - Write-Verbose "The Name $Name is already used by the right adapter." - return $true - } - elseif ( $Adapter | Where-Object {$_.InterfaceDescription -notlike $Description} ) - { - Write-Verbose "The Name $Name is already being used by another adapter." - return $false - } - else - { - Write-Verbose "The Name $Name is not in use " - return $false - } -} - -function Test-NetAdapterState -{ - param ( - [string]$State, - [switch]$Up, - [switch]$Disconnected, - [switch]$Disabled - ) - - $ValidStates = @() - if ($Up) - { - $ValidStates += 'Up' - } - if ($Disabled) - { - $ValidStates += 'Disabled' - } - if ($Disconnected) - { - $ValidStates += 'Disconnected' - } - - $OFS = ', ' - Write-Verbose "Valid states are $ValidStates." - Write-Verbose "Current state is $state." - return ($ValidStates -contains $State) - -} - -function Test-NetAdapterTeamMembership -{ - [cmdletbinding()] - param ([string]$Name, [string]$TeamName) - - Write-Verbose "Testing if $Name is present in NIC Team - $TeamName" - $IsValid = $true - $ShouldBeOnTeam = -not [string]::IsNullOrEmpty($TeamName) - - Write-Verbose "Checking for NIC to be present in $TeamName" - $TeamMember = Get-NetLbfoTeamMember -Name $Name -ErrorAction SilentlyContinue - - if ($TeamMember -and $ShouldBeOnTeam) - { - Write-Verbose "NIC $Name is in a team - $($TeamMember.Team)." - $IsValid = ($TeamMember.Team -like $TeamName) -and $IsValid - } - elseif ($ShouldBeOnTeam) - { - Write-Verbose "$Name is not in a team." - $IsValid = $IsValid -and $false - } - elseif ($TeamMember -and (-not $ShouldBeOnTeam)) - { - Write-Verbose "$Name is in a team and should not be." - $IsValid = $IsValid -and $false - } - else - { - Write-Verbose "$Name is not in a team and should not be." - } - - return $IsValid -} - -function Remove-MismatchedNetLbfoTeamMember -{ - [cmdletbinding()] - param ( - [string]$Name, - [string]$TeamName, - [switch]$RemoveFromAll - ) - - Get-NetLbfoTeamMember -Name $Name -ErrorAction SilentlyContinue | - Where-Object { if ($RemoveFromAll) {$true} else {$_.Team -notlike $TeamName} } | - ForEach-Object { - $TeamMember = $_ - try - { - Write-Verbose "Removing $Name from team $($TeamMember.team)." - Remove-NetLbfoTeamMember -Name $TeamMember.name -Team $TeamMember.Team -Confirm:$false -ErrorAction Stop - } - catch - { - Write-Verbose "Failed to remove $Name from team $($TeamMember.team)." - Write-Verbose "Removing team $($TeamMember.Team)." - Remove-NetLbfoTeam -Name $TeamMember.Team -Confirm:$false - } - } -} - -function New-NetLbfoTeamMember -{ - [cmdletbinding()] - param ( - [string]$Name, - [string]$TeamName - ) - - Write-Verbose "Checking for NIC Team - $TeamName" - if (Get-NetLBFOTeam -Name $TeamName -ErrorAction SilentlyContinue) - { - Write-Verbose "Adding NIC $Name to team $teamname." - Add-NetLbfoTeamMember -Team $TeamName -Name $Name -Confirm:$false - } - else - { - Write-Verbose "Team $TeamName does not exist. Creating team with $Name." - $TeamParameters = @{ - LoadBalancingAlgorithm = 'TransportPorts' - Name = $TeamName - TeamNicName = $TeamName - TeamingMode = 'SwitchIndependent' - TeamMembers = $Name - Confirm = $false - } - New-NetLbfoTeam @TeamParameters - } - - -} - -function Rename-NetAdapterWithWait -{ - [cmdletbinding()] - param ( - $Name, - $NewName - ) - - Get-NetAdapter -Name $Name -ErrorAction SilentlyContinue | - Rename-NetAdapter -NewName $NewName -Confirm:$false | - ForEach-Object { - while ( -not (Get-NetAdapter -Name $NewName -ErrorAction SilentlyContinue) ) - { - Write-Verbose "Waiting for rename of improperly named NIC to take effect." - Start-Sleep -Seconds 2 - } - Write-Verbose "Improperly named NIC has been renamed." - } -} -#endregion - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_NetworkAdapter/StackExchange_NetworkAdapter.schema.mof b/Resources/StackExchangeResources/DSCResources/StackExchange_NetworkAdapter/StackExchange_NetworkAdapter.schema.mof deleted file mode 100644 index e2c4b6b..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_NetworkAdapter/StackExchange_NetworkAdapter.schema.mof +++ /dev/null @@ -1,10 +0,0 @@ -[ClassVersion("1.0"), FriendlyName("NetworkAdapter")] -class StackExchange_NetworkAdapter : OMI_BaseResource -{ - [Key] string Name; - [Key] string Description; - [write] string TeamName; - [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; -}; - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_Pagefile.Tests.ps1 b/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_Pagefile.Tests.ps1 deleted file mode 100644 index ad32a77..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_Pagefile.Tests.ps1 +++ /dev/null @@ -1,193 +0,0 @@ -$here = Split-Path -Parent $MyInvocation.MyCommand.Path -$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.ps1", ".psm1") -$pathtosut = join-path $here $sut - -iex ( gc $pathtosut -Raw ) - -Describe 'how Get-TargetResource reponds' { - Context 'when automatic page file is configured' { - mock -commandName Get-WmiObject -parameterFilter {$Class -like 'Win32_ComputerSystem'} -mockWith { - return ([pscustomobject]@{AutomaticManagedPageFile = $true}) - } - mock -commandName Get-WmiObject -parameterFilter {$Class -like 'Win32_PageFileSetting'} -mockWith {} - - $result = Get-TargetResource -initialsize 4GB -MaximumSize 4GB -Ensure 'Present' - - It 'should call once Get-WmiObject Win32_ComputerSystem ' { - Assert-MockCalled -commandName Get-WmiObject -times 1 -Exactly -parameterFilter { - $Class -like 'Win32_ComputerSystem' - } - } - It 'should not call Get-WmiObject Win32_PageFileSetting' { - Assert-MockCalled -commandName Get-WmiObject -times 0 -Exactly -parameterFilter { - $Class -like 'Win32_PageFileSetting' - } - } - It "should return Ensure = 'Absent'" { - $result['Ensure'] | should be ('Absent') - } - } - Context 'when automatic page file not configured' { - mock -commandName Get-WmiObject -parameterFilter {$Class -like 'Win32_ComputerSystem'} -mockWith { - return ([pscustomobject]@{AutomaticManagedPageFile = $false}) - } - mock -commandName Get-WmiObject -parameterFilter {$Class -like 'Win32_PageFileSetting'} -mockWith { - return ([pscustomobject]@{ - InitialSize = (3GB/1MB) - MaximumSize = (3GB/1MB) - }) - } - - $result = Get-TargetResource -initialsize 4GB -MaximumSize 4GB -Ensure 'Present' - - It 'should call once Get-WmiObject Win32_ComputerSystem ' { - Assert-MockCalled -commandName Get-WmiObject -times 1 -Exactly -parameterFilter { - $Class -like 'Win32_ComputerSystem' - } - } - It 'should call once Get-WmiObject Win32_PageFileSetting' { - Assert-MockCalled -commandName Get-WmiObject -times 1 -Exactly -parameterFilter { - $Class -like 'Win32_PageFileSetting' - } - } - It "should return Ensure = 'Present' with Intial and Maximum size at 3GB" { - $result['Ensure'] | should be ('Present') - $result['InitialSize'] | should be (3GB) - $result['MaximumSize'] | should be (3GB) - } - - } -} - -Describe 'how Set-TargetResource responds' { - - Context 'when Ensure is set to Absent and AutomaticPageFile is set' { - Mock -commandName Get-WmiObject -parameterFilter {$Class -like 'Win32_ComputerSystem'} -mockWith { - $r = [pscustomobject]@{ - AutomaticManagedPageFile = $true - } | Add-Member -MemberType ScriptMethod -Name Put -Value { - $global:PutWasCalled = $true - $global:PutValue = $this - } -PassThru - return ($r) - } - $global:PutValue = $null - $global:PutWasCalled = $False - Set-TargetResource -initialsize 4GB -MaximumSize 4GB -Ensure 'Absent' - - It 'should not call put' { - $global:PutWasCalled | should be ($false) - } - } - - Context 'when Ensure is set to Absent and AutomaticPageFile is not set' { - Mock -commandName Get-WmiObject -parameterFilter {$Class -like 'Win32_ComputerSystem'} -mockWith { - $r = [pscustomobject]@{ - AutomaticManagedPageFile = $false - } | Add-Member -MemberType ScriptMethod -Name Put -Value { - $global:PutWasCalled = $true - $global:PutValue = $this - } -PassThru - return ($r) - } - $global:PutValue = $null - $global:PutWasCalled = $False - Set-TargetResource -initialsize 4GB -MaximumSize 4GB -Ensure 'Absent' - - It 'should call put' { - $global:PutWasCalled | should be ($true) - } - It 'should set AutomaticManagedPageFile set to $true' { - $global:PutValue.AutomaticManagedPageFile | should be ($true) - } - - } - Context 'when Ensure is set to Absent and AutomaticPageFile is not set' { - Mock -commandName Get-WmiObject -parameterFilter {$Class -like 'Win32_ComputerSystem'} -mockWith { - $r = [pscustomobject]@{ AutomaticManagedPageFile = $false - } | - Add-Member -MemberType ScriptMethod -Name Put -Value { - $global:Win32_ComputerPutWasCalled = $true - $global:Win32_ComputerPutValue = $this - } -PassThru - return ($r) - } - Mock -commandName Get-WmiObject -parameterFilter {$Class -like 'Win32_PageFileSetting'} -mockWith { - $r = [pscustomobject]@{ - InitialSize = 0 - MaximumSize = 0 - } | Add-Member -MemberType ScriptMethod -Name Put -Value { - $global:Win32_PageFileSettingPutWasCalled = $true - $global:Win32_PageFileSettingPutValue = $this - } -PassThru - return ($r) - } - - $global:Win32_ComputerPutValue = $null - $global:Win32_ComputerPutWasCalled = $False - $global:Win32_PageFileSettingPutValue = $null - $global:Win32_PageFileSettingPutWasCalled = $False - - Set-TargetResource -initialsize 4GB -MaximumSize 4GB -Ensure 'Absent' - - It 'should call put to Win32_ComputerSystem' { - $global:Win32_ComputerPutWasCalled | should be ($true) - } - It 'should set AutomaticManagedPageFile set to $true' { - $global:Win32_ComputerPutValue.AutomaticManagedPageFile | should be ($true) - } - - } - Context 'when Ensure is set to Present and AutomaticPageFile is not set' { - Mock -commandName Get-WmiObject -parameterFilter {$Class -like 'Win32_ComputerSystem'} -mockWith { - $r = [pscustomobject]@{ AutomaticManagedPageFile = $false - } | - Add-Member -MemberType ScriptMethod -Name Put -Value { - $global:Win32_ComputerPutWasCalled = $true - $global:PutVWin32_ComputerPutValuealue = $this - } -PassThru - return ($r) - } - Mock -commandName Get-WmiObject -parameterFilter {$Class -like 'Win32_PageFileSetting'} -mockWith { - $r = [pscustomobject]@{ - InitialSize = 0 - MaximumSize = 0 - } | Add-Member -MemberType ScriptMethod -Name Put -Value { - $global:Win32_PageFileSettingPutWasCalled = $true - $global:Win32_PageFileSettingPutValue = $this - } -PassThru - return ($r) - } - - $global:Win32_ComputerPutValue = $null - $global:Win32_ComputerPutWasCalled = $False - $global:Win32_PageFileSettingPutValue = $null - $global:Win32_PageFileSettingPutWasCalled = $False - - Set-TargetResource -initialsize 4GB -MaximumSize 4GB -Ensure 'Present' - - It 'should call put on Win32_PageFileSetting' { - $global:PutWasCalled | should be ($true) - } - It 'should not set AutomaticManagedPageFile set to $true' { - $global:Win32_ComputerPutValue.AutomaticManagedPageFile | should beNullOrEmpty - } - It 'should set Initial and Maximum size to 4 GB' { - $global:Win32_PageFileSettingPutValue.InitialSize | should be (4gb/1mb) - $global:Win32_PageFileSettingPutValue.MaximumSize | should be (4gb/1mb) - } - - } - - - Get-Variable -Scope Global -Name Win32_ComputerPutValue | - Remove-Variable -Scope Global -Force - Get-Variable -Scope Global -Name Win32_ComputerPutWasCalled | - Remove-Variable -Scope Global -Force - Get-Variable -Scope Global -Name Win32_PageFileSettingPutValue | - Remove-Variable -Scope Global -Force - Get-Variable -Scope Global -Name Win32_PageFileSettingPutWasCalled | - Remove-Variable -Scope Global -Force -} - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_Pagefile.psd1 b/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_Pagefile.psd1 deleted file mode 100644 index afde87e..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_Pagefile.psd1 +++ /dev/null @@ -1,98 +0,0 @@ -# -# Module manifest for module 'Pagefile' -# -# Generated by: Steven Murawski -# -# Generated on: 12/13/2013 -# - -@{ - -# Script module or binary module file associated with this manifest. -RootModule = 'StackExchange_Pagefile.psm1' - -# Version number of this module. -ModuleVersion = '1.7' - -# ID used to uniquely identify this module -GUID = '6328017a-8ac3-424d-90e3-ca3299fdaa8a' - -# Author of this module -Author = 'Steven Murawski' - -# Company or vendor of this module -CompanyName = 'Stack Exchange' - -# Copyright statement for this module -Copyright = '(c) 2013 Steven Murawski. All rights reserved.' - -# Description of the functionality provided by this module -# Description = '' - -# Minimum version of the Windows PowerShell engine required by this module -# PowerShellVersion = '' - -# Name of the Windows PowerShell host required by this module -# PowerShellHostName = '' - -# Minimum version of the Windows PowerShell host required by this module -# PowerShellHostVersion = '' - -# Minimum version of Microsoft .NET Framework required by this module -# DotNetFrameworkVersion = '' - -# Minimum version of the common language runtime (CLR) required by this module -# CLRVersion = '' - -# Processor architecture (None, X86, Amd64) required by this module -# ProcessorArchitecture = '' - -# Modules that must be imported into the global environment prior to importing this module -# RequiredModules = @() - -# Assemblies that must be loaded prior to importing this module -# RequiredAssemblies = @() - -# Script files (.ps1) that are run in the caller's environment prior to importing this module. -# ScriptsToProcess = @() - -# Type files (.ps1xml) to be loaded when importing this module -# TypesToProcess = @() - -# Format files (.ps1xml) to be loaded when importing this module -# FormatsToProcess = @() - -# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess -# NestedModules = @() - -# Functions to export from this module -FunctionsToExport = 'Get-TargetResource', 'Test-TargetResource', 'Set-TargetResource' - -# Cmdlets to export from this module -CmdletsToExport = '*' - -# Variables to export from this module -VariablesToExport = '*' - -# Aliases to export from this module -AliasesToExport = '*' - -# List of all modules packaged with this module -# ModuleList = @() - -# List of all files packaged with this module -# FileList = @() - -# Private data to pass to the module specified in RootModule/ModuleToProcess -# PrivateData = '' - -# HelpInfo URI of this module -# HelpInfoURI = '' - -# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. -# DefaultCommandPrefix = '' - -} - - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_Pagefile.psm1 b/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_Pagefile.psm1 deleted file mode 100644 index aa6e061..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_Pagefile.psm1 +++ /dev/null @@ -1,172 +0,0 @@ - -# Fallback message strings in en-US -DATA localizedData -{ - # same as culture = "en-US" - ConvertFrom-StringData @' -AutomaticPageFileConfigured=The page file is set to automatic configuration. -PageFileStaticallyConfigured=The page file is statically configured with the initial size of {0} and a maximum size of {1}. -DisabledAutomaticPageFile=The automatic page file configuration is disabled. -RebootRequired=A reboot is required to finalize the changes to the page file. -InitialSizeDifferent=Configured Initial Size {0} different than Desired size {1}. -MaximumSizeDifferent=Configured Maximum Size {0} different than Desired size {1}. -'@ -} - -if (Test-Path $PSScriptRoot\en-us) -{ - Import-LocalizedData LocalizedData -filename PagefileProvider.psd1 -} - -function Get-TargetResource -{ - [OutputType([Hashtable])] - param ( - [parameter(Mandatory = $true)] - [long] - $InitialSize, - [parameter(Mandatory = $true)] - [long] - $MaximumSize, - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - - #Needs to return a hashtable that returns the current - #status of the configuration component - $ComputerSystem = Get-WmiObject win32_computersystem - if ($ComputerSystem.AutomaticManagedPageFile) - { - Write-Verbose $LocalizedData.AutomaticPageFileConfigured - $Configuration = @{ - Ensure = 'Absent' - } - } - else - { - $PageFileSetting = Get-WmiObject Win32_PageFileSetting - $Configuration = @{ - Ensure = 'Present' - InitialSize = $PageFileSetting.InitialSize * 1mb - MaximumSize = $PageFileSetting.MaximumSize * 1mb - } - - Write-Verbose ($LocalizedData.PageFileStaticallyConfigured -f $Configuration.InitialSize, $Configuration.MaximumSize) - } - return $Configuration -} - -function Set-TargetResource -{ - param ( - [parameter(Mandatory = $true)] - [long] - $InitialSize, - [parameter(Mandatory = $true)] - [long] - $MaximumSize, - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - $ComputerSystem = Get-WmiObject win32_computersystem - - if ($ComputerSystem.AutomaticManagedPageFile) - { - if ($Ensure -like 'Present') - { - Write-Verbose $LocalizedData.AutomaticPageFileConfigured - $ComputerSystem.AutomaticManagedPageFile = $false - $ComputerSystem.Put() | Out-Null - Write-Verbose $LocalizedData.DisabledAutomaticPageFile - } - else - { - Write-Verbose "Nothing to configure here." - } - } - else - { - if ($Ensure -like 'Present') - { - $PageFileSetting = Get-WmiObject Win32_PageFileSetting - $PageFileSetting.InitialSize = $InitialSize / 1MB - $PageFileSetting.MaximumSize = $MaximumSize / 1MB - $PageFileSetting.put() | Out-Null - - Write-Verbose ($LocalizedData.PageFileStaticallyConfigured -f $InitialSize, $MaximumSize) - } - else - { - $ComputerSystem.AutomaticManagedPageFile = $true - $ComputerSystem.Put() | Out-Null - Write-Verbose $LocalizedData.AutomaticPageFileConfigured - } - } - - Write-Verbose $LocalizedData.RebootRequired - $global:DSCMachineStatus = 1 -} - -function Test-TargetResource -{ - [OutputType([boolean])] - param ( - [parameter(Mandatory = $true)] - [long] - $InitialSize, - [parameter(Mandatory = $true)] - [long] - $MaximumSize, - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - - $Valid = $true - $ComputerSystem = Get-WmiObject win32_computersystem - $PageFileSetting = Get-WmiObject Win32_PageFileSetting - - if ($Ensure -like 'Present') - { - - if ($ComputerSystem.AutomaticManagedPageFile) - { - Write-Verbose $LocalizedData.AutomaticPageFileConfigured - $Valid = $Valid -and $false - } - - - if ($PageFileSetting -ne $null) - { - if (-not ($PageFileSetting.InitialSize -eq ($InitialSize / 1MB))) - { - Write-Verbose ($LocalizedData.InitialSizeDifferent -f ($PageFileSetting.InitialSize * 1mb), $InitialSize) - $Valid = $Valid -and $false - } - - if (-not ($PageFileSetting.MaximumSize -eq ($MaximumSize / 1MB))) - { - Write-Verbose ($LocalizedData.MaximumSizeDifferent -f ($PageFileSetting.MaximumSize * 1mb), $MaximumSize) - $Valid = $Valid -and $false - } - } - } - else - { - if (-not $ComputerSystem.AutomaticManagedPageFile) - { - Write-Verbose $LocalizedData.DisabledAutomaticPageFile - $Valid = $Valid -and $false - } - } - - #Needs to return a boolean - return $valid -} - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_Pagefile.schema.mof b/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_Pagefile.schema.mof deleted file mode 100644 index 5b82cc8..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_Pagefile.schema.mof +++ /dev/null @@ -1,9 +0,0 @@ -[ClassVersion("1.0.0"), FriendlyName("Pagefile")] -class StackExchange_Pagefile : OMI_BaseResource -{ - [Key] sint64 InitialSize; - [Key] sint64 MaximumSize; - [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; -}; - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_en-US/StackExchange_PagefileProvider.psd1 b/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_en-US/StackExchange_PagefileProvider.psd1 deleted file mode 100644 index 9f6c694..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_en-US/StackExchange_PagefileProvider.psd1 +++ /dev/null @@ -1,14 +0,0 @@ -# Localized PagefileProvider.psd1 - -ConvertFrom-StringData @' -###PSLOC -AutomaticPageFileConfigured=The page file is set to automatic configuration. -PageFileStaticallyConfigured=The page file is statically configured with the initial size of {0} and a maximum size of {1}. -DisabledAutomaticPageFile=The automatic page file configuration is disabled. -RebootRequired=A reboot is required to finalize the changes to the page file. -InitialSizeDifferent=Configured Initial Size {0} different than Desired size {1}. -MaximumSizeDifferent=Configured Maximum Size {0} different than Desired size {1}. -###PSLOC -'@ - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_en-US/StackExchange_about_PageFile_Resource.help.txt b/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_en-US/StackExchange_about_PageFile_Resource.help.txt deleted file mode 100644 index 98b5c89..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_en-US/StackExchange_about_PageFile_Resource.help.txt +++ /dev/null @@ -1,16 +0,0 @@ -Syntax - -Pagefile [string] #ResourceName -{ - InitialSize = [long] - MaximumSize = [long] - [ Ensure = [string] { Absent | Present } ] -} - -Properties - -InitialSize - The minimum size for the machine's page file, in bytes. -MaximumSize - The maximum size for the machine's page file, in bytes. -Ensure - Set this property to "Present" to disable automatic page file and set the minimum and maximum sizes for the page file. Set this file to "Absent" to enable automatic page file management. Values are required for Initial and Maximum size, but they will be ignored when Ensure is set to "Absent". - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_nl-NL/StackExchange_PagefileProvider.psd1 b/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_nl-NL/StackExchange_PagefileProvider.psd1 deleted file mode 100644 index afe3cac..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_nl-NL/StackExchange_PagefileProvider.psd1 +++ /dev/null @@ -1,14 +0,0 @@ -# Localized PagefileProvider.psd1 - -ConvertFrom-StringData @' -###PSLOC -AutomaticPageFileConfigured=De automatische instelling van het wisselbestand is ingeschakeld. -PageFileStaticallyConfigured=Het wisselbestand is statisch geconfigureerd met een startgrootte van {0} en een maximale grootte van {1} -DisabledAutomaticPageFile=De automatische instelling van het wisselbestand is uitgeschakeld. -RebootRequired=Een herstart is vereist om de wijzigingen aan het wisselbestand af te ronden. -InitialSizeDifferent=Geconfigureerde startgrootte {0} wijkt af van de gewenste grootte {1}. -MaximumSizeDifferent=Geconfigureerde maximal grootte {0} wijkt af van de gewenste grootte {1}. -###PSLOC -'@ - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_nl-NL/StackExchange_about_PageFile_Resource.help.txt b/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_nl-NL/StackExchange_about_PageFile_Resource.help.txt deleted file mode 100644 index c510b6f..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_Pagefile/StackExchange_nl-NL/StackExchange_about_PageFile_Resource.help.txt +++ /dev/null @@ -1,16 +0,0 @@ -Syntax - -Pagefile [string] #ResourceName -{ - InitialSize = [long] - MaximumSize = [long] - [ Ensure = [string] { Absent | Present } ] -} - -Properties - -InitialSize - De startgrootte voor het wisselbestand in bytes. -MaximumSize - De maximale grootte voor het wisselbestand in bytes. -Ensure - Stel deze waarde in op "Present" om de automatische configuratie van het wisselbestand uit te schakelen. Hierna kunt u een startgrootte en een maximale grootte opgeven. Stel deze waarde in op "Absent" om de grootte van het wisselbestand automatisch in te stellen. Waardes voor "Initial" en "Maximum" zijn verplicht maar deze worden genegeerd wanneer Ensure is ingesteld op "Absent". - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_PowerPlan/StackExchange_PowerPlan.psd1 b/Resources/StackExchangeResources/DSCResources/StackExchange_PowerPlan/StackExchange_PowerPlan.psd1 deleted file mode 100644 index 70be453..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_PowerPlan/StackExchange_PowerPlan.psd1 +++ /dev/null @@ -1,98 +0,0 @@ -# -# Module manifest for module 'PowerPlan' -# -# Generated by: Steven Murawski -# -# Generated on: 12/13/2013 -# - -@{ - -# Script module or binary module file associated with this manifest. -RootModule = 'StackExchange_PowerPlan.psm1' - -# Version number of this module. -ModuleVersion = '1.7' - -# ID used to uniquely identify this module -GUID = '8c9f080b-f7e6-456b-92cb-12aeba980eaa' - -# Author of this module -Author = 'Steven Murawski' - -# Company or vendor of this module -CompanyName = 'Stack Exchange' - -# Copyright statement for this module -Copyright = '(c) 2013 Steven Murawski. All rights reserved.' - -# Description of the functionality provided by this module -# Description = '' - -# Minimum version of the Windows PowerShell engine required by this module -# PowerShellVersion = '' - -# Name of the Windows PowerShell host required by this module -# PowerShellHostName = '' - -# Minimum version of the Windows PowerShell host required by this module -# PowerShellHostVersion = '' - -# Minimum version of Microsoft .NET Framework required by this module -# DotNetFrameworkVersion = '' - -# Minimum version of the common language runtime (CLR) required by this module -# CLRVersion = '' - -# Processor architecture (None, X86, Amd64) required by this module -# ProcessorArchitecture = '' - -# Modules that must be imported into the global environment prior to importing this module -# RequiredModules = @() - -# Assemblies that must be loaded prior to importing this module -# RequiredAssemblies = @() - -# Script files (.ps1) that are run in the caller's environment prior to importing this module. -# ScriptsToProcess = @() - -# Type files (.ps1xml) to be loaded when importing this module -# TypesToProcess = @() - -# Format files (.ps1xml) to be loaded when importing this module -# FormatsToProcess = @() - -# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess -# NestedModules = @() - -# Functions to export from this module -FunctionsToExport = 'Get-TargetResource', 'Test-TargetResource', 'Set-TargetResource' - -# Cmdlets to export from this module -CmdletsToExport = '*' - -# Variables to export from this module -VariablesToExport = '*' - -# Aliases to export from this module -AliasesToExport = '*' - -# List of all modules packaged with this module -# ModuleList = @() - -# List of all files packaged with this module -# FileList = @() - -# Private data to pass to the module specified in RootModule/ModuleToProcess -# PrivateData = '' - -# HelpInfo URI of this module -# HelpInfoURI = '' - -# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. -# DefaultCommandPrefix = '' - -} - - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_PowerPlan/StackExchange_PowerPlan.psm1 b/Resources/StackExchangeResources/DSCResources/StackExchange_PowerPlan/StackExchange_PowerPlan.psm1 deleted file mode 100644 index e33096c..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_PowerPlan/StackExchange_PowerPlan.psm1 +++ /dev/null @@ -1,193 +0,0 @@ -$CIMParameters = @{ - Namespace = 'root\cimv2\power' - Class = 'Win32_PowerPlan' -} - -DATA localizedData -{ - # same as culture = "en-US" - ConvertFrom-StringData @' -ElementName=Adding filter for Element Name of {0} -FilterText=Adding the filter text ({0}) to the query. -IsActiveFilter=Adding filter for IsActive = True -NoFilterCriteria=No filter criteria. Making sure nothing is hanging around. -Cruft=Found some cruft. Removing. -MatchingActivePowerPlan=Found a matching active powerplan. -NoMatchingActivePowerPlan=Did not a matching active powerplan. -SettingActivePowerPlan=Setting active Power Plan to {0} -CurrentPowerPlan=Current Power Plan is set to {0}. -CheckingForActivePowerPlan=Checking for an active powerplan called {0}. -ActivePlanNotSetTo=The active Power Plan is not set to {0}. -ActivePlanSetTo=The active Power Plan is set to {0}. All good here. -ActivePlanSetToAndShouldNotBe=The active Power Plan is set to {0}, and should not be. -ActivePlanNotSetToAndShouldNotBe=The active Power Plan is not set to {0}, and should not be. All good here. -'@ -} - -if (Test-Path $PSScriptRoot\en-us) -{ - Import-LocalizedData LocalizedData -filename PowerPlanProvider.psd1 -} - - -function Get-TargetResource -{ - [OutputType([Hashtable])] - param ( - [parameter(Mandatory = $true)] - [string] - $Name, - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - - $powerplan = Get-CIMPowerPlan -name $Name -active - - $Configuration = @{ - Name = $Name - } - - If ($PowerPlan) - { - #Needs to return a hashtable that returns the current - #status of the configuration component - Write-Verbose $LocalizedData.MatchingActivePowerPlan - $Configuration.Ensure = 'Present' - } - else - { - Write-Verbose $LocalizedData.NoMatchingActivePowerPlan - $Configuration.Ensure = 'Absent' - } - return $Configuration -} - -function Set-TargetResource -{ - param ( - [parameter(Mandatory = $true)] - [string] - $Name, - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - - if ($Ensure -like 'Present') - { - Set-CIMPowerPlan -name $Name - } - else - { - Write-Verbose ($localizedData.CurrentPowerPlan -f $Name) - switch ($Name) - { - 'Balanced' { Set-CimPowerPlan -name 'High Performance' } - default { Set-CimPowerPlan -name 'Balanced' } - } - } - -} - -function Test-TargetResource -{ - [OutputType([boolean])] - param ( - [parameter(Mandatory = $true)] - [string] - $Name, - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - - $Valid = $true - - Write-Verbose ($LocalizedData.CheckingForActivePowerPlan -f $Name) - $PowerPlan = Get-CIMPowerPlan -active -name $Name - - if ($Ensure -like 'Present') - { - if ( $PowerPlan -eq $null ) - { - Write-Verbose ($LocalizedData.ActivePlanNotSetTo -f $Name) - $Valid = $false - } - else - { - Write-Verbose ($LocalizedData.ActivePlanSetTo -f $Name) - } - } - else - { - if ( $PowerPlan -ne $null ) - { - Write-Verbose ($LocalizedData.ActivePlanSetToAndShouldNotBe -f $Name) - $Valid = $false - } - else - { - Write-Verbose ($LocalizedData.ActivePlanNotSetToAndShouldNotBe -f $Name) - } - } - return $valid -} - -Function Get-CIMPowerPlan -{ - param ([string]$name, [switch]$active) - - $FilterText = '' - if (-not [string]::IsNullOrEmpty($name)) - { - if (-not [string]::IsNullOrEmpty($FilterText)) - { - $FilterText += ' and ' - } - Write-Debug ($LocalizedData.ElementName -f $Name) - $FilterText += "ElementName like '$Name'" - } - if ($active) - { - if (-not [string]::IsNullOrEmpty($FilterText)) - { - $FilterText += ' and ' - } - Write-Debug $LocalizedData.IsActiveFilter - $FilterText += "IsActive = 'True'" - } - - if ([string]::IsNullOrEmpty($FilterText)) - { - Write-Debug $LocalizedData.NoFilterCriteria - if ($CIMParameters.ContainsKey('Filter')) - { - Write-Debug $LocalizedData.Cruft - $CIMParameters.Remove('Filter') | Out-Null - } - } - else - { - Write-Debug ($LocalizedData.FilterText -f $FilterText) - $CIMParameters.Filter = $FilterText - } - - Get-CimInstance @CIMParameters - -} - -function Set-CIMPowerPlan -{ - param ($name) - - Write-Verbose ($LocalizedData.SettingActivePowerPlan -f $Name) - - Get-CIMPowerPlan -name $name | - Invoke-CimMethod -MethodName Activate -} - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_PowerPlan/StackExchange_PowerPlan.schema.mof b/Resources/StackExchangeResources/DSCResources/StackExchange_PowerPlan/StackExchange_PowerPlan.schema.mof deleted file mode 100644 index abdc4df..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_PowerPlan/StackExchange_PowerPlan.schema.mof +++ /dev/null @@ -1,8 +0,0 @@ -[ClassVersion("1.0.0"), FriendlyName("PowerPlan")] -class StackExchange_PowerPlan : OMI_BaseResource -{ - [Key] string Name; - [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; -}; - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_PowerPlan/StackExchange_en-US/StackExchange_PowerPlanProvider.psd1 b/Resources/StackExchangeResources/DSCResources/StackExchange_PowerPlan/StackExchange_en-US/StackExchange_PowerPlanProvider.psd1 deleted file mode 100644 index 166b6fe..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_PowerPlan/StackExchange_en-US/StackExchange_PowerPlanProvider.psd1 +++ /dev/null @@ -1,20 +0,0 @@ - -ConvertFrom-StringData @' -###PSLOC -ElementName=Adding filter for Element Name of {0} -FilterText=Adding the filter text ({0}) to the query. -IsActiveFilter=Adding filter for IsActive = True -NoFilterCriteria=No filter criteria. Making sure nothing is hanging around. -Cruft=Found some cruft. Removing. -MatchingActivePowerPlan=Found a matching active powerplan. -NoMatchingActivePowerPlan=Did not a matching active powerplan. -SettingActivePowerPlan=Setting active Power Plan to {0} -CurrentPowerPlan=Current Power Plan is set to {0}. -CheckingForActivePowerPlan=Checking for an active powerplan called {0}. -ActivePlanNotSetTo=The active Power Plan is not set to {0}. -ActivePlanSetTo=The active Power Plan is set to {0}. All good here. -ActivePlanSetToAndShouldNotBe=The active Power Plan is set to {0}, and should not be. -ActivePlanNotSetToAndShouldNotBe=The active Power Plan is not set to {0}, and should not be. All good here. -###PSLOC -'@ - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_PowerPlan/StackExchange_en-US/StackExchange_about_PowerPlan_Resource.txt b/Resources/StackExchangeResources/DSCResources/StackExchange_PowerPlan/StackExchange_en-US/StackExchange_about_PowerPlan_Resource.txt deleted file mode 100644 index e013a5e..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_PowerPlan/StackExchange_en-US/StackExchange_about_PowerPlan_Resource.txt +++ /dev/null @@ -1,12 +0,0 @@ -Syntax - -PowerPlan [string] #ResourceName -{ - Name = [string] - [ Ensure = [string] { Absent | Present } ] -} - -Properties - -Name - Name of the PowerPlan. Common plans are "Balanced", "High performance", and "Power saver". -Ensure - Set this property to "Present" to activate the desired Power Plan. Set this property to "Absent" to return to "Balanced" from other plans (if it is already set to "Balanced", it'll set it to "High performance"). diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_ScheduledTask/StackExchange_ScheduledTask.Tests.ps1 b/Resources/StackExchangeResources/DSCResources/StackExchange_ScheduledTask/StackExchange_ScheduledTask.Tests.ps1 deleted file mode 100644 index c15045b..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_ScheduledTask/StackExchange_ScheduledTask.Tests.ps1 +++ /dev/null @@ -1,602 +0,0 @@ -$here = Split-Path -Parent $MyInvocation.MyCommand.Path -$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.ps1", ".psm1") -$pathtosut = join-path $here $sut - -iex (gc $pathtosut -Raw) - -Describe 'how Test-JobFilePath responds' { - Context 'when the file path is correct' { - $script:TargetResource = [pscustomobject]@{ - FilePath = 'c:\scripts\test.ps1' - Job = [pscustomobject]@{ - Command = 'c:\scripts\test.ps1' - } - IsValid = $true - } - - Test-JobFilePath - it 'should return true' { - $script:TargetResource.IsValid | should be $true - } - } - - Context 'when the file path is correct' { - $script:TargetResource = [pscustomobject]@{ - FilePath = 'c:\scripts\test.ps1' - Job = [pscustomobject]@{ - Command = 'c:\scripts\nottest.ps1 ' - } - IsValid = $true - } - - Test-JobFilePath - it 'should return false' { - $script:TargetResource.IsValid | should be $false - } - } -} - -Describe 'how Test-JobTriggerAtTime responds' { - Context 'when job At time matches configured At time' { - $script:TargetResource = [pscustomobject]@{ - At = '1/1/2014' - Job = [pscustomobject]@{ - JobTriggers = @( - [pscustomobject]@{ - At = [pscustomobject]@{ - Value = [datetime]::Parse('1/1/2014') - HasValue = $true - } - } - ) - } - IsValid = $true - } - - Test-JobTriggerAtTime - - It 'should return true ' { - $script:TargetResource.IsValid | should be ($true) - } - } - - Context 'when job At time does not match configured At time' { - $script:TargetResource = [pscustomobject]@{ - At = '1/1/2014' - Job = [pscustomobject]@{ - JobTriggers = @( - [pscustomobject]@{ - At = [pscustomobject]@{ - Value = [datetime]::Parse('2/1/2014') - HasValue = $true - } - } - ) - } - IsValid = $true - } - - Test-JobTriggerAtTime - - It 'should return false ' { - $script:TargetResource.IsValid | should be ($false) - } - } -} - -Describe 'how Test-JobFrequency responds' { - context 'when job frequency is once and the requested frequency is once' { - $script:TargetResource = [pscustomobject]@{ - Once = $true - Job = [pscustomobject]@{ - JobTriggers = @( - [pscustomobject]@{ - Frequency = 'once' - } - ) - } - IsValid = $true - } - Test-JobFrequency - it 'should be true' { - $script:TargetResource.IsValid | should be $true - } - } - - context 'when job frequency is once and the requested frequency is daily' { - $script:TargetResource = [pscustomobject]@{ - Daily = $true - Job = [pscustomobject]@{ - JobTriggers = @( - [pscustomobject]@{ - Frequency = 'once' - } - ) - } - IsValid = $true - } - Test-JobFrequency - it 'should be false' { - $script:TargetResource.IsValid | should be $false - } - } - - context 'when job frequency is once and the requested frequency is weekly' { - $script:TargetResource = [pscustomobject]@{ - Weekly = $true - Job = [pscustomobject]@{ - JobTriggers = @( - [pscustomobject]@{ - Frequency = 'once' - } - ) - } - IsValid = $true - } - Test-JobFrequency - it 'should be false' { - $script:TargetResource.IsValid | should be $false - } - } - - context 'when job frequency is daily and the requested frequency is once' { - $script:TargetResource = [pscustomobject]@{ - Once = $true - Job = [pscustomobject]@{ - JobTriggers = @( - [pscustomobject]@{ - Frequency = 'Daily' - } - ) - } - IsValid = $true - } - Test-JobFrequency - it 'should be false' { - $script:TargetResource.IsValid | should be $false - } - } - - context 'when job frequency is daily and the requested frequency is daily' { - $script:TargetResource = [pscustomobject]@{ - Daily = $true - Job = [pscustomobject]@{ - JobTriggers = @( - [pscustomobject]@{ - Frequency = 'Daily' - } - ) - } - IsValid = $true - } - Test-JobFrequency - it 'should be true' { - $script:TargetResource.IsValid | should be $true - } - } - - context 'when job frequency is daily and the requested frequency is weekly' { - $script:TargetResource = [pscustomobject]@{ - Weekly = $true - Job = [pscustomobject]@{ - JobTriggers = @( - [pscustomobject]@{ - Frequency = 'Daily' - } - ) - } - IsValid = $true - } - Test-JobFrequency - it 'should be false' { - $script:TargetResource.IsValid | should be $false - } - } - - context 'when job frequency is weekly and the requested frequency is once' { - $script:TargetResource = [pscustomobject]@{ - Once = $true - Job = [pscustomobject]@{ - JobTriggers = @( - [pscustomobject]@{ - Frequency = 'Weekly' - } - ) - } - IsValid = $true - } - Test-JobFrequency - it 'should be false' { - $script:TargetResource.IsValid | should be $false - } - } - - context 'when job frequency is weekly and the requested frequency is daily' { - $script:TargetResource = [pscustomobject]@{ - Daily = $true - Job = [pscustomobject]@{ - JobTriggers = @( - [pscustomobject]@{ - Frequency = 'Weekly' - } - ) - } - IsValid = $true - } - Test-JobFrequency - it 'should be false' { - $script:TargetResource.IsValid | should be $false - } - } - - context 'when job frequency is weekly and the requested frequency is weekly' { - $script:TargetResource = [pscustomobject]@{ - Weekly = $true - Job = [pscustomobject]@{ - JobTriggers = @( - [pscustomobject]@{ - Frequency = 'Weekly' - } - ) - } - IsValid = $true - } - Test-JobFrequency - it 'should be true' { - $script:TargetResource.IsValid | should be $true - } - } -} - -Describe 'how Test-OnceJobTrigger responds' { - - Context 'when job frequency is Once and set to repeat every hour and a half.' { - $script:TargetResource = [pscustomobject]@{ - Once = $true - Hours = 1 - Minutes = 30 - Job = [pscustomobject]@{ - JobTriggers = @( - [pscustomobject]@{ - Frequency = 'Once' - RepetitionInterval = [pscustomobject]@{ - Value = [pscustomobject]@{ - Hours = 1 - Minutes = 30 - } - HasValue = $true - } - } - ) - } - IsValid = $true - } - - Test-OnceJobTrigger - - It 'should return true' { - $script:TargetResource.IsValid | should be ($true) - } - } - - Context 'when job frequency is Once and set to repeat every hour and a half but should be every two hours' { - $script:TargetResource = [pscustomobject]@{ - Once = $true - Hours = 2 - Minutes = 0 - Job = [pscustomobject]@{ - JobTriggers = @( - [pscustomobject]@{ - Frequency = 'Once' - RepetitionInterval = [pscustomobject]@{ - Value = [pscustomobject]@{ - Hours = 1 - Minutes = 30 - } - HasValue = $true - } - } - ) - } - IsValid = $true - } - - Test-OnceJobTrigger - - It 'should return false' { - $script:TargetResource.IsValid | should be ($false) - } - } - - Context 'when job frequency is Once and repetition interval is null' { - $script:TargetResource = [pscustomobject]@{ - Once = $true - Hours = 2 - Minutes = 0 - Job = [pscustomobject]@{ - JobTriggers = @( - [pscustomobject]@{ - Frequency = 'Once' - RepetitionInterval = [pscustomobject]@{ - Value = $null - HasValue = $false - } - } - ) - } - IsValid = $true - } - - Test-OnceJobTrigger - - It 'should return false' { - $script:TargetResource.IsValid | should be ($false) - } - } -} - -Describe 'how Test-DailyJobTrigger responds' { - Context 'when job frequency is Daily and should have an interval of 1' { - $script:TargetResource = [pscustomobject]@{ - Daily = $true - DaysInterval = 1 - Job = [pscustomobject]@{ - JobTriggers = @( - [pscustomobject]@{ - Frequency = 'Daily' - Interval = 1 - } - ) - } - IsValid = $true - } - - Test-DailyJobTrigger - - It 'should return true ' { - $script:TargetResource.IsValid | should be ($true) - } - } - - Context 'when job frequency is Daily with an interval of 1 and should have an interval of 2' { - $script:TargetResource = [pscustomobject]@{ - Daily = $true - DaysInterval = 2 - Job = [pscustomobject]@{ - JobTriggers = @( - [pscustomobject]@{ - Frequency = 'Daily' - Interval = 1 - } - ) - } - IsValid = $true - } - - Test-DailyJobTrigger - - It 'should return false ' { - $script:TargetResource.IsValid | should be ($false) - } - } -} - -Describe 'how Test-WeeklyJobTrigger responds' { - - Context 'when job frequency is Weekly with days of the week should be Weekly with days of week ' { - $script:TargetResource = [pscustomobject]@{ - Weekly = $true - DaysOfWeek = 'Monday', 'Wednesday', 'Friday' - Job = [pscustomobject]@{ - JobTriggers = @( - [pscustomobject]@{ - Frequency = 'Weekly' - DaysOfWeek = 'Monday', 'Wednesday', 'Friday' - } - ) - } - IsValid = $true - } - - Test-WeeklyJobTrigger - - It 'should return true ' { - $script:TargetResource.IsValid | should be ($true) - } - } - - Context 'when job frequency is Weekly with days of week, but should be Weekly ' { - $script:TargetResource = [pscustomobject]@{ - Weekly = $true - DaysOfWeek = [string[]]@() - Job = [pscustomobject]@{ - JobTriggers = @( - [pscustomobject]@{ - Frequency = 'Weekly' - DaysOfWeek = 'Monday', 'Wednesday', 'Friday' - } - ) - } - IsValid = $true - } - - Test-WeeklyJobTrigger - - It 'should return false ' { - $script:TargetResource.IsValid | should be ($false) - } - } -} - -Describe 'how Test-TargetResource responds' { - Context 'when the job does not exist ' { - Mock -commandName Get-ScheduledJob -mockWith {$null} - - $result = Test-TargetResource -Name Test -FilePath c:\scripts\test.ps1 -Once $true -Hours 1 -Minutes 1 - - It "should call all the mocks" { - Assert-MockCalled -commandName Get-ScheduledJob -times 1 -Exactly - } - It 'should be false' { - $result | should be ($false) - } - } - - Context 'when the job exists but should not ' { - Mock -commandName Get-ScheduledJob -mockWith { - return ([pscustomobject]@{ - FilePath = 'c:\scripts\test2.ps1' - }) - } - - $result = Test-TargetResource -Name Test -FilePath c:\scripts\test.ps1 -Once $true -Hours 1 -Minutes 1 -Ensure Absent - - It "should call Get-ScheduledJob" { - Assert-MockCalled -commandName Get-ScheduledJob -times 1 -Exactly - } - It 'should be false' { - $result | should be ($false) - } - } - - Context 'when the job exists, but the file path is wrong ' { - Mock -commandName Get-ScheduledJob -mockWith { - return ([pscustomobject]@{ - Command = 'c:\scripts\test.ps1' - JobTriggers = ,([pscustomobject]@{ - Frequency = 'Once' - RepetitionInterval = [pscustomobject]@{ - Value = [pscustomobject]@{ - Hours = 1 - Minutes = 30 - } - HasValue = $true - } - }) - }) - } - - $result = Test-TargetResource -Name Test -FilePath c:\scripts\test.ps1 -Once $true -Hours 1 -Minutes 1 - - It 'should be false ' { - $result | should be ($false) - } - } - - Context 'when the job exits exist, and is configured to repeat every hour and a half ' { - - Mock -commandName Get-ScheduledJob -mockWith { - return ([pscustomobject]@{ - Command = 'c:\scripts\test.ps1' - JobTriggers = ,([pscustomobject]@{ - Frequency = 'Once' - RepetitionInterval = [pscustomobject]@{ - Value = [pscustomobject]@{ - Hours = 1 - Minutes = 30 - } - HasValue = $true - } - }) - }) - } - - $result = Test-TargetResource -Name Test -FilePath c:\scripts\test.ps1 -Once $true -Hours 1 -Minutes 30 -At '1/1/2014' - - It 'should be true ' { - $result | should be ($true) - } - } - - Context 'when the job exists, and is configured to repeat every hour and a half ' { - - Mock -commandName Get-ScheduledJob -mockWith { - return ([pscustomobject]@{ - Command = 'c:\scripts\test.ps1' - JobTriggers = ,([pscustomobject]@{ - Frequency = 'Once' - RepetitionInterval = [pscustomobject]@{ - Value = [pscustomobject]@{ - Hours = 1 - Minutes = 30 - } - HasValue = $true - } - }) - }) - } - - $result = Test-TargetResource -Name Test -FilePath c:\scripts\test.ps1 -Once $true -Hours 1 -Minutes 30 -At '1/1/2014' - - It 'should be true ' { - $result | should be ($true) - } - } - - Context 'when the job exists, and is configured to repeat every hour and a half but should be weekly ' { - - Mock -commandName Get-ScheduledJob -mockWith { - return ([pscustomobject]@{ - Command = 'c:\scripts\test.ps1' - JobTriggers = ,([pscustomobject]@{ - Frequency = 'Once' - RepetitionInterval = [pscustomobject]@{ - Value = [pscustomobject]@{ - Hours = 1 - Minutes = 30 - } - HasValue = $true - } - }) - }) - } - - $result = Test-TargetResource -Name Test -FilePath c:\scripts\test.ps1 -weekly $true - It 'should be false ' { - $result | should be ($false) - } - } - - Context 'when the job exists, but should not ' { - Mock -commandName Get-ScheduledJob -mockWith { - return ([pscustomobject]@{ - Command = 'c:\scripts\test.ps1' - JobTriggers = ,([pscustomobject]@{ - Frequency = 'Once' - RepetitionInterval = [pscustomobject]@{ - Value = [pscustomobject]@{ - Hours = 1 - Minutes = 30 - } - HasValue = $true - } - }) - }) - } - - $result = Test-TargetResource -Name Test -FilePath c:\scripts\test.ps1 -Ensure Absent - - It 'should be false ' { - $result | should be ($false) - } - } -} - -<# -Describe 'how Set-TargetResource responds' { - Context 'when ' { - $expected = '' - $result = '' - - It "should call all the mocks" { - Assert-VerifiableMocks - } - It 'should ' { - $result | should be ($expected) - } - - } -} - - -#> diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_ScheduledTask/StackExchange_ScheduledTask.psd1 b/Resources/StackExchangeResources/DSCResources/StackExchange_ScheduledTask/StackExchange_ScheduledTask.psd1 deleted file mode 100644 index 7780be8..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_ScheduledTask/StackExchange_ScheduledTask.psd1 +++ /dev/null @@ -1,98 +0,0 @@ -# -# Module manifest for module 'StackExchange_ScheduledTask' -# -# Generated by: Steven Murawski -# -# Generated on: 1/24/2014 -# - -@{ - -# Script module or binary module file associated with this manifest. -RootModule = 'StackExchange_ScheduledTask.psm1' - -# Version number of this module. -ModuleVersion = '1.0' - -# ID used to uniquely identify this module -GUID = '7d03a6ad-75f7-4b3c-9adb-1ae489e77877' - -# Author of this module -Author = 'Steven Murawski' - -# Company or vendor of this module -CompanyName = 'Stack Exchange' - -# Copyright statement for this module -Copyright = '(c) 2014 Steven Murawski. All rights reserved.' - -# Description of the functionality provided by this module -# Description = '' - -# Minimum version of the Windows PowerShell engine required by this module -# PowerShellVersion = '' - -# Name of the Windows PowerShell host required by this module -# PowerShellHostName = '' - -# Minimum version of the Windows PowerShell host required by this module -# PowerShellHostVersion = '' - -# Minimum version of Microsoft .NET Framework required by this module -# DotNetFrameworkVersion = '' - -# Minimum version of the common language runtime (CLR) required by this module -# CLRVersion = '' - -# Processor architecture (None, X86, Amd64) required by this module -# ProcessorArchitecture = '' - -# Modules that must be imported into the global environment prior to importing this module -# RequiredModules = @() - -# Assemblies that must be loaded prior to importing this module -# RequiredAssemblies = @() - -# Script files (.ps1) that are run in the caller's environment prior to importing this module. -# ScriptsToProcess = @() - -# Type files (.ps1xml) to be loaded when importing this module -# TypesToProcess = @() - -# Format files (.ps1xml) to be loaded when importing this module -# FormatsToProcess = @() - -# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess -# NestedModules = @() - -# Functions to export from this module -FunctionsToExport = 'Get-TargetResource', 'Set-TargetResource', 'Test-TargetResource' - -# Cmdlets to export from this module -CmdletsToExport = '*' - -# Variables to export from this module -VariablesToExport = '*' - -# Aliases to export from this module -AliasesToExport = '*' - -# List of all modules packaged with this module -# ModuleList = @() - -# List of all files packaged with this module -# FileList = @() - -# Private data to pass to the module specified in RootModule/ModuleToProcess -# PrivateData = '' - -# HelpInfo URI of this module -# HelpInfoURI = '' - -# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. -# DefaultCommandPrefix = '' - -} - - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_ScheduledTask/StackExchange_ScheduledTask.psm1 b/Resources/StackExchangeResources/DSCResources/StackExchange_ScheduledTask/StackExchange_ScheduledTask.psm1 deleted file mode 100644 index e19a87a..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_ScheduledTask/StackExchange_ScheduledTask.psm1 +++ /dev/null @@ -1,531 +0,0 @@ - - -function Get-TargetResource -{ - [OutputType([Hashtable])] - param ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $Name, - - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $FilePath, - - [parameter()] - [string] - $At = (Get-Date), - - [parameter()] - [int] - $Hours = 0, - - [parameter()] - [int] - $Minutes = 0, - - [parameter()] - [bool] - $Once = $false, - - [parameter()] - [int] - $DaysInterval, - - [parameter()] - [bool] - $Daily = $false, - - [parameter()] - #[ValidateSet('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')] - [string[]] - $DaysOfWeek, - - [parameter()] - [bool] - $Weekly = $false, - - [parameter()] - [System.Management.Automation.PSCredential] - $Credential = [System.Management.Automation.PSCredential]::Empty, - - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - - $Session = new-pssession -computername $env:computername -Credential $Credential -Authentication CredSSP - $Job =Invoke-Command -Session $Session { Get-ScheduledJob -Name $Name -ErrorAction SilentlyContinue } - - #Needs to return a hashtable that returns the current - #status of the configuration component - - $Configuration = @{ - Name = $Name - } - if ($Job) - { - $Configuration.FilePath = $Job.Command - if ($Job.JobTriggers[0].At.HasValue) - { - $Configuration.At = $job.JobTriggers[0].At.Value.ToString() - } - if ($Job.JobTriggers[0].RepetitionInterval.HasValue) - { - $Configuration.Hours = $Job.JobTriggers[0].RepetitionInterval.Value.Hours - $Configuration.Minutes = $Job.JobTriggers[0].RepetitionInterval.Value.Minutes - } - - if ( 'Once' -like $Job.JobTriggers[0].Frequency ) - { - $Configuration.Once = $true - } - else - { - $Configuration.Once = $false - } - if ( 'Daily' -like $Job.JobTriggers[0].Frequency ) - { - $Configuration.Daily = $true - $Configuration.DaysInterval = $Job.JobTriggers[0].Interval - } - else - { - $Configuration.Daily = $false - } - if ( 'Weekly' -like $Job.JobTriggers[0].Frequency ) - { - $Configuration.Weekly = $true - [string[]]$Configuration.DaysOfWeek = $job.JobTriggers[0].DaysOfWeek - } - else - { - $Configuration.Weekly = $false - } - $Configuration.Ensure = 'Present' - } - else - { - $Configuration.FilePath = $FilePath - $Configuration.Ensure = 'Absent' - } - - return $Configuration -} - -function Set-TargetResource -{ - param ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $Name, - - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $FilePath, - - [parameter()] - [string] - $At = (Get-Date), - - [parameter()] - [int] - $Hours = 0, - - [parameter()] - [int] - $Minutes = 0, - - [parameter()] - [bool] - $Once = $false, - - [parameter()] - [int] - $DaysInterval = 0, - - [parameter()] - [bool] - $Daily = $false, - - [parameter()] - #[ValidateSet('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')] - [string[]] - $DaysOfWeek, - - [parameter()] - [bool] - $Weekly = $false, - - [parameter()] - [System.Management.Automation.PSCredential] - $Credential = [System.Management.Automation.PSCredential]::Empty, - - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - - - - if ($Ensure -like 'Present') - { - - $JobParameters = @{ - Name = $Name - FilePath = $FilePath - #Credential = $credential - MaxResultCount = 10 - } - $JobTriggerParameters = @{} - $JobTriggerParameters.At = $At - if ($Once) - { - $JobTriggerParameters.Once = $true - if (($Hours -gt 0) -or ($Minutes -gt 0)) - { - $JobTriggerParameters.RepetitionInterval = New-TimeSpan -Hours $Hours -Minutes $Minutes - $JobTriggerParameters.RepetitionDuration = [timespan]::MaxValue - } - } - elseif ($Daily) - { - $JobTriggerParameters.Daily = $true - if ($DaysInterval -gt 0) - { - $JobTriggerParameters.DaysInterval = $DaysInterval - } - } - elseif ($Weekly) - { - $JobTriggerParameters.Weekly = $true - if ($DaysOfWeek.count -gt 0) - { - $JobTriggerParameters.DaysOfWeek = $DaysOfWeek - } - } - $JobParameters.Trigger = New-JobTrigger @JobTriggerParameters - Register-ScheduledJob @JobParameters - } - else - { - Write-Verbose "Job $Name removed." - } - -} - -function Test-TargetResource -{ - [OutputType([boolean])] - param ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $Name, - - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $FilePath, - - [parameter()] - [string] - $At = (Get-Date), - - [parameter()] - [int] - $Hours = 0, - - [parameter()] - [int] - $Minutes = 0, - - [parameter()] - [bool] - $Once = $false, - - [parameter()] - [int] - $DaysInterval, - - [parameter()] - [bool] - $Daily = $false, - - [parameter()] - #[ValidateSet('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')] - [string[]] - $DaysOfWeek, - - [parameter()] - [bool] - $Weekly = $false, - - [parameter()] - [System.Management.Automation.PSCredential] - $Credential = [System.Management.Automation.PSCredential]::Empty, - - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - - New-TargetResourceObject @psboundparameters - - if ($script:TargetResource.Ensure -like 'Present') - { - if ($script:TargetResource.Job) - { - Test-JobFilePath - Test-JobTriggerAtTime - Test-JobFrequency - - if ($script:TargetResource.Once) { - Test-OnceJobTrigger - } - if ($script:TargetResource.Daily) { - Test-DailyJobTrigger - } - if ($script:TargetResource.Weekly) { - Test-WeeklyJobTrigger - } - } - else - { - $script:TargetResource.IsValid = $false - Write-Verbose "Unable to find matching job." - } - } - else - { - if ($script:TargetResource.job) - { - $script:TargetResource.IsValid = $false - Write-Verbose "Job should not be present, but is registered." - } - else - { - Write-Verbose "No job found and no job should be present." - } - } - - - return $script:TargetResource.IsValid -} - -$TargetResource = $null -function New-TargetResourceObject { - param ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $Name, - - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $FilePath, - - [parameter()] - [string] - $At = (Get-Date), - - [parameter()] - [int] - $Hours = 0, - - [parameter()] - [int] - $Minutes = 0, - - [parameter()] - [bool] - $Once = $false, - - [parameter()] - [int] - $DaysInterval, - - [parameter()] - [bool] - $Daily = $false, - - [parameter()] - #[ValidateSet('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')] - [string[]] - $DaysOfWeek, - - [parameter()] - [bool] - $Weekly = $false, - - [parameter()] - [System.Management.Automation.PSCredential] - $Credential = [System.Management.Automation.PSCredential]::Empty, - - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - if (-not $psboundparameters.containskey('At')) { - $psboundparameters.Add('At', $At) - } - if (-not $psboundparameters.containskey('Hours')) { - $psboundparameters.Add('Hours', $Hours) - } - if (-not $psboundparameters.containskey('Minutes')) { - $psboundparameters.Add('Minutes', $Minutes) - } - if (-not $psboundparameters.containskey('Once')) { - $psboundparameters.Add('Once', $Once) - } - if (-not $psboundparameters.containskey('Daily')) { - $psboundparameters.Add('Daily', $Daily) - } - if (-not $psboundparameters.containskey('Weekly')) { - $psboundparameters.Add('Weekly', $Weekly) - } - - - $Job = Get-ScheduledJob -Name $Name -ErrorAction SilentlyContinue - if ($Job) { - $psboundparameters.Add('Job', $Job) - } - if (-not $psboundparameters.containskey('Ensure')) { - $psboundparameters.Add('Ensure', $Ensure) - } - $psboundparameters.Add('IsValid', $true) - $script:TargetResource = [pscustomobject]$psboundparameters -} - -function Remove-Job { - param ( - [parameter()] - [string] - $Name, - [parameter()] - [System.Management.Automation.PSCredential] - $Credential = [System.Management.Automation.PSCredential]::Empty - ) - $Session = new-pssession -computername $env:computername -Credential $Credential -Authentication CredSSP - - Invoke-Command -Session $Session { - $Job = Get-ScheduledJob -Name $using:Name -ErrorAction SilentlyContinue - if ($Job) - { - $job | Unregister-ScheduledJob -Force -Confirm:$False - } - } -} - -function Test-JobFilePath { - [cmdletbinding()] - param () - - if ($script:TargetResource.IsValid) { - Write-Verbose "Comparing $($script:TargetResource.FilePath) to $($script:TargetResource.Job.Command)" - $script:TargetResource.IsValid = $script:TargetResource.FilePath -like $script:TargetResource.Job.Command - } - Write-Verbose "Checking Filepath against existing command. Status is $($script:TargetResource.IsValid)." -} - -function Test-JobTriggerAtTime { - [cmdletbinding()] - param () - - $Trigger = $script:TargetResource.job.JobTriggers[0] - if ($script:TargetResource.IsValid) { - if ($Trigger.At.HasValue) { - $script:TargetResource.IsValid = [datetime]::Parse($script:TargetResource.At) -eq $Trigger.At.Value - } - else { - $script:TargetResource.IsValid = $False - } - } - Write-Verbose "Checking Job Trigger At time. Status is $($script:TargetResource.IsValid)." -} - -function Test-JobFrequency { - [cmdletbinding()] - param() - - $Frequency = $script:TargetResource.Job.JobTriggers[0].Frequency - if ($script:TargetResource.Once) { - $script:TargetResource.IsValid = 'Once' -like $Frequency - } - if ($script:TargetResource.Daily) { - $script:TargetResource.IsValid = 'Daily' -like $Frequency - } - if ($script:TargetResource.Weekly) { - $script:TargetResource.IsValid = 'Weekly' -like $Frequency - } -} - -function Test-OnceJobTrigger { - [cmdletbinding()] - param () - - $Trigger = $script:TargetResource.Job.JobTriggers[0] - if ($script:TargetResource.IsValid -and $script:TargetResource.Once) { - if ($Trigger.RepetitionInterval.HasValue) { - $script:TargetResource.IsValid = $script:TargetResource.Hours -eq $Trigger.RepetitionInterval.Value.Hours - $script:TargetResource.IsValid = $script:TargetResource.Minutes -eq $Trigger.RepetitionInterval.Value.Minutes - } - else { - $script:TargetResource.IsValid = $false - } - } - Write-Verbose "Checking Job Trigger repetition is set to Once. Status is $($script:TargetResource.IsValid)." -} - -function Test-DailyJobTrigger { - [cmdletbinding()] - param () - - $Trigger = $script:TargetResource.Job.JobTriggers[0] - if ($script:TargetResource.IsValid -and $script:TargetResource.Daily) { - $script:TargetResource.IsValid = $script:TargetResource.DaysInterval -eq $Trigger.Interval - } - Write-Verbose "Checking Job Trigger repetition is set to Daily. Status is $($script:TargetResource.IsValid)." -} - -function Test-WeeklyJobTrigger -{ - [cmdletbinding()] - param() - - $Trigger = $script:TargetResource.Job.JobTriggers[0] - if ($script:TargetResource.IsValid -and $script:TargetResource.Weekly) { - Test-DaysOfWeekInWeeklyJobTrigger - } - Write-Verbose "Checking Job Trigger repetition is set to Weekly. Status is $($script:TargetResource.IsValid)." -} - -function Test-DaysOfWeekInWeeklyJobTrigger { - [cmdletbinding()] - param() - - if ( $script:TargetResource.DaysOfWeek.Count -eq $Trigger.DaysOfWeek.count ){ - if ($script:TargetResource.DaysOfWeek.count -gt 0) { - foreach ($day in $Trigger.DaysOfWeek) { - if (-not $script:TargetResource.IsValid) { - break - } - $script:TargetResource.IsValid = ($script:TargetResource.DaysOfWeek -contains $day) - } - } - } - else { - $script:TargetResource.IsValid = $false - } -} - - - - - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_ScheduledTask/StackExchange_ScheduledTask.schema.mof b/Resources/StackExchangeResources/DSCResources/StackExchange_ScheduledTask/StackExchange_ScheduledTask.schema.mof deleted file mode 100644 index a5bda85..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_ScheduledTask/StackExchange_ScheduledTask.schema.mof +++ /dev/null @@ -1,18 +0,0 @@ -[ClassVersion("1.0"), FriendlyName("ScheduledTask")] -class StackExchange_ScheduledTask : OMI_BaseResource -{ -[Key] string Name; -[Key] string FilePath; -[write] string At; -[write] sint32 Hours; -[write] sint32 Minutes; -[write] boolean Once; -[write] sint32 DaysInterval; -[write] boolean Daily; -[write] string DaysOfWeek[]; -[write] boolean Weekly; -[write,EmbeddedInstance("MSFT_Credential")] string Credential; -[write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; -}; - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_SetExecutionPolicy/StackExchange_SetExecutionPolicy.psd1 b/Resources/StackExchangeResources/DSCResources/StackExchange_SetExecutionPolicy/StackExchange_SetExecutionPolicy.psd1 deleted file mode 100644 index 0fa826f..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_SetExecutionPolicy/StackExchange_SetExecutionPolicy.psd1 +++ /dev/null @@ -1,98 +0,0 @@ -# -# Module manifest for module 'SetExecutionPolicy' -# -# Generated by: Steven Murawski -# -# Generated on: 12/13/2013 -# - -@{ - -# Script module or binary module file associated with this manifest. -RootModule = 'StackExchange_SetExecutionPolicy.psm1' - -# Version number of this module. -ModuleVersion = '1.7' - -# ID used to uniquely identify this module -GUID = '6ee60831-33c5-46ad-880d-91a9e011cfaa' - -# Author of this module -Author = 'Steven Murawski' - -# Company or vendor of this module -CompanyName = 'Stack Exchange' - -# Copyright statement for this module -Copyright = '(c) 2013 Steven Murawski. All rights reserved.' - -# Description of the functionality provided by this module -# Description = '' - -# Minimum version of the Windows PowerShell engine required by this module -# PowerShellVersion = '' - -# Name of the Windows PowerShell host required by this module -# PowerShellHostName = '' - -# Minimum version of the Windows PowerShell host required by this module -# PowerShellHostVersion = '' - -# Minimum version of Microsoft .NET Framework required by this module -# DotNetFrameworkVersion = '' - -# Minimum version of the common language runtime (CLR) required by this module -# CLRVersion = '' - -# Processor architecture (None, X86, Amd64) required by this module -# ProcessorArchitecture = '' - -# Modules that must be imported into the global environment prior to importing this module -# RequiredModules = @() - -# Assemblies that must be loaded prior to importing this module -# RequiredAssemblies = @() - -# Script files (.ps1) that are run in the caller's environment prior to importing this module. -# ScriptsToProcess = @() - -# Type files (.ps1xml) to be loaded when importing this module -# TypesToProcess = @() - -# Format files (.ps1xml) to be loaded when importing this module -# FormatsToProcess = @() - -# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess -# NestedModules = @() - -# Functions to export from this module -FunctionsToExport = 'Get-TargetResource', 'Test-TargetResource', 'Set-TargetResource' - -# Cmdlets to export from this module -CmdletsToExport = '*' - -# Variables to export from this module -VariablesToExport = '*' - -# Aliases to export from this module -AliasesToExport = '*' - -# List of all modules packaged with this module -# ModuleList = @() - -# List of all files packaged with this module -# FileList = @() - -# Private data to pass to the module specified in RootModule/ModuleToProcess -# PrivateData = '' - -# HelpInfo URI of this module -# HelpInfoURI = '' - -# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. -# DefaultCommandPrefix = '' - -} - - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_SetExecutionPolicy/StackExchange_SetExecutionPolicy.psm1 b/Resources/StackExchangeResources/DSCResources/StackExchange_SetExecutionPolicy/StackExchange_SetExecutionPolicy.psm1 deleted file mode 100644 index 12b231e..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_SetExecutionPolicy/StackExchange_SetExecutionPolicy.psm1 +++ /dev/null @@ -1,124 +0,0 @@ -# Fallback message strings in en-US -DATA localizedData -{ - # same as culture = "en-US" - ConvertFrom-StringData @' - CheckingCurrentExecutionPolicy=Checking for the existing execution policy. - ExecutionPolicyFound=Located an execution policy of {0}. - ExecutionPolicyNotFound=Did not find an execution policy of {0}. - ApplyingExecutionPolicy=Starting to apply {0} as the execution policy. - AppliedExecutionPolicy=Applied {0} as the execution policy. - AnErrorOccurred=An error occurred trying to apply {0} as the execution policy: {1}. - InnerException=Nested error trying to apply {0} as the execution policy: {1}. - DoesNotApply=Absent does not apply to this configuration item. -'@ -} - -if (Test-Path $PSScriptRoot\en-us) -{ - Import-LocalizedData LocalizedData -filename SetExecutionPolicyProvider.psd1 -} - -function Get-TargetResource -{ - [OutputType([Hashtable])] - param ( - [parameter(Mandatory = $true)] - [ValidateSet('Restricted', 'AllSigned', 'RemoteSigned', 'Unrestricted')] - [string] - $Name, - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - - $Configuration = @{ - Name = $Name - } - - Write-Verbose $LocalizedData.CheckingCurrentExecutionPolicy - $CurrentExecutionPolicy = Get-ExecutionPolicy - if ($Name -like $CurrentExecutionPolicy) - { - Write-Verbose ($LocalizedData.ExecutionPolicyFound -f $Name) - $Configuration.Ensure = 'Present' - } - else - { - Write-Verbose ($LocalizedData.ExecutionPolicyNotFound -f $Name) - $Configuration.Ensure = 'Absent' - } - - return $Configuration -} - -function Set-TargetResource -{ - param ( - [parameter(Mandatory = $true)] - [ValidateSet('Restricted', 'AllSigned', 'RemoteSigned', 'Unrestricted')] - [string] - $Name, - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - - if ($Ensure -like 'Present') - { - Write-Verbose ($LocalizedData.ApplyingExecutionPolicy -f $Name) - try - { - Set-ExecutionPolicy -ExecutionPolicy $Name -Force -ErrorAction Stop - Write-Verbose ($LocalizedData.AppliedExecutionPolicy -f $Name) - } - catch - { - $exception = $_ - Write-Verbose ($LocalizedData.AnErrorOccurred -f $name, $exception.message) - while ($exception.InnerException -ne $null) - { - $exception = $exception.InnerException - Write-Verbose ($LocalizedData.InnerException -f $name, $exception.message) - } - } - } - else - { - Write-Verbose $LocalizedData.DoesNotApply - } - - -} - -function Test-TargetResource -{ - [OutputType([boolean])] - param ( - [parameter(Mandatory = $true)] - [ValidateSet('Restricted', 'AllSigned', 'RemoteSigned', 'Unrestricted')] - [string] - $Name, - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - - switch (Get-ExecutionPolicy) - { - {($Name -like $_) -and ($Ensure -like 'Present')} { - Write-Verbose ($LocalizedData.ExecutionPolicyFound -f $name) - return $true - } - - default { - Write-Verbose ($LocalizedData.ExecutionPolicyNotFound -f $Name) - return $false - } - } -} - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_SetExecutionPolicy/StackExchange_SetExecutionPolicy.schema.mof b/Resources/StackExchangeResources/DSCResources/StackExchange_SetExecutionPolicy/StackExchange_SetExecutionPolicy.schema.mof deleted file mode 100644 index 011ea5a..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_SetExecutionPolicy/StackExchange_SetExecutionPolicy.schema.mof +++ /dev/null @@ -1,8 +0,0 @@ -[ClassVersion("1.0.0"), FriendlyName("SetExecutionPolicy")] -class StackExchange_SetExecutionPolicy : OMI_BaseResource -{ - [Key,ValueMap{"Restricted", "AllSigned", "RemoteSigned", "Unrestricted"},Values{"Restricted", "AllSigned", "RemoteSigned", "Unrestricted"}] string Name; - [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; -}; - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_SetExecutionPolicy/StackExchange_en-US/StackExchange_SetExecutionPolicyProvider.psd1 b/Resources/StackExchangeResources/DSCResources/StackExchange_SetExecutionPolicy/StackExchange_en-US/StackExchange_SetExecutionPolicyProvider.psd1 deleted file mode 100644 index f769245..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_SetExecutionPolicy/StackExchange_en-US/StackExchange_SetExecutionPolicyProvider.psd1 +++ /dev/null @@ -1,12 +0,0 @@ -ConvertFrom-StringData @' - CheckingCurrentExecutionPolicy=Checking for the existing execution policy. - ExecutionPolicyFound=Located an execution policy of {0}. - ExecutionPolicyNotFound=Did not find an execution policy of {0}. - ApplyingExecutionPolicy=Starting to apply {0} as the execution policy. - AppliedExecutionPolicy=Applied {0} as the execution policy. - AnErrorOccurred=An error occurred trying to apply {0} as the execution policy: {1}. - InnerException=Nested error trying to apply {0} as the execution policy: {1}. - DoesNotApply=Absent does not apply to this configuration item. -'@ - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_SetExecutionPolicy/StackExchange_en-US/StackExchange_about_SetExecutionPolicy_Resource.txt b/Resources/StackExchangeResources/DSCResources/StackExchange_SetExecutionPolicy/StackExchange_en-US/StackExchange_about_SetExecutionPolicy_Resource.txt deleted file mode 100644 index f0564be..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_SetExecutionPolicy/StackExchange_en-US/StackExchange_about_SetExecutionPolicy_Resource.txt +++ /dev/null @@ -1,16 +0,0 @@ -Syntax - -Pagefile [string] #ResourceName -{ - Name = [string] { Restricted | AllSigned | RemoteSigned | Unrestricted } - - [ Ensure = [string] { Absent | Present } ] -} - -Properties - -Name - The name of the execution policy. - -Ensure - Set this property to "Present" set the named execution policy. Absent does not apply. - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_Timezone/StackExchange_Timezone.psd1 b/Resources/StackExchangeResources/DSCResources/StackExchange_Timezone/StackExchange_Timezone.psd1 deleted file mode 100644 index 508a227..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_Timezone/StackExchange_Timezone.psd1 +++ /dev/null @@ -1,98 +0,0 @@ -# -# Module manifest for module 'Timezone' -# -# Generated by: Steven Murawski -# -# Generated on: 12/13/2013 -# - -@{ - -# Script module or binary module file associated with this manifest. -RootModule = 'StackExchange_Timezone.psm1' - -# Version number of this module. -ModuleVersion = '1.7' - -# ID used to uniquely identify this module -GUID = 'd2b7eb0f-b0e4-493d-a26a-862d65f76900' - -# Author of this module -Author = 'Steven Murawski' - -# Company or vendor of this module -CompanyName = 'Stack Exchange' - -# Copyright statement for this module -Copyright = '(c) 2013 Steven Murawski. All rights reserved.' - -# Description of the functionality provided by this module -# Description = '' - -# Minimum version of the Windows PowerShell engine required by this module -# PowerShellVersion = '' - -# Name of the Windows PowerShell host required by this module -# PowerShellHostName = '' - -# Minimum version of the Windows PowerShell host required by this module -# PowerShellHostVersion = '' - -# Minimum version of Microsoft .NET Framework required by this module -# DotNetFrameworkVersion = '' - -# Minimum version of the common language runtime (CLR) required by this module -# CLRVersion = '' - -# Processor architecture (None, X86, Amd64) required by this module -# ProcessorArchitecture = '' - -# Modules that must be imported into the global environment prior to importing this module -# RequiredModules = @() - -# Assemblies that must be loaded prior to importing this module -# RequiredAssemblies = @() - -# Script files (.ps1) that are run in the caller's environment prior to importing this module. -# ScriptsToProcess = @() - -# Type files (.ps1xml) to be loaded when importing this module -# TypesToProcess = @() - -# Format files (.ps1xml) to be loaded when importing this module -# FormatsToProcess = @() - -# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess -# NestedModules = @() - -# Functions to export from this module -FunctionsToExport = 'Get-TargetResource', 'Test-TargetResource', 'Set-TargetResource' - -# Cmdlets to export from this module -CmdletsToExport = '*' - -# Variables to export from this module -VariablesToExport = '*' - -# Aliases to export from this module -AliasesToExport = '*' - -# List of all modules packaged with this module -# ModuleList = @() - -# List of all files packaged with this module -# FileList = @() - -# Private data to pass to the module specified in RootModule/ModuleToProcess -# PrivateData = '' - -# HelpInfo URI of this module -# HelpInfoURI = '' - -# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. -# DefaultCommandPrefix = '' - -} - - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_Timezone/StackExchange_Timezone.psm1 b/Resources/StackExchangeResources/DSCResources/StackExchange_Timezone/StackExchange_Timezone.psm1 deleted file mode 100644 index a49af23..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_Timezone/StackExchange_Timezone.psm1 +++ /dev/null @@ -1,85 +0,0 @@ - -function Get-TargetResource -{ - [OutputType([Hashtable])] - param ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $Name - ) - - #Needs to return a hashtable that returns the current - #status of the configuration component - - $Configuration = @{ - Name = (tzutil /g) - Ensure = 'Present' - } - - return $Configuration -} - -function Set-TargetResource -{ - param ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $Name, - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - - if ($ensure -like 'Present') - { - tzutil /s "$Name" - } - - -} - -function Test-TargetResource -{ - [OutputType([boolean])] - param ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $Name, - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - - $CurrentTimeZone = tzutil.exe /g - - if ($Ensure -like 'present') - { - if ($Name -like $CurrentTimeZone) - { - return $true - } - else - { - return $false - } - } - else - { - if ($Name -like $CurrentTimeZone) - { - return $false - } - else - { - return $true - } - } - -} - - diff --git a/Resources/StackExchangeResources/DSCResources/StackExchange_Timezone/StackExchange_Timezone.schema.mof b/Resources/StackExchangeResources/DSCResources/StackExchange_Timezone/StackExchange_Timezone.schema.mof deleted file mode 100644 index 003b759..0000000 --- a/Resources/StackExchangeResources/DSCResources/StackExchange_Timezone/StackExchange_Timezone.schema.mof +++ /dev/null @@ -1,8 +0,0 @@ -[ClassVersion("1.0.0"), FriendlyName("Timezone")] -class StackExchange_Timezone : OMI_BaseResource -{ - [Key] string Name; - [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; -}; - - diff --git a/Resources/StackExchangeResources/StackExchangeResources.psd1 b/Resources/StackExchangeResources/StackExchangeResources.psd1 deleted file mode 100644 index 1ecad6d..0000000 --- a/Resources/StackExchangeResources/StackExchangeResources.psd1 +++ /dev/null @@ -1,98 +0,0 @@ -# -# Module manifest for module 'StackExchangeResources' -# -# Generated by: Steven Murawski -# -# Generated on: 1/27/2014 -# - -@{ - -# Script module or binary module file associated with this manifest. -# RootModule = '' - -# Version number of this module. -ModuleVersion = '1.9.10.0' - -# ID used to uniquely identify this module -GUID = '7cec8ec5-91d8-435e-8136-51088d62fbed' - -# Author of this module -Author = 'Steven Murawski' - -# Company or vendor of this module -CompanyName = 'Stack Exchange' - -# Copyright statement for this module -Copyright = '(c) 2014 Steven Murawski. All rights reserved.' - -# Description of the functionality provided by this module -# Description = '' - -# Minimum version of the Windows PowerShell engine required by this module -# PowerShellVersion = '' - -# Name of the Windows PowerShell host required by this module -# PowerShellHostName = '' - -# Minimum version of the Windows PowerShell host required by this module -# PowerShellHostVersion = '' - -# Minimum version of Microsoft .NET Framework required by this module -# DotNetFrameworkVersion = '' - -# Minimum version of the common language runtime (CLR) required by this module -# CLRVersion = '' - -# Processor architecture (None, X86, Amd64) required by this module -# ProcessorArchitecture = '' - -# Modules that must be imported into the global environment prior to importing this module -# RequiredModules = @() - -# Assemblies that must be loaded prior to importing this module -# RequiredAssemblies = @() - -# Script files (.ps1) that are run in the caller's environment prior to importing this module. -# ScriptsToProcess = @() - -# Type files (.ps1xml) to be loaded when importing this module -# TypesToProcess = @() - -# Format files (.ps1xml) to be loaded when importing this module -# FormatsToProcess = @() - -# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess -# NestedModules = @() - -# Functions to export from this module -FunctionsToExport = '*' - -# Cmdlets to export from this module -CmdletsToExport = '*' - -# Variables to export from this module -VariablesToExport = '*' - -# Aliases to export from this module -AliasesToExport = '*' - -# List of all modules packaged with this module -# ModuleList = @() - -# List of all files packaged with this module -# FileList = @() - -# Private data to pass to the module specified in RootModule/ModuleToProcess -# PrivateData = '' - -# HelpInfo URI of this module -# HelpInfoURI = '' - -# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. -# DefaultCommandPrefix = '' - -} - - - diff --git a/Resources/cActiveDirectory/DSCResources/PSHOrg_cADDomain/PSHOrg_cADDomain.psm1 b/Resources/cActiveDirectory/DSCResources/PSHOrg_cADDomain/PSHOrg_cADDomain.psm1 deleted file mode 100644 index a985d7c..0000000 --- a/Resources/cActiveDirectory/DSCResources/PSHOrg_cADDomain/PSHOrg_cADDomain.psm1 +++ /dev/null @@ -1,180 +0,0 @@ -# [Key] String DomainName; -# [Key] String ParentDomainName; -# [Required, EmbeddedInstance("MSFT_Credential")] String DomainAdministratorCredential; -# [write,EmbeddedInstance("MSFT_Credential")] String DnsDelegationCredential; - - -function Get-TargetResource -{ - [OutputType([System.Collections.Hashtable])] - param - ( - [Parameter(Mandatory)] - [String]$DomainName, - - [String]$ParentDomainName, - - [Parameter(Mandatory)] - [PSCredential]$DomainAdministratorCredential, - - [Parameter(Mandatory)] - [PSCredential]$SafemodeAdministratorPassword, - - [PSCredential]$DnsDelegationCredential - ) - - $returnValue = @{ - Name = $DomainName - Ensure = $false - } - - try - { - $fullDomainName = $DomainName - if( $ParentDomainName ) - { - $fullDomainName = $DomainName + "." + $ParentDomainName - } - - Write-Verbose -Message "Resolving $fullDomainName..." - $domain = Get-ADDomain -Identity $fullDomainName -Credential $DomainAdministratorCredential - if( $domain -ne $null ) - { - Write-Verbose -Message "Domain $fullDomainName is present. Looking for DCs" - try - { - $dc = Get-ADDomainController -Identity $env:COMPUTERNAME -Credential $DomainAdministratorCredential - Write-Verbose -Message "Got Domain Controller $($dc.Name) in domain $($dc.Domain). Parent domain was $($dc.ParentDomain), $ParentDomainName was asked for" - if(($dc.Domain -eq $DomainName) -and ( ( !($dc.ParentDomain) -and !($ParentDomainName) ) -or ($dc.ParentDomain -eq $ParentDomainName))) - { - Write-Verbose -Message "Current node $($dc.Name) is already a domain controller for $($dc.Domain). Parent Domain " - $returnValue.Ensure = $true - } - } - catch - { - Write-Verbose -Message "The local computer does not host a domain controller" - } - } - } - catch - { - Write-Verbose -Message "Target Machine is not running AD WS, and hence is not a domain controller" - } - $returnValue -} - - -function Set-TargetResource -{ - param - ( - [Parameter(Mandatory)] - [String]$DomainName, - - [String]$ParentDomainName, - - [Parameter(Mandatory)] - [PSCredential]$DomainAdministratorCredential, - - [Parameter(Mandatory)] - [PSCredential]$SafemodeAdministratorPassword, - - [PSCredential]$DnsDelegationCredential - ) - - $parameters = $PSBoundParameters.Remove("Debug"); - $state = Test-TargetResource @PSBoundParameters - if( $state -eq $true ) - { - Write-Verbose -Message "Already at desired state. Nothing to set." - return - } - - $fullDomainName = $DomainName - if( $ParentDomainName ) - { - $fullDomainName = $DomainName + "." + $ParentDomainName - } - - Write-Verbose -Message "Checking if Domain $fullDomainName is present ..." - # Check if the domain exists - $domain = $null; - try - { - $domain = Get-ADDomain -Identity $fullDomainName -Credential $DomainAdministratorCredential - } - catch - { - } - if( $domain -ne $null ) - { - Write-Error -Message "Domain $DomainName is already present, but is not hosted by this node. Returning error" - throw (new-object -TypeName System.InvalidOperationException -ArgumentList "Domain $Name is already present, but is not hosted by this node") - } - - Write-Verbose -Message "Verified that Domain $DomainName is not already present in the network. Going on to create the domain." - if( ( $ParentDomainName -eq $null ) -or ( $ParentDomainName -eq "" ) ) - { - Write-Verbose -Message "Domain $DomainName is NOT present. Creating Forest $DomainName ..." - - $params = @{ DomainName = $DomainName; SafeModeAdministratorPassword = $SafemodeAdministratorPassword.Password; NoRebootOnCompletion = $true; InstallDns = $true; Force = $true } - if( $DnsDelegationCredential -ne $null ) - { - $params.Add( "DnsDelegationCredential", $DnsDelegationCredential ) - $params.Add( "CreateDnsDelegation", $true ) - } - Install-ADDSForest @params - - Write-Verbose -Message "Created Forest $DomainName" - } - else - { - Write-Verbose -Message "Domain $DomainName is NOT present. Creating domain $DomainName as a child of $ParentDomainName..." - Import-Module -Name ADDSDeployment - $params = @{ NewDomainName = $DomainName; ParentDomainName = $ParentDomainName; DomainType = [Microsoft.DirectoryServices.Deployment.Types.DomainType]::ChildDomain; SafeModeAdministratorPassword = $SafemodeAdministratorPassword.Password; Credential = $DomainAdministratorCredential; NoRebootOnCompletion = $true; InstallDns = $true; Force = $true } - if( $DnsDelegationCredential -ne $null ) - { - $params.Add( "DnsDelegationCredential", $DnsDelegationCredential ) - $params.Add( "CreateDnsDelegation", $true ) - } - Install-ADDSDomain @params - Write-Verbose -Message "Created Domain $DomainName" - } - - Write-Verbose -Message "Indicating to LCM that system needs reboot." - $global:DSCMachineStatus = 1 -} - - -function Test-TargetResource -{ - [OutputType([System.Boolean])] - param - ( - [Parameter(Mandatory)] - [String]$DomainName, - - [String]$ParentDomainName, - - [Parameter(Mandatory)] - [PSCredential]$DomainAdministratorCredential, - - [Parameter(Mandatory)] - [PSCredential]$SafemodeAdministratorPassword, - - [PSCredential]$DnsDelegationCredential - ) - try - { - $parameters = $PSBoundParameters.Remove("Debug"); - $existingResource = Get-TargetResource @PSBoundParameters - $existingResource.Ensure - } - # If the domain doesn't exist - catch - { - Write-Verbose -Message "Domain $Name is NOT present on the node" - $false - } -} diff --git a/Resources/cActiveDirectory/DSCResources/PSHOrg_cADDomain/PSHOrg_cADDomain.schema.mof b/Resources/cActiveDirectory/DSCResources/PSHOrg_cADDomain/PSHOrg_cADDomain.schema.mof deleted file mode 100644 index 36fc575..0000000 --- a/Resources/cActiveDirectory/DSCResources/PSHOrg_cADDomain/PSHOrg_cADDomain.schema.mof +++ /dev/null @@ -1,9 +0,0 @@ -[ClassVersion("1.0.0.0"), FriendlyName("cADDomain")] -class PSHOrg_cADDomain : OMI_BaseResource -{ - [Key] String DomainName; - [write] String ParentDomainName; - [Required, EmbeddedInstance("MSFT_Credential")] String DomainAdministratorCredential; - [Required, EmbeddedInstance("MSFT_Credential")] String SafemodeAdministratorPassword; - [write,EmbeddedInstance("MSFT_Credential")] String DnsDelegationCredential; -}; diff --git a/Resources/cActiveDirectory/DSCResources/PSHOrg_cADDomainController/PSHOrg_cADDomainController.psm1 b/Resources/cActiveDirectory/DSCResources/PSHOrg_cADDomainController/PSHOrg_cADDomainController.psm1 deleted file mode 100644 index fd47fb1..0000000 --- a/Resources/cActiveDirectory/DSCResources/PSHOrg_cADDomainController/PSHOrg_cADDomainController.psm1 +++ /dev/null @@ -1,135 +0,0 @@ -function Get-TargetResource -{ - [OutputType([System.Collections.Hashtable])] - param - ( - [Parameter(Mandatory)] - [String]$DomainName, - - [Parameter(Mandatory)] - [PSCredential]$DomainAdministratorCredential, - - [Parameter(Mandatory)] - [PSCredential]$SafemodeAdministratorPassword - ) - - $returnValue = @{ - Name = $DomainName - Ensure = $false - } - - try - { - Write-Verbose -Message "Resolving $DomainName..." - $domain = Get-ADDomain -Identity $DomainName -Credential $DomainAdministratorCredential - if( $domain -ne $null ) - { - Write-Verbose -Message "Domain $DomainName is present. Looking for DCs" - try - { - $dc = Get-ADDomainController -Identity $env:COMPUTERNAME -Credential $DomainAdministratorCredential - Write-Verbose -Message "Got Domain Controller $($dc.Name) in domain $($dc.Domain)." - if($dc.Domain -eq $DomainName) - { - Write-Verbose -Message "Current node $($dc.Name) is already a domain controller for $($dc.Domain)." - $returnValue.Ensure = $true - } - } - catch - { - Write-Verbose -Message "No domain controllers could be contacted for $DomainName" - } - } - } - catch - { - Write-Error -Message "Target Machine is not running AD WS, and hence is not a domain controller" - throw $_ - } - $returnValue -} - - -function Set-TargetResource -{ - param - ( - [Parameter(Mandatory)] - [String]$DomainName, - - [Parameter(Mandatory)] - [PSCredential]$DomainAdministratorCredential, - - [Parameter(Mandatory)] - [PSCredential]$SafemodeAdministratorPassword - ) - - $parameters = $PSBoundParameters.Remove("Debug"); - $state = Test-TargetResource @PSBoundParameters - if( $state -eq $true ) - { - Write-Verbose -Message "Already at desired state. Returning." - return - } - - Write-Verbose -Message "Checking if Domain $DomainName is present ..." - # Check if the domain exists - $domain = $null; - try - { - $domain = Get-ADDomain -Identity $DomainName -Credential $DomainAdministratorCredential - } - catch - { - Write-Error -Message "Domain $DomainName could not be found. Assert a domain resource first." - throw (new-object -TypeName System.InvalidOperationException -ArgumentList "Domain $DomainName could not be found.") - } - - Write-Verbose -Message "Verified that Domain $DomainName is present in the network. Going on to create the domain controller." - - $InstallParameters = @{ - DomainName = $DomainName - Force = $true - AllowDomainControllerReinstall = $true - Verbose = $false - NoRebootOnCompletion = $true - SafeModeAdministratorPassword = $SafemodeAdministratorPassword.Password - Credential = $DomainAdministratorCredential - } - Install-ADDSDomainController @InstallParameters - - Write-Verbose -Message "Node is now a domain controller for $DomainName" - Write-Verbose -Message "Indicating to LCM that system needs reboot." - $global:DSCMachineStatus = 1 - -} - - -function Test-TargetResource -{ - [OutputType([System.Boolean])] - param - ( - [Parameter(Mandatory)] - [String]$DomainName, - - [Parameter(Mandatory)] - [PSCredential]$DomainAdministratorCredential, - - [Parameter(Mandatory)] - [PSCredential]$SafemodeAdministratorPassword - ) - - try - { - $parameters = $PSBoundParameters.Remove("Debug"); - $existingResource = Get-TargetResource @PSBoundParameters - $existingResource.Ensure - } - # If the domain doesn't exist - catch - { - Write-Error -Message "Domain $DomainName is NOT present on the node" - throw $_ - } -} diff --git a/Resources/cActiveDirectory/DSCResources/PSHOrg_cADDomainController/PSHOrg_cADDomainController.schema.mof b/Resources/cActiveDirectory/DSCResources/PSHOrg_cADDomainController/PSHOrg_cADDomainController.schema.mof deleted file mode 100644 index 0970d5d..0000000 --- a/Resources/cActiveDirectory/DSCResources/PSHOrg_cADDomainController/PSHOrg_cADDomainController.schema.mof +++ /dev/null @@ -1,7 +0,0 @@ -[ClassVersion("1.0.0.0"), FriendlyName("cADDomainController")] -class PSHOrg_cADDomainController : OMI_BaseResource -{ - [Key] String DomainName; - [Required, EmbeddedInstance("MSFT_Credential")] String DomainAdministratorCredential; - [Required, EmbeddedInstance("MSFT_Credential")] String SafemodeAdministratorPassword; -}; \ No newline at end of file diff --git a/Resources/cActiveDirectory/DSCResources/PSHOrg_cADUser/PSHOrg_cADUser.psm1 b/Resources/cActiveDirectory/DSCResources/PSHOrg_cADUser/PSHOrg_cADUser.psm1 deleted file mode 100644 index 818cb7b..0000000 --- a/Resources/cActiveDirectory/DSCResources/PSHOrg_cADUser/PSHOrg_cADUser.psm1 +++ /dev/null @@ -1,220 +0,0 @@ -function Get-TargetResource -{ - param - ( - [Parameter(Mandatory)] - [string]$DomainName, - - [Parameter(Mandatory)] - [string]$UserName, - - [Parameter(Mandatory)] - [PSCredential]$DomainAdministratorCredential, - - [PSCredential]$Password, - - [ValidateSet("Present","Absent")] - [string]$Ensure = "Present" - ) - - try - { - Write-Verbose -Message "Checking if the user $UserName in domain $DomainName is present ..." - $user = Get-AdUser -Identity $UserName -Credential $DomainAdministratorCredential - Write-Verbose -Message "User $UserName in domain $DomainName is present." - $Ensure = "Present" - } - # User not found - catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] - { - Write-Verbose -Message "User $UserName account in domain $DomainName is NOT present" - $Ensure = "Absent" - } - catch - { - Write-Error -Message "Unhandled exception looking up $UserName account in domain $DomainName." - throw $_ - } - - @{ - DomainName = $DomainName - UserName = $UserName - Ensure = $Ensure - } -} - -function Set-TargetResource -{ - param - ( - [Parameter(Mandatory)] - [string]$DomainName, - - [Parameter(Mandatory)] - [string]$UserName, - - [Parameter(Mandatory)] - [PSCredential]$DomainAdministratorCredential, - - [PSCredential]$Password, - - [ValidateSet("Present","Absent")] - [string]$Ensure = "Present" - ) - try - { - ValidateProperties @PSBoundParameters -Apply - } - catch - { - Write-Error -Message "Error setting AD User $UserName in domain $DomainName. $_" - throw $_ - } -} - -function Test-TargetResource -{ - param - ( - [Parameter(Mandatory)] - [string]$DomainName, - - [Parameter(Mandatory)] - [string]$UserName, - - [Parameter(Mandatory)] - [PSCredential]$DomainAdministratorCredential, - - [PSCredential]$Password, - - [ValidateSet("Present","Absent")] - [string]$Ensure = "Present" - ) - - try - { - $parameters = $PSBoundParameters.Remove("Debug"); - ValidateProperties @PSBoundParameters - } - catch - { - Write-Error -Message "Error testing AD User $UserName in domain $DomainName. $_" - throw $_ - } -} - -function ValidateProperties -{ - param - ( - [Parameter(Mandatory)] - [string]$DomainName, - - [Parameter(Mandatory)] - [string]$UserName, - - [Parameter(Mandatory)] - [PSCredential]$DomainAdministratorCredential, - - [PSCredential]$Password, - - [ValidateSet("Present","Absent")] - [string]$Ensure = "Present", - - [Switch]$Apply - ) - - $result = $true - # Check if user exists and if user exists validate the password - try - { - Write-Verbose -Message "Checking if the user $UserName in domain $DomainName is present ..." - $user = Get-AdUser -Identity $UserName -Credential $DomainAdministratorCredential - Write-Verbose -Message "User $UserName in domain $DomainName is present." - - if( $Ensure -eq "Absent" ) - { - if( $Apply ) - { - Remove-ADUser -Identity $UserName -Credential $DomainAdministratorCredential -Confirm:$false - return - } - else - { - return $false - } - } - - if($Apply) - { - # If account is not enabled, enable it. Needed for password validation - If(!($user.Enabled)) - { - Set-AdUser -Identity $UserName -Enabled $true -Credential $DomainAdministratorCredential - Write-Verbose -Message "Enabled $UserName account in domain $DomainName." - } - } - - # If password is specified, check if it is valid - if($Password) - { - Write-Verbose -Message "Checking if the user $UserName password is valid ..." - Add-Type -AssemblyName 'System.DirectoryServices.AccountManagement' - - Write-Verbose -Message "Creating connection to the domain $DomainName ..." - $prnContext = new-object System.DirectoryServices.AccountManagement.PrincipalContext( - "Domain", $DomainName, $DomainAdministratorCredential.UserName, ` - $DomainAdministratorCredential.GetNetworkCredential().Password) - - # This can return true or false - $result = $prnContext.ValidateCredentials($UserName,$Password.GetNetworkCredential().Password) - if($result) - { - Write-Verbose -Message "User $UserName password is valid" - return $true - } - else - { - Write-Verbose -Message "User $UserName password is NOT valid" - if($Apply) - { - Set-AdAccountPassword -Reset -Identity $UserName -NewPassword $Password.Password -Credential $DomainAdministratorCredential - Write-Verbose -Message "User $UserName password has been reset" - } - else - { - return $false - } - } - } - else - { - Write-Verbose -Message "User $UserName account in domain $DomainName is present" - return $true - } - } - # User not found - catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] - { - Write-Verbose -Message "User $UserName account in domain $DomainName is NOT present" - if($Apply) - { - if( $Ensure -ne "Absent" ) - { - $params = @{ Name = $UserName; Enabled = $true; Credential = $DomainAdministratorCredential } - if( $Password ) - { - $params.Add( "AccountPassword", $Password.Password ) - } - New-AdUser @params - Write-Verbose -Message "User $UserName account in domain $DomainName has been created" - } - } - else - { - return ( $Ensure -eq "Absent" ) - } - } -} - -Export-ModuleMember -Function *-TargetResource diff --git a/Resources/cActiveDirectory/DSCResources/PSHOrg_cADUser/PSHOrg_cADUser.schema.mof b/Resources/cActiveDirectory/DSCResources/PSHOrg_cADUser/PSHOrg_cADUser.schema.mof deleted file mode 100644 index d60f848..0000000 --- a/Resources/cActiveDirectory/DSCResources/PSHOrg_cADUser/PSHOrg_cADUser.schema.mof +++ /dev/null @@ -1,9 +0,0 @@ -[ClassVersion("1.0.0"), FriendlyName("cADUser")] -class PSHOrg_cADUser : OMI_BaseResource -{ - [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; - [Key] string DomainName; - [Key] string UserName; - [write,EmbeddedInstance("MSFT_Credential")] string Password; - [required,EmbeddedInstance("MSFT_Credential")] string DomainAdministratorCredential; -}; \ No newline at end of file diff --git a/Resources/cActiveDirectory/DSCResources/PSHOrg_cWaitForADDomain/PSHOrg_cWaitForADDomain.psm1 b/Resources/cActiveDirectory/DSCResources/PSHOrg_cWaitForADDomain/PSHOrg_cWaitForADDomain.psm1 deleted file mode 100644 index c7b397a..0000000 --- a/Resources/cActiveDirectory/DSCResources/PSHOrg_cWaitForADDomain/PSHOrg_cWaitForADDomain.psm1 +++ /dev/null @@ -1,92 +0,0 @@ -function Get-TargetResource -{ - [OutputType([System.Collections.Hashtable])] - param - ( - [Parameter(Mandatory)] - [String]$DomainName, - - [Parameter(Mandatory)] - [PSCredential]$DomainUserCredential, - - [UInt64]$RetryIntervalSec = 10, - - [UInt32]$RetryCount = 5 - ) - - $returnValue = @{ - Name = $Name - DomainUserCredential = $DomainUserCredential.UserName - RetryIntervalSec = $RetryIntervalSec - RetryCount = $RetryCount - } - $returnValue -} - - -function Set-TargetResource -{ - param - ( - [Parameter(Mandatory)] - [String]$DomainName, - - [Parameter(Mandatory)] - [PSCredential]$DomainUserCredential, - - [UInt64]$RetryIntervalSec = 10, - - [UInt32]$RetryCount = 5 - ) - - $domainFound = $false - Write-Verbose -Message "Checking for domain $Name ..." - - for($count = 0; $count -lt $RetryCount; $count++) - { - try - { - $domain = Get-ADDomain -Identity $DomainName -Credential $DomainUserCredential - Write-Verbose -Message "Found domain $DomainName" - $domainFound = $true - break; - } - Catch - { - Write-Verbose -Message "Domain $DomainName not found. Will retry again after $RetryIntervalSec sec" - Start-Sleep -Seconds $RetryIntervalSec - } - } - - if(! $domainFound) {throw "Domain $DomainName not found after $count attempts with $RetryIntervalSec sec interval"} -} - -function Test-TargetResource -{ - [OutputType([System.Boolean])] - param - ( - [Parameter(Mandatory)] - [String]$DomainName, - - [Parameter(Mandatory)] - [PSCredential]$DomainUserCredential, - - [UInt64]$RetryIntervalSec = 10, - - [UInt32]$RetryCount = 5 - ) - - Write-Verbose -Message "Checking for domain $Name ..." - try - { - $domain = Get-ADDomain -Identity $DomainName -Credential $DomainUserCredential - Write-Verbose -Message "Found domain $DomainName" - $true - } - Catch - { - Write-Verbose -Message "Domain $DomainName not found" - $false - } -} \ No newline at end of file diff --git a/Resources/cActiveDirectory/DSCResources/PSHOrg_cWaitForADDomain/PSHOrg_cWaitForADDomain.schema.mof b/Resources/cActiveDirectory/DSCResources/PSHOrg_cWaitForADDomain/PSHOrg_cWaitForADDomain.schema.mof deleted file mode 100644 index 09d7412..0000000 --- a/Resources/cActiveDirectory/DSCResources/PSHOrg_cWaitForADDomain/PSHOrg_cWaitForADDomain.schema.mof +++ /dev/null @@ -1,9 +0,0 @@ -[ClassVersion("1.0.0.0"), FriendlyName("cWaitForADDomain")] -class PSHOrg_cWaitForADDomain : OMI_BaseResource -{ - [Key] String DomainName; - [Required, EmbeddedInstance("MSFT_Credential")] String DomainUserCredential; - [Write] Uint64 RetryIntervalSec; - [Write] Uint32 RetryCount; -}; - diff --git a/Resources/cActiveDirectory/cActiveDirectory.psd1 b/Resources/cActiveDirectory/cActiveDirectory.psd1 deleted file mode 100644 index 40ef20d..0000000 --- a/Resources/cActiveDirectory/cActiveDirectory.psd1 +++ /dev/null @@ -1,34 +0,0 @@ -@{ -# Version number of this module. -ModuleVersion = '1.0.1' - -# ID used to uniquely identify this module -GUID = 'caedd141-8493-4af3-bda0-eef11e9ca2be' - -# Author of this module -Author = 'Microsoft Corporation' - -# Company or vendor of this module -CompanyName = 'Microsoft Corporation' - -# Copyright statement for this module -Copyright = '(c) 2013 Microsoft Corporation. All rights reserved.' - -# Description of the functionality provided by this module -Description = 'Module with DSC Resources for Active Directory' - -# Minimum version of the Windows PowerShell engine required by this module -PowerShellVersion = '4.0' - -# Minimum version of the common language runtime (CLR) required by this module -CLRVersion = '4.0' - -# Functions to export from this module -FunctionsToExport = '*' - -# Cmdlets to export from this module -CmdletsToExport = '*' -} - - - diff --git a/Resources/cComputerManagement/DSCResources/PSHOrg_cComputer/PSHOrg_cComputer.psm1 b/Resources/cComputerManagement/DSCResources/PSHOrg_cComputer/PSHOrg_cComputer.psm1 deleted file mode 100644 index fa0d31a..0000000 --- a/Resources/cComputerManagement/DSCResources/PSHOrg_cComputer/PSHOrg_cComputer.psm1 +++ /dev/null @@ -1,226 +0,0 @@ - -####################################################################### -# The Get-TargetResource cmdlet. -####################################################################### -function Get-TargetResource -{ - param - ( - [parameter(Mandatory)] - [string] $Name, - - [string] $DomainName, - - [PSCredential]$Credential, - - [string] $WorkGroupName - ) - - $convertToCim = New-CimInstance -ClassName MSFT_Credential -Property @{Username=[string]$Credential.UserName; Password=[string]$null} -Namespace root/microsoft/windows/desiredstateconfiguration -ClientOnly - $returnValue = @{ - Name = $env:COMPUTERNAME - DomainName =(gwmi WIN32_ComputerSystem).Domain - Credential = [ciminstance]$convertToCim - WorkGroupName= (gwmi WIN32_ComputerSystem).WorkGroup - } - - $returnValue -} - -######################################################################## -# The Set-TargetResource cmdlet. -######################################################################## -function Set-TargetResource -{ - param - ( - [parameter(Mandatory)] - [string] $Name, - - [string] $DomainName, - - [PSCredential]$Credential, - - [string] $WorkGroupName - - - ) - ValidateDomainWorkGroup -DomainName $DomainName -WorkGroupName $WorkGroupName - - $currName = $env:COMPUTERNAME - - if($Credential) - { - if($DomainName) - { - $currentMachineDomain = (gwmi win32_computersystem).Domain - if($DomainName -eq $currentMachineDomain) - { - #new computer name, stay on the same domain - Rename-Computer -NewName $Name -DomainCredential $Credential -Force - Write-Verbose -Message "Renamed computer to $Name" - } - else - { - if($Name -ne $currName) - { - #New computer name, join to domain - Add-Computer -DomainName $DomainName -Credential $Credential -NewName $Name -Force - Write-Verbose -Message "Renamed computer to $Name and added to the domain $DomainName" - } - else - { - #Same computer name, join to domain - Add-Computer -DomainName $DomainName -Credential $Credential -Force - Write-Verbose -Message "Added computer to Domain $DomainName" - } - } - } - elseif ($WorkGroupName) - { - $currentMachineWorkgroup = (gwmi win32_computersystem).WorkGroup - if($WorkGroupName -eq $currentMachineWorkgroup) - { - #new computer name, stay on the same workgroup - Rename-Computer -NewName $Name - Write-Verbose -Message "Renamed computer to $Name" - } - else - { - if($Name -ne $currName) - { - #New computer name, join to workgroup - Add-Computer -NewName $Name -Credential $Credential -WorkgroupName $WorkGroupName -Force - Write-Verbose -Message "Renamed computer to $Name and addded computer to workgroup $WorkGroupName" - } - else - { - #same computer name, join to workgroup - Add-Computer -WorkGroupName $WorkGroupName -Credential $Credential -Force - Write-Verbose -Message "Added computer to workgroup $WorkGroupName" - } - } - } - #a user neither provides domain nor workgroup - elseif($Name -ne $currName) - { - #Check if the computer is domain-joined or part of a workgroup - $isMachineInDomain = (Get-WmiObject win32_computersystem).PartOfDomain - if($isMachineInDomain) - { - Rename-Computer -NewName $Name -DomainCredential $Credential -Force - Write-Verbose -Message "Renamed computer to $Name" - } - else - { - Rename-Computer -NewName $Name -Force - Write-Verbose -Message "Renamed computer to $Name" - } - } - } - - # must be non domain scenario - change the machine name in the same workgroup or change workgroup name or both - else - { - if($DomainName) - { - throw "Need to specify credentials with domain" - } - if($WorkGroupName) - { - - if($WorkGroupName -eq (Get-WmiObject win32_computersystem).Workgroup) - { - # Same workgroup, new computer name - Rename-Computer -NewName $Name -force - Write-Verbose -Message "Renamed computer to $Name" - } - else - { - if($name -ne $env:COMPUTERNAME) - { - #New workgroup, new name - Add-Computer -WorkgroupName $WorkGroupName -NewName $Name - } - else - { - #New workgroup, same name - Add-Computer -WorkgroupName $WorkGroupName - } - - Write-Verbose -Message "Added computer to workgroup $WorkGroupName" - } - } - else - { - if($Name -ne $env:COMPUTERNAME) - { - #Only if new name is different from the current name - Rename-Computer -NewName $Name - Write-Verbose -Message "Renamed computer to $Name" - } - } - } - - - - # Tell the DSC Engine to restart the machine - $global:DSCMachineStatus = 1 -} - -####################################################################### -# The Test-TargetResource cmdlet. -####################################################################### -function Test-TargetResource -{ - [CmdletBinding()] - param - ( - [parameter(Mandatory)] - [string] $Name, - - [PSCredential]$Credential, - - [string] $DomainName, - - [string] $WorkGroupName - ) - - Write-Verbose -Message "Checking if computer name is $Name" - - $testResult= ($Name -eq $env:COMPUTERNAME) - ValidateDomainWorkGroup -DomainName $DomainName -WorkGroupName $WorkGroupName - $computerSystem =get-WmiObject -Class Win32_ComputerSystem - if($DomainName) - { - if(!($Credential)) - { - throw "Need to specify credentials with domain" - } - Write-Verbose -Message "Checking if domain name is $DomainName" - $testResult= $testResult -and ($DomainName -eq $computerSystem.Domain) - } - elseif($WorkGroupName) - { - Write-Verbose -Message "Checking if workgroup name is $WorkGroupName" - $testResult= $testResult -and ($WorkGroupName -eq $computerSystem.WorkGroup) - } - $testResult -} -####################################################################### -# Validation functions (Not exported) -####################################################################### - -function ValidateDomainWorkGroup -{ - param($DomainName,$WorkGroupName) - if($DomainName -and $WorkGroupName) - { - throw "Only one of either the domain name or the workgroup name can be set! Please edit the configuration to ensure that only one of these properties have a value." - - } -} - - -Export-ModuleMember -Function *-TargetResource - diff --git a/Resources/cComputerManagement/DSCResources/PSHOrg_cComputer/PSHOrg_cComputer.schema.mof b/Resources/cComputerManagement/DSCResources/PSHOrg_cComputer/PSHOrg_cComputer.schema.mof deleted file mode 100644 index 8813352..0000000 --- a/Resources/cComputerManagement/DSCResources/PSHOrg_cComputer/PSHOrg_cComputer.schema.mof +++ /dev/null @@ -1,14 +0,0 @@ - -[ClassVersion("1.0.0"), FriendlyName("cComputer")] -class PSHOrg_cComputer : OMI_BaseResource -{ - [key] string Name; - - [write] string DomainName; - - [write,EmbeddedInstance("MSFT_Credential")] String Credential; - - [write] string WorkGroupName; -}; - - diff --git a/Resources/cComputerManagement/Documentation-cComputer.docx b/Resources/cComputerManagement/Documentation-cComputer.docx deleted file mode 100644 index 789dc72..0000000 Binary files a/Resources/cComputerManagement/Documentation-cComputer.docx and /dev/null differ diff --git a/Resources/cComputerManagement/Examples/Sample_cComputer_ChangeNameAndWorkgroup.ps1 b/Resources/cComputerManagement/Examples/Sample_cComputer_ChangeNameAndWorkgroup.ps1 deleted file mode 100644 index ec078fe..0000000 --- a/Resources/cComputerManagement/Examples/Sample_cComputer_ChangeNameAndWorkgroup.ps1 +++ /dev/null @@ -1,27 +0,0 @@ -# A configuration to change the machine workgroup and its name - -Configuration Sample_cComputer_ChangeNameAndWorkGroup -{ - param - ( - [string[]]$NodeName="localhost", - - [Parameter(Mandatory)] - [string]$MachineName, - - [Parameter(Mandatory)] - [string]$WorkGroupName - ) - - #Import the required DSC Resources - Import-DscResource -Module cComputerManagement - - Node $NodeName - { - cComputer NewNameAndWorkgroup - { - Name = $MachineName - WorkGroupName = $WorkGroupName - } - } -} diff --git a/Resources/cComputerManagement/Examples/Sample_cComputer_ChangeNameInDomain.ps1 b/Resources/cComputerManagement/Examples/Sample_cComputer_ChangeNameInDomain.ps1 deleted file mode 100644 index e8adc0a..0000000 --- a/Resources/cComputerManagement/Examples/Sample_cComputer_ChangeNameInDomain.ps1 +++ /dev/null @@ -1,45 +0,0 @@ -# A configuration to change machine while in the same domain - -Configuration Sample_cComputer_ChangeNameInDomain -{ - param - ( - [string[]]$NodeName="localhost", - - [Parameter(Mandatory)] - [string]$MachineName, - - [Parameter(Mandatory)] - [pscredential]$Credential - ) - - #Import the required DSC Resources - Import-DscResource -Module cComputerManagement - - Node $NodeName - { - cComputer NewName - { - Name = $MachineName - Credential = $Credential # Domain credential - } - } -} - -<#**************************** -To save the credential in plain-text in the mof file, use the following configuration data - -$ConfigData = @{ - AllNodes = @( - @{ - NodeName = "localhost"; - - # Allows credential to be saved in plain-text in the the *.mof instance document. - PSDscAllowPlainTextPassword = $true; - }; - ); - } - -Sample_xComputer_ChangeNameInDomain -ConfigurationData $ConfigData -MachineName -Credential (Get-Credential) - -*****************************#> diff --git a/Resources/cComputerManagement/Examples/Sample_cComputer_ChangeNameInWorkGroup.ps1 b/Resources/cComputerManagement/Examples/Sample_cComputer_ChangeNameInWorkGroup.ps1 deleted file mode 100644 index 6300e8d..0000000 --- a/Resources/cComputerManagement/Examples/Sample_cComputer_ChangeNameInWorkGroup.ps1 +++ /dev/null @@ -1,23 +0,0 @@ -# A configuration to change the machine name within the same workgroup - -configuration Sample_cComputer_ChangeNameInWorkgroup -{ - param - ( - [string[]]$NodeName="localhost", - - [Parameter(Mandatory)] - [string]$MachineName - ) - - #Import the required DSC Resources - Import-DscResource -Module cComputerManagement - - Node $NodeName - { - cComputer NewName - { - Name = $MachineName - } - } -} diff --git a/Resources/cComputerManagement/Examples/Sample_cComputer_DomainToWorkgroup.ps1 b/Resources/cComputerManagement/Examples/Sample_cComputer_DomainToWorkgroup.ps1 deleted file mode 100644 index 909bb32..0000000 --- a/Resources/cComputerManagement/Examples/Sample_cComputer_DomainToWorkgroup.ps1 +++ /dev/null @@ -1,49 +0,0 @@ -# A configuration to move a machine from a Domain to a WorkGroup -- note: a credential is required - -Configuration Sample_cComputer_DomainToWorkgroup -{ - param - ( - [string[]]$NodeName="localhost", - - [Parameter(Mandatory)] - [string]$MachineName, - - [Parameter(Mandatory)] - [string]$WorkGroup, - - [Parameter(Mandatory)] - [pscredential]$Credential - ) - - #Import the required DSC Resources - Import-DscResource -Module cComputerManagement - - Node $NodeName - { - cComputer JoinWorkgroup - { - Name = $MachineName - WorkGroupName = $WorkGroup - Credential = $Credential # Credential to unjoin from domain - } - } -} - -<#**************************** -To save the credential in plain-text in the mof file, use the following configuration data - -$ConfigData = @{ - AllNodes = @( - @{ - NodeName = "localhost"; - - # Allows credential to be saved in plain-text in the the *.mof instance document. - PSDscAllowPlainTextPassword = $true; - }; - ); - } - -Sample_cComputer_DomainToWorkgroup -ConfigurationData $ConfigData -MachineName -credential (Get-Credential) -WorkGroup -****************************#> - diff --git a/Resources/cComputerManagement/Examples/Sample_cComputer_WorkGroupToDomain.ps1 b/Resources/cComputerManagement/Examples/Sample_cComputer_WorkGroupToDomain.ps1 deleted file mode 100644 index fec03e4..0000000 --- a/Resources/cComputerManagement/Examples/Sample_cComputer_WorkGroupToDomain.ps1 +++ /dev/null @@ -1,49 +0,0 @@ -# A simple configuration to join a workgroup computer to a domain - -Configuration Sample_cComputer_WorkgroupToDomain -{ - param - ( - [string[]]$NodeName="localhost", - - [Parameter(Mandatory)] - [string]$MachineName, - - [Parameter(Mandatory)] - [string]$Domain, - - [Parameter(Mandatory)] - [pscredential]$Credential - ) - - #Import the required DSC Resources - Import-DscResource -Module cComputerManagement - - Node $NodeName - { - cComputer JoinDomain - { - Name = $MachineName - DomainName = $Domain - Credential = $Credential # Credential to join to domain - } - } -} - -<#**************************** -To save the credential in plain-text in the mof file, use the following configuration data - -$ConfigData = @{ - AllNodes = @( - @{ - NodeName = "localhost"; - - # Allows credential to be saved in plain-text in the the *.mof instance document. - PSDscAllowPlainTextPassword = $true; - }; - ); - } - -Sample_cComputer_WorkgroupToDomain -ConfigurationData $ConfigData -MachineName -credential (Get-Credential) -Domain -****************************#> - diff --git a/Resources/cComputerManagement/cComputerManagement.psd1 b/Resources/cComputerManagement/cComputerManagement.psd1 deleted file mode 100644 index 7b28d35..0000000 --- a/Resources/cComputerManagement/cComputerManagement.psd1 +++ /dev/null @@ -1,32 +0,0 @@ -@{ -# Version number of this module. -ModuleVersion = '1.0' - -# ID used to uniquely identify this module -GUID = '41c83857-b8c6-43a2-8568-1b155cddcb85' - -# Author of this module -Author = 'Microsoft Corporation' - -# Company or vendor of this module -CompanyName = 'Microsoft Corporation' - -# Copyright statement for this module -Copyright = '(c) 2013 Microsoft Corporation. All rights reserved.' - -# Description of the functionality provided by this module -Description = 'Module with DSC Resources for Computer Management area' - -# Minimum version of the Windows PowerShell engine required by this module -PowerShellVersion = '4.0' - -# Minimum version of the common language runtime (CLR) required by this module -CLRVersion = '4.0' - -# Functions to export from this module -FunctionsToExport = '*' - -# Cmdlets to export from this module -CmdletsToExport = '*' -} - diff --git a/Resources/cFailOverCluster/DSCResources/PSHOrg_cCluster/PSHOrg_cCluster.psm1 b/Resources/cFailOverCluster/DSCResources/PSHOrg_cCluster/PSHOrg_cCluster.psm1 deleted file mode 100644 index d0b6088..0000000 --- a/Resources/cFailOverCluster/DSCResources/PSHOrg_cCluster/PSHOrg_cCluster.psm1 +++ /dev/null @@ -1,299 +0,0 @@ -# -# xCluster: DSC resource to configure a Windows Cluster. If the cluster does not exist, it will create one in the -# domain and assign the StaticIPAddress to the cluster. Then, it will add current node to the cluster. -# - -# -# The Get-TargetResource cmdlet. -# -function Get-TargetResource -{ - param - ( - [parameter(Mandatory)] - [string] $Name, - - [parameter(Mandatory)] - [string] $StaticIPAddress, - - [parameter(Mandatory)] - [PSCredential] $DomainAdministratorCredential - ) - - $ComputerInfo = Get-WmiObject Win32_ComputerSystem - if (($ComputerInfo -eq $null) -or ($ComputerInfo.Domain -eq $null)) - { - throw "Can't find machine's domain name" - } - - try - { - ($oldToken, $context, $newToken) = ImpersonateAs -cred $DomainAdministratorCredential - $cluster = Get-Cluster -Name $Name -Domain $ComputerInfo.Domain - if ($null -eq $cluster) - { - throw "Can't find the cluster $Name" - } - - $address = Get-ClusterGroup -Cluster $Name -Name "Cluster IP Address" | Get-ClusterParameter "Address" - } - finally - { - if ($context) - { - $context.Undo() - $context.Dispose() - CloseUserToken($newToken) - } - } - - $retvalue = @{ - Name = $Name - IPAddress = $address.Value - } -} - -# -# The Set-TargetResource cmdlet. -# -function Set-TargetResource -{ - param - ( - [parameter(Mandatory)] - [string] $Name, - - [parameter(Mandatory)] - [string] $StaticIPAddress, - - [parameter(Mandatory)] - [PSCredential] $DomainAdministratorCredential - ) - - $bCreate = $true - - Write-Verbose -Message "Checking if Cluster $Name is present ..." - try - { - $ComputerInfo = Get-WmiObject Win32_ComputerSystem - if (($ComputerInfo -eq $null) -or ($ComputerInfo.Domain -eq $null)) - { - throw "Can't find machine's domain name" - } - - $cluster = Get-Cluster -Name $Name -Domain $ComputerInfo.Domain - - if ($cluster) - { - $bCreate = $false - } - } - catch - { - $bCreate = $true - - } - - try - { - ($oldToken, $context, $newToken) = ImpersonateAs -cred $DomainAdministratorCredential - - if ($bCreate) - { - Write-Verbose -Message "Cluster $Name is NOT present" - - New-Cluster -Name $Name -Node $env:COMPUTERNAME -StaticAddress $StaticIPAddress -NoStorage -Force - - Write-Verbose -Message "Created Cluster $Name" - } - else - { - Write-Verbose -Message "Add node to Cluster $Name ..." - - Write-Verbose -Message "Add-ClusterNode $env:COMPUTERNAME to cluster $Name" - - $list = Get-ClusterNode -Cluster $Name - foreach ($node in $list) - { - if ($node.Name -eq $env:COMPUTERNAME) - { - if ($node.State -eq "Down") - { - Write-Verbose -Message "node $env:COMPUTERNAME was down, need remove it from the list." - - Remove-ClusterNode $env:COMPUTERNAME -Cluster $Name -Force - } - } - } - - Add-ClusterNode $env:COMPUTERNAME -Cluster $Name - - Write-Verbose -Message "Added node to Cluster $Name" - - } - } - finally - { - if ($context) - { - $context.Undo() - $context.Dispose() - CloseUserToken($newToken) - } - } -} - -# -# Test-TargetResource -# -# The code will check the following in order: -# 1. Is machine in domain? -# 2. Does the cluster exist in the domain? -# 3. Is the machine is in the cluster's nodelist? -# 4. Does the cluster node is UP? -# -# Function will return FALSE if any above is not true. Which causes cluster to be configured. -# -function Test-TargetResource -{ - param - ( - [parameter(Mandatory)] - [string] $Name, - - [parameter(Mandatory)] - [string] $StaticIPAddress, - - [parameter(Mandatory)] - [PSCredential] $DomainAdministratorCredential - ) - - $bRet = $false - - Write-Verbose -Message "Checking if Cluster $Name is present ..." - try - { - - $ComputerInfo = Get-WmiObject Win32_ComputerSystem - if (($ComputerInfo -eq $null) -or ($ComputerInfo.Domain -eq $null)) - { - Write-Verbose -Message "Can't find machine's domain name" - $bRet = $false - } - else - { - try - { - ($oldToken, $context, $newToken) = ImpersonateAs -cred $DomainAdministratorCredential - - $cluster = Get-Cluster -Name $Name -Domain $ComputerInfo.Domain - - Write-Verbose -Message "Cluster $Name is present" - - if ($cluster) - { - Write-Verbose -Message "Checking if the node is in cluster $Name ..." - - $allNodes = Get-ClusterNode -Cluster $Name - - foreach ($node in $allNodes) - { - if ($node.Name -eq $env:COMPUTERNAME) - { - if ($node.State -eq "Up") - { - $bRet = $true - } - else - { - Write-Verbose -Message "Node is in cluster $Name but is NOT up, treat as NOT in cluster." - } - - break - } - } - - if ($bRet) - { - Write-Verbose -Message "Node is in cluster $Name" - } - else - { - Write-Verbose -Message "Node is NOT in cluster $Name" - } - } - } - finally - { - if ($context) - { - $context.Undo() - $context.Dispose() - - CloseUserToken($newToken) - } - } - } - } - catch - { - Write-Verbose -Message "Cluster $Name is NOT present with Error $_.Message" - } - - $bRet -} - - -function Get-ImpersonatetLib -{ - if ($script:ImpersonateLib) - { - return $script:ImpersonateLib - } - - $sig = @' -[DllImport("advapi32.dll", SetLastError = true)] -public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); - -[DllImport("kernel32.dll")] -public static extern Boolean CloseHandle(IntPtr hObject); -'@ - $script:ImpersonateLib = Add-Type -PassThru -Namespace 'Lib.Impersonation' -Name ImpersonationLib -MemberDefinition $sig - - return $script:ImpersonateLib - -} - -function ImpersonateAs([PSCredential] $cred) -{ - [IntPtr] $userToken = [Security.Principal.WindowsIdentity]::GetCurrent().Token - $userToken - $ImpersonateLib = Get-ImpersonatetLib - - $bLogin = $ImpersonateLib::LogonUser($cred.GetNetworkCredential().UserName, $cred.GetNetworkCredential().Domain, $cred.GetNetworkCredential().Password, - 9, 0, [ref]$userToken) - - if ($bLogin) - { - $Identity = New-Object Security.Principal.WindowsIdentity $userToken - $context = $Identity.Impersonate() - } - else - { - throw "Can't Logon as User $cred.GetNetworkCredential().UserName." - } - $context, $userToken -} - -function CloseUserToken([IntPtr] $token) -{ - $ImpersonateLib = Get-ImpersonatetLib - - $bLogin = $ImpersonateLib::CloseHandle($token) - if (!$bLogin) - { - throw "Can't close token" - } -} - - diff --git a/Resources/cFailOverCluster/DSCResources/PSHOrg_cCluster/PSHOrg_cCluster.schema.mof b/Resources/cFailOverCluster/DSCResources/PSHOrg_cCluster/PSHOrg_cCluster.schema.mof deleted file mode 100644 index d7f1b78..0000000 --- a/Resources/cFailOverCluster/DSCResources/PSHOrg_cCluster/PSHOrg_cCluster.schema.mof +++ /dev/null @@ -1,13 +0,0 @@ -#pragma namespace("\\\\.\\root\\microsoft\\windows\\DesiredStateConfiguration") - -[ClassVersion("1.0.0"), FriendlyName("cCluster")] -class PSHOrg_cCluster : OMI_BaseResource -{ - [key, Description("Name of the Cluster")] string Name; - [required, Description("StaticIPAddress of the Cluster")] string StaticIPAddress; - - [required, EmbeddedInstance("MSFT_Credential"), Description("Credential to create the cluster")] - String DomainAdministratorCredential; -}; - - diff --git a/Resources/cFailOverCluster/DSCResources/PSHOrg_cWaitForCluster/PSHOrg_cWaitForCluster.psm1 b/Resources/cFailOverCluster/DSCResources/PSHOrg_cWaitForCluster/PSHOrg_cWaitForCluster.psm1 deleted file mode 100644 index b75f20e..0000000 --- a/Resources/cFailOverCluster/DSCResources/PSHOrg_cWaitForCluster/PSHOrg_cWaitForCluster.psm1 +++ /dev/null @@ -1,123 +0,0 @@ -# -# xWaitForCluster: DSC Resource that will wait for given name of Cluster, it checks the state of the cluster for given # interval until the cluster is found or the number of retries is reached. -# -# - - -# -# The Get-TargetResource cmdlet. -# -function Get-TargetResource -{ - param - ( - [parameter(Mandatory)][string] $Name, - - [UInt64] $RetryIntervalSec = 10, - [UInt32] $RetryCount = 50 - ) - - @{ - Name = $Name - RetryIntervalSec = $RetryIntervalSec - RetryCount = $RetryCount - } -} - -# -# The Set-TargetResource cmdlet. -# -function Set-TargetResource -{ - param - ( - [parameter(Mandatory)][string] $Name, - - [UInt64] $RetryIntervalSec = 10, - [UInt32] $RetryCount = 50 - ) - - $clusterFound = $false - Write-Verbose -Message "Checking for cluster $Name ..." - - for ($count = 0; $count -lt $RetryCount; $count++) - { - try - { - $ComputerInfo = Get-WmiObject Win32_ComputerSystem - if (($ComputerInfo -eq $null) -or ($ComputerInfo.Domain -eq $null)) - { - Write-Verbose -Message "Can't find machine's domain name" - break; - } - - $cluster = Get-Cluster -Name $Name -Domain $ComputerInfo.Domain - - if ($cluster -ne $null) - { - Write-Verbose -Message "Found cluster $Name" - $clusterFound = $true - - break; - } - - } - catch - { - Write-Verbose -Message "Cluster $Name not found. Will retry again after $RetryIntervalSec sec" - } - - Write-Verbose -Message "Cluster $Name not found. Will retry again after $RetryIntervalSec sec" - Start-Sleep -Seconds $RetryIntervalSec - } - - if (! $clusterFound) - { - throw "Cluster $Name not found after $count attempts with $RetryIntervalSec sec interval" - } -} - -# -# The Test-TargetResource cmdlet. -# -function Test-TargetResource -{ - param - ( - [parameter(Mandatory)][string] $Name, - - [UInt64] $RetryIntervalSec = 10, - [UInt32] $RetryCount = 50 - ) - - Write-Verbose -Message "Checking for Cluster $Name ..." - - try - { - $ComputerInfo = Get-WmiObject Win32_ComputerSystem - if (($ComputerInfo -eq $null) -or ($ComputerInfo.Domain -eq $null)) - { - Write-Verbose -Message "Can't find machine's domain name" - $false - } - - $cluster = Get-Cluster -Name $Name -Domain $ComputerInfo.Domain - if ($cluster -eq $null) - { - Write-Verbose -Message "Cluster $Name not found in domain $ComputerInfo.Domain" - $false - } - else - { - Write-Verbose -Message "Found cluster $Name" - $true - } - } - catch - { - Write-Verbose -Message "Cluster $Name not found" - $false - } -} - - diff --git a/Resources/cFailOverCluster/DSCResources/PSHOrg_cWaitForCluster/PSHOrg_cWaitForCluster.schema.mof b/Resources/cFailOverCluster/DSCResources/PSHOrg_cWaitForCluster/PSHOrg_cWaitForCluster.schema.mof deleted file mode 100644 index 0d07048..0000000 --- a/Resources/cFailOverCluster/DSCResources/PSHOrg_cWaitForCluster/PSHOrg_cWaitForCluster.schema.mof +++ /dev/null @@ -1,16 +0,0 @@ -#pragma namespace("\\\\.\\root\\microsoft\\windows\\DesiredStateConfiguration") - -[ClassVersion("1.0.0"), FriendlyName("cWaitForCluster")] -class PSHOrg_cWaitForCluster : OMI_BaseResource -{ - [key, Description("Name of the cluster")] - string Name; - - [Write, Description("Interval to check the cluster existency")] - Uint64 RetryIntervalSec; - - [Write, Description("Maximum number of retries to check cluster existency")] - Uint32 RetryCount; -}; - - diff --git a/Resources/cFailOverCluster/cFailOverCluster.psd1 b/Resources/cFailOverCluster/cFailOverCluster.psd1 deleted file mode 100644 index 5d1d532..0000000 --- a/Resources/cFailOverCluster/cFailOverCluster.psd1 +++ /dev/null @@ -1,19 +0,0 @@ - - -@{ - - -ModuleVersion = '1.1' -GUID = '026e7fd8-06dd-41bc-b373-59366ab18679' - -Author = 'Microsoft Corporation' -CompanyName = 'Microsoft Corporation' -Copyright = '(c) 2014 Microsoft Corporation. All rights reserved.' - -Description = 'Module containing DSC resources used to configure Failover Clusters.' - - - -} - - diff --git a/Resources/cHyper-V/DSCResources/PSHOrg_cVHD/PSHOrg_cVHD.psm1 b/Resources/cHyper-V/DSCResources/PSHOrg_cVHD/PSHOrg_cVHD.psm1 deleted file mode 100644 index e0b1005..0000000 --- a/Resources/cHyper-V/DSCResources/PSHOrg_cVHD/PSHOrg_cVHD.psm1 +++ /dev/null @@ -1,273 +0,0 @@ -function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] - param - ( - [parameter(Mandatory)] - [String]$Name, - - [parameter(Mandatory)] - [String]$Path, - - # Virtual disk format - Vhd or Vhdx - [ValidateSet("Vhd","Vhdx")] - [String]$Generation = "Vhd" - ) - - # Check if Hyper-V module is present for Hyper-V cmdlets - if(!(Get-Module -ListAvailable -Name Hyper-V)) - { - Throw "Please ensure that Hyper-V role is installed with its PowerShell module" - } - - # Construct the full path for the vhdFile - $vhdName = GetNameWithExtension -Name $Name -Generation $Generation - $vhdFilePath = Join-Path -Path $Path -ChildPath $vhdName - Write-Debug -Message "Vhd full path is $vhdFilePath" - - $vhd = Get-VHD -Path $vhdFilePath -ErrorAction SilentlyContinue - @{ - Name = $Name - Path = $Path - ParentPath = $vhd.ParentPath - Generation = $vhd.VhdFormat - Ensure = if($vhd){"Present"}else{"Absent"} - ID = $vhd.DiskIdentifier - Type = $vhd.VhdType - FileSizeBytes = $vhd.FileSize - MaximumSizeBytes = $vhd.Size - IsAttached = $vhd.Attached - } -} - -function Set-TargetResource -{ - [CmdletBinding()] - param - ( - # Name of the VHD File - [parameter(Mandatory)] - [String]$Name, - - # Folder where the VHD will be created - [parameter(Mandatory)] - [String]$Path, - - # Parent VHD file path, for differencing disk - [String]$ParentPath, - - # Size of Vhd to be created - [Uint64]$MaximumSizeBytes, - - # Virtual disk format - Vhd or Vhdx - [ValidateSet("Vhd","Vhdx")] - [String]$Generation = "Vhd", - - # Should the VHD be created or deleted - [ValidateSet("Present","Absent")] - [String]$Ensure = "Present" - ) - - # Check if Hyper-V module is present for Hyper-V cmdlets - if(!(Get-Module -ListAvailable -Name Hyper-V)) - { - Throw "Please ensure that Hyper-V role is installed with its PowerShell module" - } - - # Construct the full path for the vhdFile - $vhdName = GetNameWithExtension -Name $Name -Generation $Generation - $vhdFilePath = Join-Path -Path $Path -ChildPath $vhdName - Write-Debug -Message "Vhd full path is $vhdFilePath" - - Write-Verbose -Message "Checking if $vhdFilePath is $Ensure ..." - - # If vhd should be absent, delete it - if($Ensure -eq "Absent") - { - if (Test-Path $vhdFilePath) - { - Write-Verbose -Message "$vhdFilePath is not $Ensure" - Remove-Item -Path $vhdFilePath -Force -ErrorAction Stop - } - Write-Verbose -Message "$vhdFilePath is $Ensure" - } - - else - { - # Check if the Vhd is present - try - { - $vhd = Get-VHD -Path $vhdFilePath -ErrorAction Stop - - # If this is a differencing disk, check the parent path - if($ParentPath) - { - Write-Verbose -Message "Checking if $vhdFilePath parent path is $ParentPath ..." - - # If the parent path is not set correct, fix it - if($vhd.ParentPath -ne $ParentPath) - { - Write-Verbose -Message "$vhdFilePath parent path is not $ParentPath." - Set-VHD -Path $vhdFilePath -ParentPath $ParentPath - Write-Verbose -Message "$vhdFilePath parent path is now $ParentPath." - } - else - { - Write-Verbose -Message "$vhdFilePath is $Ensure and parent path is set to $ParentPath." - } - } - - # This is a fixed disk, check the size - else - { - Write-Verbose -Message "Checking if $vhdFilePath size is $MaximumSizeBytes ..." - - # If the size is not correct, fix it - if($vhd.Size -ne $MaximumSizeBytes) - { - Write-Verbose -Message "$vhdFilePath size is not $MaximumSizeBytes." - Resize-VHD -Path $vhdFilePath -SizeBytes $MaximumSizeBytes - Write-Verbose -Message "$vhdFilePath size is now $MaximumSizeBytes." - } - else - { - Write-Verbose -Message "$vhdFilePath is $Ensure and size is $MaximumSizeBytes." - } - } - } - - # Vhd file is not present - catch [System.Management.Automation.ActionPreferenceStopException] - { - - Write-Verbose -Message "$vhdFilePath is not $Ensure" - if($ParentPath) - { - $null = New-VHD -Path $vhdFilePath -ParentPath $ParentPath - } - else - { - $null = New-VHD -Path $vhdFilePath -SizeBytes $MaximumSizeBytes - } - Write-Verbose -Message "$vhdFilePath is now $Ensure" - } - - } - -} - -function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Boolean])] - param - ( - # Name of the VHD File - [parameter(Mandatory)] - [String]$Name, - - # Folder where the VHD will be created - [parameter(Mandatory)] - [String]$Path, - - # Parent VHD file path, for differencing disk - [String]$ParentPath, - - # Size of Vhd to be created - [Uint64]$MaximumSizeBytes, - - # Virtual disk format - Vhd or Vhdx - [ValidateSet("Vhd","Vhdx")] - [String]$Generation = "Vhd", - - # Should the VHD be created or deleted - [ValidateSet("Present","Absent")] - [String]$Ensure = "Present" - ) - - #region input validation - - # Check if Hyper-V module is present for Hyper-V cmdlets - if(!(Get-Module -ListAvailable -Name Hyper-V)) - { - Throw "Please ensure that Hyper-V role is installed with its PowerShell module" - } - - if(! ($ParentPath -or $MaximumSizeBytes)) - { - Throw "Either specify ParentPath or MaximumSize property." - } - - if($ParentPath) - { - # Ensure only one value is specified - differencing disk or new disk - if($MaximumSizeBytes) - { - Throw "Cannot specify both ParentPath and MaximumSize. Specify only one and try again." - } - - if(! (Test-Path -Path $ParentPath)) - { - Throw "$ParentPath does not exists" - } - - # Check if the generation matches parenting disk - if($Generation -and ($ParentPath.Split('.')[-1] -ne $Generation)) - { - Throw "Generation $geneartion should match ParentPath extension $($ParentPath.Split('.')[-1])" - } - } - if(!(Test-Path -Path $Path)) - { - Throw "$Path does not exists" - } - - # Construct the full path for the vhdFile - $vhdName = GetNameWithExtension -Name $Name -Generation $Generation - $vhdFilePath = Join-Path -Path $Path -ChildPath $vhdName - Write-Debug -Message "Vhd full path is $vhdFilePath" - - # Add the logic here and at the end return either $true or $false. - $result = Test-VHD -Path $vhdFilePath -ErrorAction SilentlyContinue - Write-Verbose -Message "Vhd $vhdFilePath is present:$result and Ensure is $Ensure" - return ($result -and ($Ensure -eq "Present")) -} - -# Appends the generation to the name provided if it is not part of the name already. -function GetNameWithExtension -{ - param( - # Name of the VHD File - [parameter(Mandatory)] - [String]$Name, - [parameter(Mandatory)] - [String]$Generation ='Vhd' - ) - - # If the name ends with vhd or vhdx don't append the generation to the vhdname. - if ($Name -like '*.vhd' -or $Name -like '*.vhdx') - { - $extension = $Name.Split('.')[-1] - if ($Generation -ne $extension) - { - throw "the extension $extension on the name does match the generation $Generation" - } - else - { - Write-Debug -Message "Vhd full name is $vhdName" - $vhdName = $Name - } - } - else - { - # Append generation to the name - $vhdName = "$Name.$Generation" - Write-Debug -Message "Vhd full name is $vhdName" - } - - return $vhdName -} - -Export-ModuleMember -Function *-TargetResource - diff --git a/Resources/cHyper-V/DSCResources/PSHOrg_cVHD/PSHOrg_cVHD.schema.mof b/Resources/cHyper-V/DSCResources/PSHOrg_cVHD/PSHOrg_cVHD.schema.mof deleted file mode 100644 index ce7fac3..0000000 --- a/Resources/cHyper-V/DSCResources/PSHOrg_cVHD/PSHOrg_cVHD.schema.mof +++ /dev/null @@ -1,15 +0,0 @@ -[ClassVersion("1.0.0"), FriendlyName("cVHD")] -class PSHOrg_cVHD : OMI_BaseResource -{ - [Key, Description("Name of the VHD File")] String Name; - [Key, Description("Folder where the VHD will be created")] String Path; - [Write, Description("Parent VHD file path, for differencing disk")] String ParentPath; - [Write, Description("Maximum size of Vhd to be created")] Uint64 MaximumSizeBytes; - [Write, Description("Virtual disk format - Vhd or Vhdx"), ValueMap{"Vhd","Vhdx"}, Values{"Vhd","Vhdx"}] String Generation; - [Write, Description("Should the VHD be created or deleted"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; - [Read, Description("Virtual Disk Identifier")] String ID; - [Read, Description("Type of Vhd - Dynamic, Fixed, Differencing")] String Type; - [Read, Description("Current size of the VHD")] Uint64 FileSizeBytes; - [Read, Description("Is the VHD attached to a VM or not")] Boolean IsAttached; -}; - diff --git a/Resources/cHyper-V/DSCResources/PSHOrg_cVMHost/PSHOrg_cVMHost.psm1 b/Resources/cHyper-V/DSCResources/PSHOrg_cVMHost/PSHOrg_cVMHost.psm1 deleted file mode 100644 index cbc807d..0000000 --- a/Resources/cHyper-V/DSCResources/PSHOrg_cVMHost/PSHOrg_cVMHost.psm1 +++ /dev/null @@ -1,372 +0,0 @@ -function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] - param - ( - [parameter(Mandatory = $true)] - [System.String] - $VMHost - ) - - if((Get-WindowsFeature -Name Hyper-V).installed){ - $Ensure = $true # if true - } - else { - $Ensure = $false # if false - } - - if ($ensure -eq $true) { - # Check if Hyper-V module is present for Hyper-V cmdlets - $poshHv = [system.boolean]((Get-Module -ListAvailable -Name Hyper-V)) - $vmHostObj = Get-VMHost $VmHost #-ErrorAction SilentlyContinue - } - - $returnValue = @{ - VMHost = [System.String]$vmHostObj.ComputerName - Ensure = [System.String]$Ensure - VirtualDiskPath = [System.String]$vmHostObj.VirtualHardDiskPath - VirtualMachinePath = [System.String]$vmHostObj.VirtualMachinePath - VirtualMachineMigration = [System.String]$vmHostObj.VirtualMachineMigrationEnabled - EnhancedSessionMode = [System.String]$vmHostObj.EnableEnhancedSessionMode - HyperVPowerShell = [System.Boolean]$poshHv - } - - $returnValue -} - - -function Set-TargetResource -{ - [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - [System.String] - $VMHost, - - [ValidateSet("Present","Absent")] - [System.String] - $Ensure, - - [System.String] - $VirtualDiskPath, - - [System.String] - $VirtualMachinePath, - - [ValidateSet("True","False","","0","1")] - [System.String] - $VirtualMachineMigration = 2, - - [ValidateSet("True","False","","0","1")] - [System.String] - $EnhancedSessionMode = 2 - ) - - if($Ensure -eq 'Present') { - - Write-Verbose -Message "Checking if Hyper-V is enabled ..." - if ((Get-WindowsFeature -Name Hyper-V).installed){ - Write-Verbose -Message "The Hyper-V Role is present." - } - else{ - Write-Verbose -Message "Installing the Hyper-V Role ..." - Install-WindowsFeature -Name Hyper-V -IncludeAllSubFeature - $global:DSCMachineStatus = 1 - } - - Write-Verbose -Message "Checking if Hyper-V PowerShell modules are installed ..." - if ((Get-WindowsFeature -Name Hyper-V-PowerShell).installed){ - Write-Verbose "The Hyper-V PowerShell module is present." - } - else { - Write-Verbose -Message "Installing the Hyper-V PowerSehll module ..." - Install-WindowsFeature -Name Hyper-V-PowerShell -IncludeAllSubFeature - } - - - # Do not continue processing if reboot is pending. - if (!$global:DSCMachineStatus -eq 1) { - - $vmHostObj = Get-VMHost $VMHost -ErrorAction SilentlyContinue - - if ($VirtualDiskPath) { - Write-Verbose -Message "Checking if $VirtualDiskPath matches the current configuration ..." - if ($vmHostObj.VirtualHardDiskPath -eq $VirtualDiskPath){ - Write-Verbose -Message "$VirtualDiskPath is correctly set as the default virtual disk path" - } - else { - - Write-Verbose -Message "Desired virtual disk path $VirtualDiskPath does not match current path of $vmHostObj.VirtualHardDiskPath" - - Write-Verbose -Message "Validating the path $VirtualDiskPath ..." - if (!(Test-Path -Path $VirtualDiskPath)) { - Write-Verbose -Message "The path does not already exist. Building the path ..." - - Write-Verbose -Message "Validating the drive letter ..." - try { - - if (Get-Partition -DriveLetter $VirtualDiskPath[0] -ErrorAction SilentlyContinue){ - - Write-Verbose -Message "Drive letter $VirtualDiskPath[0] is valid, creating folder ..." - New-Item -Path $VirtualDiskPath -ItemType Directory - } - } - catch [System.Management.Automation.ActionPreferenceStopException] { - Throw "Drive letter $VirtualDiskPath[0] does not exist on this system. Configuration cannot be applied ..." - } - - } - - if ((Test-Path -Path $VirtualDiskPath)) { - Set-VMHost -VirtualHardDiskPath $VirtualDiskPath - Write-Verbose -Message "Default virtual disk path $vmHostObj.VirtualHardDiskPath matches desired $VirtualDiskPath" - } - else{ - Throw "The path is not valid to store virtual disks." - } - } - } - - - if ($VirtualMachinePath) { - - Write-Verbose -Message "Checking if $VirtualMachinePath matches the current configuration ..." - - if ($vmHostObj.VirtualMachinePath -eq $VirtualMachinePath){ - Write-Verbose -Message "$VirtualMachinePath is correctly set as the default virtual machine path" - } - else { - - Write-Verbose -Message "Desired virtual disk path $VirtualMachinePath does not match current path of $vmHostObj.VirtualMachinePath" - - Write-Verbose -Message "Validating machine configuration path $VirtualMachinePath ..." - if (!(Test-Path -Path $VirtualMachinePath)) { - - Write-Verbose -Message "Validating drive letter $VirtualMachinePath ..." - try { - if (Get-Partition -DriveLetter $VirtualMachinePath[0] -ErrorAction SilentlyContinue){ - Write-Verbose -Message "Drive letter $VirtualMachinePath[0] is valid, creating folder ..." - New-Item -Path $VirtualMachinePath -ItemType Directory - } - } - catch [System.Management.Automation.ActionPreferenceStopException] { - Throw "Drive letter $VirtualMachinePath[0] does not exist on this system. Configuration cannot be applied ..." - } - - } - - if ((Test-Path -Path $VirtualMachinePath)) { - Set-VMHost -VirtualMachinePath $VirtualMachinePath - Write-Verbose -Message "Default virtual disk path $vmHostObj.VirtualMachinePath matches desired $VirtualDiskPath" - } - else{ - Throw "The path is not valid to store virtual machine configurations" - } - } - } - - if ($VirtualMachineMigration -eq $true) { - Write-Verbose -Message "Checking if virtual machine migration is set to True ..." - if ($vmHostObj.VirtualMachineMigrationEnabled -eq $true){ - Write-Verbose -Message "Virtual machine migration is correctly set to $VirtualMachineMigration" - } - else { - Write-Verbose -Message "Enabling virtual machine migration for any network ..." - Set-VMHost -UseAnyNetworkForMigration $true - Enable-VMMigration - } - } - elseif ($VirtualMachineMigration -eq $false) { - if ($vmHostObj.VirtualMachineMigrationEnabled -eq $false){ - Write-Verbose -Message "Virtual machine migration is correctly set to $VirtualMachineMigration" - } - else { - Write-Verbose -Message "Disabling virtual machine migration ..." - Disable-VMMigration - } - } - - if ($EnhancedSessionMode -eq $true) { - Write-Verbose -Message "Checking if virtual machine migration is set to True ..." - if ($vmHostObj.EnableEnhancedSessionMode -eq $true){ - Write-Verbose -Message "Enhanced session mode is correctly set to $EnhancedSessionMode" - } - else { - Write-Verbose -Message "Enabling enhanced session mode ..." - Set-VMHost -EnableEnhancedSessionMode $true - } - } - elseif ($EnhancedSessionMode -eq $false) { - if ($vmHostObj.EnableEnhancedSessionMode -eq $false){ - Write-Verbose -Message "Enhanced session mode is correctly set to $EnhancedSessionMode" - } - else { - Write-Verbose -Message "Disabling enhanced session mode ..." - Set-VMHost -EnableEnhancedSessionMode $false - } - } - } - } - else { # Hyper-V is set to absent - - Write-Verbose -Message "Checking if Hyper-V is enabled ..." - - if ((Get-WindowsFeature -Name Hyper-V).installed){ - - Write-Verbose -Message "Checking if this is Hyper-V Server ..." - - If ((Get-WindowsEdition -Online).Edition -ne 'ServerHyperCore') { - Write-Verbose -Message "Removing the Hyper-V Role ..." - Uninstall-WindowsFeature -Name Hyper-V -IncludeManagementTools - $global:DSCMachineStatus = 1 - } - else { - Write-Verbose -Message "Hyper-V cannot be removed from the Hyper-V Server Edition" - } - } - else{ - Write-Verbose -Message "Hyper-V Role is not installed ..." - } - } -} - - -function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Boolean])] - param - ( - [parameter(Mandatory = $true)] - [System.String] - $VMHost, - - [ValidateSet("Present","Absent")] - [System.String] - $Ensure, - - [System.String] - $VirtualDiskPath, - - [System.String] - $VirtualMachinePath, - - [ValidateSet("True","False","","0","1")] - [System.String] - $VirtualMachineMigration = 2, - - [ValidateSet("True","False","","0","1")] - [System.String] - $EnhancedSessionMode = 2 - ) - - if($Ensure -eq 'Present') { - - Write-Verbose -Message "Checking if Hyper-V is enabled ..." - if ((Get-WindowsFeature -Name Hyper-V).installed){ - Write-Verbose -Message "The Hyper-V Role is present." - Write-Verbose -Message "Checking if Hyper-V PowerShell modules are installed ..." - if ((Get-WindowsFeature -Name Hyper-V-PowerShell).installed){ - Write-Verbose "The Hyper-V PowerShell module is present." - } - else { - Write-Verbose -Message "The Hyper-V PowerShell module is missing. Hyper-V is not properly installed." - Return $false - } - } - else{ - Write-Verbose -Message "The Hyper-V Role is not installed" - Return $false - } - - $vmHostObj = Get-VMHost $VMHost -ErrorAction SilentlyContinue - - if ($VirtualDiskPath) { - Write-Verbose -Message "Checking if $VirtualDiskPath matches the configuration ..." - if ($vmHostObj.VirtualHardDiskPath -eq $VirtualDiskPath){ - Write-Verbose -Message "$VirtualDiskPath is correctly set as the default virtual disk path" - Return $true - } - else { - Write-Verbose -Message "$VirtualDiskPath does not match the current setting of $vmHostObj.VirtualHardDiskPath." - Return $false - } - } - - - if ($VirtualMachinePath) { - Write-Verbose -Message "Checking if $VirtualMachinePath matches the configuration ..." - if ($vmHostObj.VirtualMachinePath -eq $VirtualMachinePath){ - Write-Verbose -Message "$VirtualMachinePath is correctly set as the default virtual machine path" - Return $true - } - else { - Write-Verbose -Message "$VirtualMachinePath is not set as the default virtual machine path" - Return $false - } - } - - if ($VirtualMachineMigration -eq $true) { - Write-Verbose -Message "Checking if virtual machine migration is set to True ..." - if ($vmHostObj.VirtualMachineMigrationEnabled -eq $true){ - Write-Verbose -Message "Virtual machine migration is correctly set to $VirtualMachineMigration" - Return $true - } - else { - Write-Verbose -Message "Virtual machine migration is not set to $VirtualMachineMigration" - Return $false - } - } - elseif ($VirtualMachineMigration -eq $false) { - if ($vmHostObj.VirtualMachineMigrationEnabled -eq $false){ - Write-Verbose -Message "Virtual machine migration is correctly set to $VirtualMachineMigration" - Return $true - } - else { - Write-Verbose -Message "Virtual machine migration is not set to $VirtualMachineMigration" - Return $false - } - } - - if ($EnhancedSessionMode -eq $true) { - Write-Verbose -Message "Checking if virtual machine migration is set to True ..." - if ($vmHostObj.EnableEnhancedSessionMode -eq $true){ - Write-Verbose -Message "Enhanced session mode is correctly set to $EnhancedSessionMode" - Return $true - } - else { - Write-Verbose -Message "Enhanced session mode is not set to $EnhancedSessionMode" - Return $false - } - } - elseif ($EnhancedSessionMode -eq $false) { - if ($vmHostObj.EnableEnhancedSessionMode -eq $false){ - Write-Verbose -Message "Enhanced session mode is correctly set to $EnhancedSessionMode" - Return $true - } - else { - Write-Verbose -Message "Enhanced session mode is not set to $EnhancedSessionMode" - Return $false - } - } - } - else { # Ensure is set to Absent - - Write-Verbose -Message "Checking if Hyper-V is not enabled ..." - if ((Get-WindowsFeature -Name Hyper-V)){ - Write-Verbose -Message "The Hyper-V Role is present." - Return $false - } - else{ - Write-Verbose -Message "The Hyper-V Role is not installed" - Return $true - } - } -} - -Export-ModuleMember -Function *-TargetResource - - - diff --git a/Resources/cHyper-V/DSCResources/PSHOrg_cVMHost/PSHOrg_cVMHost.schema.mof b/Resources/cHyper-V/DSCResources/PSHOrg_cVMHost/PSHOrg_cVMHost.schema.mof deleted file mode 100644 index 803d319..0000000 --- a/Resources/cHyper-V/DSCResources/PSHOrg_cVMHost/PSHOrg_cVMHost.schema.mof +++ /dev/null @@ -1,15 +0,0 @@ - -[ClassVersion("1.0.0.0"), FriendlyName("PSHOrg_cVMHost")] -class PSHOrg_cVMHost : OMI_BaseResource -{ - [Key] String VMHost; - [Write, ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; - [Write] String VirtualDiskPath; - [Write] String VirtualMachinePath; - [Write, ValueMap{"True","False","","0","1"}, Values{"True","False","","0","1"}] String VirtualMachineMigration; - [Write, ValueMap{"True","False","","0","1"}, Values{"True","False","","0","1"}] String EnhancedSessionMode; - [Read] Boolean HyperVPowerShell; -}; - - - diff --git a/Resources/cHyper-V/DSCResources/PSHOrg_cVMHyperV/PSHOrg_cVMHyperV.psm1 b/Resources/cHyper-V/DSCResources/PSHOrg_cVMHyperV/PSHOrg_cVMHyperV.psm1 deleted file mode 100644 index 47c9add..0000000 --- a/Resources/cHyper-V/DSCResources/PSHOrg_cVMHyperV/PSHOrg_cVMHyperV.psm1 +++ /dev/null @@ -1,464 +0,0 @@ -function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] - param - ( - [parameter(Mandatory = $true)] - [String]$Name, - - [parameter(Mandatory = $true)] - [String]$VhdPath - ) - - # Check if Hyper-V module is present for Hyper-V cmdlets - if(!(Get-Module -ListAvailable -Name Hyper-V)) - { - Throw "Please ensure that Hyper-V role is installed with its PowerShell module" - } - - $vmobj = Get-VM -Name $Name -ErrorAction SilentlyContinue - - # Check if 1 or 0 VM with name = $name exist - if($vmobj.count -gt 1) - { - Throw "More than one VM with the name $Name exist." - } - - - @{ - Name = $Name - VhdPath = $vmObj.HardDrives[0].Path - SwitchName = $vmObj.NetworkAdapters[0].SwitchName - State = $vmobj.State - Path = $vmobj.Path - Generation = if($vmobj.Generation -eq 1){"Vhd"}else{"Vhdx"} - StartupMemory = $vmobj.MemoryStartup - MinimumMemory = $vmobj.MemoryMinimum - MaximumMemory = $vmobj.MemoryMaximum - MACAddress = $vmObj.NetWorkAdapters[0].MacAddress - ProcessorCount = $vmobj.ProcessorCount - Ensure = if($vmobj){"Present"}else{"Absent"} - ID = $vmobj.Id - Status = $vmobj.Status - CPUUsage = $vmobj.CPUUsage - MemoryAssigned = $vmobj.MemoryAssigned - Uptime = $vmobj.Uptime - CreationTime = $vmobj.CreationTime - HasDynamicMemory = $vmobj.DynamicMemoryEnabled - NetworkAdapters = $vmobj.NetworkAdapters.IPAddresses - } -} - -function Set-TargetResource -{ - [CmdletBinding()] - param - ( - # Name of the VM - [parameter(Mandatory)] - [String]$Name, - - # VHD associated with the VM - [parameter(Mandatory)] - [String]$VhdPath, - - # Virtual switch associated with the VM - [String]$SwitchName, - - # State of the VM - [ValidateSet("Running","Paused","Off")] - [String]$State = "Off", - - # Folder where the VM data will be stored - [String]$Path, - - # Associated Virtual disk format - Vhd or Vhdx - [ValidateSet("Vhd","Vhdx")] - [String]$Generation = "Vhd", - - # Startup RAM for the VM - [ValidateRange(32MB,17342MB)] - [UInt64]$StartupMemory, - - # Minimum RAM for the VM. This enables dynamic memory - [ValidateRange(32MB,17342MB)] - [UInt64]$MinimumMemory, - - # Maximum RAM for the VM. This enables dynamic memory - [ValidateRange(32MB,1048576MB)] - [UInt64]$MaximumMemory, - - # MAC address of the VM - [String]$MACAddress, - - # Processor count for the VM - [UInt32]$ProcessorCount, - - # Waits for VM to get valid IP address - [Boolean]$WaitForIP, - - # If specified, shutdowns and restarts the VM as needed for property changes - [Boolean]$RestartIfNeeded, - - # Should the VM be created or deleted - [ValidateSet("Present","Absent")] - [String]$Ensure = "Present" - ) - - # Check if Hyper-V module is present for Hyper-V cmdlets - if(!(Get-Module -ListAvailable -Name Hyper-V)) - { - Throw "Please ensure that Hyper-V role is installed with its PowerShell module" - } - - Write-Verbose -Message "Checking if VM $Name exists ..." - $vmObj = Get-VM -Name $Name -ErrorAction SilentlyContinue - - # VM already exists - if($vmObj) - { - Write-Verbose -Message "VM $Name exists" - - # If VM shouldn't be there, stop it and remove it - if($Ensure -eq "Absent") - { - Write-Verbose -Message "VM $Name should be $Ensure" - Get-VM $Name | Stop-VM -Force -Passthru -WarningAction SilentlyContinue | Remove-VM -Force - Write-Verbose -Message "VM $Name is $Ensure" - } - - # If VM is present, check its state, startup memory, minimum memory, maximum memory,processor countand mac address - # One cannot set the VM's vhdpath, path, generation and switchName after creation - else - { - # If the VM is not in right state, set it to right state - if($vmObj.State -ne $State) - { - Write-Verbose -Message "VM $Name is not $State. Expected $State, actual $($vmObj.State)" - SetVMState -Name $Name -State $State -WaitForIP $WaitForIP - Write-Verbose -Message "VM $Name is now $State" - } - - $changeProperty = @{} - # If the VM does not have the right startup memory - if($StartupMemory -and ($vmObj.MemoryStartup -ne $StartupMemory)) - { - Write-Verbose -Message "VM $Name does not have correct startup memory. Expected $StartupMemory, actual $($vmObj.MemoryStartup)" - $changeProperty["MemoryStartup"]=$StartupMemory - } - - # If the VM does not have the right minimum or maximum memory, stop the VM, set the right memory, start the VM - if($MinimumMemory -or $MaximumMemory) - { - $changeProperty["DynamicMemory"]=$true - - if($MinimumMemory -and ($vmObj.Memoryminimum -ne $MinimumMemory)) - { - Write-Verbose -Message "VM $Name does not have correct minimum memory. Expected $MinimumMemory, actual $($vmObj.MemoryMinimum)" - $changeProperty["MemoryMinimum"]=$MinimumMemory - } - if($MaximumMemory -and ($vmObj.Memorymaximum -ne $MaximumMemory)) - { - Write-Verbose -Message "VM $Name does not have correct maximum memory. Expected $MaximumMemory, actual $($vmObj.MemoryMaximum)" - $changeProperty["MemoryMaximum"]=$MaximumMemory - } - } - - # If the VM does not have the right processor count, stop the VM, set the right memory, start the VM - if($ProcessorCount -and ($vmObj.ProcessorCount -ne $ProcessorCount)) - { - Write-Verbose -Message "VM $Name does not have correct processor count. Expected $ProcessorCount, actual $($vmObj.ProcessorCount)" - $changeProperty["ProcessorCount"]=$ProcessorCount - } - - # Stop the VM, set the right properties, start the VM - ChangeVMProperty -Name $Name -VMCommand "Set-VM" -ChangeProperty $changeProperty -WaitForIP $WaitForIP -RestartIfNeeded $RestartIfNeeded - - # If the VM does not have the right MACAddress, stop the VM, set the right MACAddress, start the VM - if($MACAddress -and ($vmObj.NetWorkAdapters.MacAddress -notcontains $MACAddress)) - { - Write-Verbose -Message "VM $Name does not have correct MACAddress. Expected $MACAddress, actual $($vmObj.NetWorkAdapters[0].MacAddress)" - ChangeVMProperty -Name $Name -VMCommand "Set-VMNetworkAdapter" -ChangeProperty @{StaticMacAddress=$MACAddress} -WaitForIP $WaitForIP -RestartIfNeeded $RestartIfNeeded - Write-Verbose -Message "VM $Name now has correct MACAddress." - } - } - } - - # VM is not present, create one - else - { - Write-Verbose -Message "VM $Name does not exists" - if($Ensure -eq "Present") - { - Write-Verbose -Message "Creating VM $Name ..." - - $parameters = @{} - $parameters["Name"] = $Name - $parameters["VHDPath"] = $VhdPath - - # Optional parameters - if($SwitchName){$parameters["SwitchName"]=$SwitchName} - if($Path){$parameters["Path"]=$Path} - if($Generation){$parameters["Generation"]=if($Generation -eq "Vhd"){1}else{2}} - if($StartupMemory){$parameters["MemoryStartupBytes"]=$StartupMemory} - $null = New-VM @parameters - - $parameters = @{} - $parameters["Name"] = $Name - if($MinimumMemory -or $MaximumMemory) - { - $parameters["DynamicMemory"]=$true - if($MinimumMemory){$parameters["MemoryMinimumBytes"]=$MinimumMemory} - if($MaximumMemory){$parameters["MemoryMaximumBytes"]=$MaximumMemory} - } - if($ProcessorCount){$parameters["ProcessorCount"]=$ProcessorCount} - $null = Set-VM @parameters - - if($MACAddress) - { - Set-VMNetworkAdapter -VMName $Name -StaticMacAddress $MACAddress - } - - SetVMState -Name $Name -State $State -WaitForIP $WaitForIP - Write-Verbose -Message "VM $Name created and is $State" - } - } -} - -function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Boolean])] - param - ( - # Name of the VM - [parameter(Mandatory)] - [String]$Name, - - # VHD associated with the VM - [parameter(Mandatory)] - [String]$VhdPath, - - # Virtual switch associated with the VM - [String]$SwitchName, - - # State of the VM - [ValidateSet("Running","Paused","Off")] - [String]$State = "Off", - - # Folder where the VM data will be stored - [String]$Path, - - # Associated Virtual disk format - Vhd or Vhdx - [ValidateSet("Vhd","Vhdx")] - [String]$Generation = "Vhd", - - # Startup RAM for the VM - [ValidateRange(32MB,17342MB)] - [UInt64]$StartupMemory, - - # Minimum RAM for the VM. This enables dynamic memory - [ValidateRange(32MB,17342MB)] - [UInt64]$MinimumMemory, - - # Maximum RAM for the VM. This enables dynamic memory - [ValidateRange(32MB,1048576MB)] - [UInt64]$MaximumMemory, - - # MAC address of the VM - [String]$MACAddress, - - # Processor count for the VM - [UInt32]$ProcessorCount, - - # Waits for VM to get valid IP address - [Boolean]$WaitForIP, - - # If specified, shutdowns and restarts the VM as needed for property changes - [Boolean]$RestartIfNeeded, - - # Should the VM be created or deleted - [ValidateSet("Present","Absent")] - [String]$Ensure = "Present" - ) - - #region input validation - - # Check if Hyper-V module is present for Hyper-V cmdlets - if(!(Get-Module -ListAvailable -Name Hyper-V)) - { - Throw "Please ensure that Hyper-V role is installed with its PowerShell module" - } - - # Check if 1 or 0 VM with name = $name exist - if((Get-VM -Name $Name -ErrorAction SilentlyContinue).count -gt 1) - { - Throw "More than one VM with the name $Name exist." - } - - # Check if $VhdPath exist - if(!(Test-Path $VhdPath)) - { - Throw "$VhdPath does not exists" - } - - # Check if Minimum memory is less than StartUpmemory - if($StartupMemory -and $MinimumMemory -and ($MinimumMemory -gt $StartupMemory)) - { - Throw "MinimumMemory($MinimumMemory) should not be greater than StartupMemory($StartupMemory)" - } - - # Check if Minimum memory is greater than Maximummemory - if($MaximumMemory -and $MinimumMemory -and ($MinimumMemory -gt $MaximumMemory)) - { - Throw "MinimumMemory($MinimumMemory) should not be greater than MaximumMemory($MaximumMemory)" - } - - # Check if Startup memory is greater than Maximummemory - if($MaximumMemory -and $StartupMemory -and ($StartupMemory -gt $MaximumMemory)) - { - Throw "StartupMemory($StartupMemory) should not be greater than MaximumMemory($MaximumMemory)" - } - - # Check if the generation matches the VhdPath extenstion - if($Generation -and ($VhdPath.Split('.')[-1] -ne $Generation)) - { - Throw "Generation $geneartion should match virtual disk extension $($VhdPath.Split('.')[-1])" - } - - # Check if $Path exist - if($Path -and !(Test-Path -Path $Path)) - { - Throw "$Path does not exists" - } - - #endregion - - $result = $false - - try - { - $vmObj = Get-VM -Name $Name -ErrorAction Stop - - if($Ensure -eq "Present") - { - if($vmObj.HardDrives.Path -notcontains $VhdPath){return $false} - if($SwitchName -and ($vmObj.NetworkAdapters.SwitchName -notcontains $SwitchName)){return $false} - if($state -and ($vmObj.State -ne $State)){return $false} - if($StartupMemory -and ($vmObj.MemoryStartup -ne $StartupMemory)){return $false} - if($MACAddress -and ($vmObj.NetWorkAdapters.MacAddress -notcontains $MACAddress)){return $false} - if($ProcessorCount -and ($vmObj.ProcessorCount -ne $ProcessorCount)){return $false} - if($MaximumMemory -and ($vmObj.MemoryMaximum -ne $MaximumMemory)){return $false} - if($MinimumMemory -and ($vmObj.MemoryMinimum -ne $MinimumMemory)){return $false} - - return $true - } - else {return $false} - } - catch [System.Management.Automation.ActionPreferenceStopException] - { - ($Ensure -eq 'Absent') - } -} - -#region Helper function - -function SetVMState -{ - param - ( - [Parameter(Mandatory)] - [String]$Name, - - [Parameter(Mandatory)] - [ValidateSet("Running","Paused","Off")] - [String]$State, - - [Boolean]$WaitForIP - ) - - switch ($State) - { - 'Running' { - $oldState = (Get-VM -Name $Name).State - # If VM is in paused state, use resume-vm to make it running - if($oldState -eq "Paused"){Resume-VM -Name $Name} - # If VM is Off, use start-vm to make it running - elseif ($oldState -eq "Off"){Start-VM -Name $Name} - - if($WaitForIP) { Get-VMIPAddress -Name $Name -Verbose } - } - 'Paused' {if($oldState -ne 'Off'){Suspend-VM -Name $Name}} - 'Off' {Stop-VM -Name $Name -Force -WarningAction SilentlyContinue} - } -} - -function ChangeVMProperty -{ - param - ( - [Parameter(Mandatory)] - [String]$Name, - - [Parameter(Mandatory)] - [String]$VMCommand, - - [Parameter(Mandatory)] - [Hashtable]$ChangeProperty, - - [Boolean]$WaitForIP, - - [Boolean]$RestartIfNeeded - ) - - $vmObj = Get-VM -Name $Name - if($vmObj.state -ne "Off" -and $RestartIfNeeded) - { - SetVMState -Name $Name -State Off - &$VMCommand -Name $Name @ChangeProperty - - # Can not move a off VM to paused, but only to running state - if($vmObj.state -eq "Running") - { - SetVMState -Name $Name -State Running -WaitForIP $WaitForIP - } - - Write-Verbose -Message "VM $Name now has correct properties." - - # Cannot make a paused VM to go back to Paused state after turning Off - if($vmObj.state -eq "Paused") - { - Write-Warning -Message "VM $Name state will be OFF and not Paused" - } - } - elseif($vmObj.state -eq "Off") - { - &$VMCommand -Name $Name @ChangeProperty - Write-Verbose -Message "VM $Name now has correct properties." - } - else - { - Write-Error -Message "Can not change properties for VM $Name in $($vmObj.State) state unless RestartIfNeeded is set to true" - } -} - -function Get-VMIPAddress -{ - param - ( - [Parameter(Mandatory)] - [string]$Name - ) - - while((Get-VMNetworkAdapter -VMName $Name).ipaddresses.count -lt 2) - { - Write-Verbose -Message "Waiting for IP Address for VM $Name ..." -Verbose - Start-Sleep -Seconds 3; - } -} - -#endregion - -Export-ModuleMember -Function *-TargetResource - diff --git a/Resources/cHyper-V/DSCResources/PSHOrg_cVMHyperV/PSHOrg_cVMHyperV.schema.mof b/Resources/cHyper-V/DSCResources/PSHOrg_cVMHyperV/PSHOrg_cVMHyperV.schema.mof deleted file mode 100644 index e19e717..0000000 --- a/Resources/cHyper-V/DSCResources/PSHOrg_cVMHyperV/PSHOrg_cVMHyperV.schema.mof +++ /dev/null @@ -1,28 +0,0 @@ -[ClassVersion("1.0.0"), FriendlyName("cVMHyperV")] -class PSHOrg_cVMHyperV : OMI_BaseResource -{ - [Key, Description("Name of the VM")] String Name; - [Required, Description("VHD associated with the VM")] String VhdPath; - [Write, Description("Virtual switch associated with the VM")] String SwitchName; - [Write, Description("State of the VM"), ValueMap{"Running","Paused","Off"}, Values{"Running","Paused","Off"}] String State; - [Write, Description("Folder where the VM data will be stored")] String Path; - [Write, Description("Associated Virtual disk format - Vhd or Vhdx"), ValueMap{"Vhd","Vhdx"}, Values{"Vhd","Vhdx"}] String Generation; - [Write, Description("Startup RAM for the VM")] Uint64 StartupMemory; - [Write, Description("Minimum RAM for the VM. This enables dynamic memory")] Uint64 MinimumMemory; - [Write, Description("Maximum RAM for the VM. This enable dynamic memory")] Uint64 MaximumMemory; - [Write, Description("MAC address of the VM")] String MACAddress; - [Write, Description("Processor count for the VM")] Uint32 ProcessorCount; - [Write, Description("Waits for VM to get valid IP address")] Boolean WaitForIP; - [Write, Description("If specified, shutdowns and restarts the VM as needed for property changes")] Boolean RestartIfNeeded; - [Write, Description("Should the VM be created or deleted"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; - [Read, Description("VM unique ID")] String ID; - [Read, Description("Status of the VM")] String Status; - [Read, Description("CPU Usage of the VM")] Uint32 CPUUsage; - [Read, Description("Memory assigned to the VM")] Uint64 MemoryAssigned; - [Read, Description("Uptime of the VM")] String Uptime; - [Read, Description("Creation time of the VM")] DateTime CreationTime; - [Read, Description("Does VM has dynamic memory enabled")] Boolean HasDynamicMemory; - [Read, Description("Network adapters of the VM")] String NetworkAdapters[]; -}; - - diff --git a/Resources/cHyper-V/DSCResources/PSHOrg_cVMSwitch/PSHOrg_cVMSwitch.psm1 b/Resources/cHyper-V/DSCResources/PSHOrg_cVMSwitch/PSHOrg_cVMSwitch.psm1 deleted file mode 100644 index c0a26ec..0000000 --- a/Resources/cHyper-V/DSCResources/PSHOrg_cVMSwitch/PSHOrg_cVMSwitch.psm1 +++ /dev/null @@ -1,235 +0,0 @@ -function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] - param - ( - [parameter(Mandatory)] - [String]$Name, - - [parameter(Mandatory)] - [ValidateSet("External","Internal","Private")] - [String]$Type - ) - - # Check if Hyper-V module is present for Hyper-V cmdlets - if(!(Get-Module -ListAvailable -Name Hyper-V)) - { - Throw "Please ensure that Hyper-V role is installed with its PowerShell module" - } - - $switch = Get-VMSwitch -Name $Name -SwitchType $Type -ErrorAction SilentlyContinue - - @{ - Name = $switch.Name - Type = $switch.SwitchType - NetAdapterName = $( if($switch.NetAdapterInterfaceDescription){ - (Get-NetAdapter -InterfaceDescription $switch.NetAdapterInterfaceDescription).Name}) - AllowManagementOS = $switch.AllowManagementOS - Ensure = if($switch){'Present'}else{'Absent'} - Id = $switch.Id - NetAdapterInterfaceDescription = $switch.NetAdapterInterfaceDescription - } -} - - -function Set-TargetResource -{ - [CmdletBinding()] - param - ( - [parameter(Mandatory)] - [String]$Name, - - [parameter(Mandatory)] - [ValidateSet("External","Internal","Private")] - [String]$Type, - - [ValidateNotNullOrEmpty()] - [String]$NetAdapterName, - - [Boolean]$AllowManagementOS, - - [ValidateSet("Present","Absent")] - [String]$Ensure = "Present" - ) - # Check if Hyper-V module is present for Hyper-V cmdlets - if(!(Get-Module -ListAvailable -Name Hyper-V)) - { - Throw "Please ensure that Hyper-V role is installed with its PowerShell module" - } - - if($Ensure -eq 'Present') - { - $switch = (Get-VMSwitch -Name $Name -SwitchType $Type -ErrorAction SilentlyContinue) - - # If switch is present and it is external type, that means it doesn't have right properties (TEST code ensures that) - if($switch -and ($switch.SwitchType -eq 'External')) - { - Write-Verbose -Message "Checking switch $Name NetAdapterInterface ..." - if((Get-NetAdapter -Name $NetAdapterName).InterfaceDescription -ne $switch.NetAdapterInterfaceDescription) - { - Write-Verbose -Message "Removing switch $Name and creating with right netadapter ..." - $switch | Remove-VMSwitch -Force - $parameters = @{} - $parameters["Name"] = $Name - $parameters["NetAdapterName"] = $NetAdapterName - if($AllowManagementOS){$parameters["AllowManagementOS"]=$AllowManagementOS} - $null = New-VMSwitch @parameters - Write-Verbose -Message "Switch $Name has right netadapter $NetAdapterName" - } - else - { - Write-Verbose -Message "Switch $Name has right netadapter $NetAdapterName" - } - - Write-Verbose -Message "Checking switch $Name AllowManagementOS ..." - if($PSBoundParameters.ContainsKey("AllowManagementOS") -and ($switch.AllowManagementOS -ne $AllowManagementOS)) - { - Write-Verbose -Message "Switch $Name AllowManagementOS property is not correct" - $switch | Set-VMSwitch -AllowManagementOS $AllowManagementOS - Write-Verbose -Message "Switch $Name AllowManagementOS property is set to $AllowManagementOS" - } - else - { - Write-Verbose -Message "Switch $Name AllowManagementOS is correctly set" - } - } - - # If the switch is not present, create one - else - { - Write-Verbose -Message "Switch $Name is not $Ensure." - Write-Verbose -Message "Creating Switch ..." - $parameters = @{} - $parameters["Name"] = $Name - if($NetAdapterName) - { - $parameters["NetAdapterName"] = $NetAdapterName - if($AllowManagementOS) - { - $parameters["AllowManagementOS"] = $AllowManagementOS - } - } - else - { - $parameters["SwitchType"] = $Type - } - - $null = New-VMSwitch @parameters - Write-Verbose -Message "Switch $Name is now $Ensure." - } - } - # Ensure is set to "Absent", remove the switch - else - { - Get-VMSwitch $Name -ErrorAction SilentlyContinue | Remove-VMSwitch -Force - } -} - - -function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Boolean])] - param - ( - [parameter(Mandatory)] - [String]$Name, - - [parameter(Mandatory)] - [ValidateSet("External","Internal","Private")] - [String]$Type, - - [ValidateNotNullOrEmpty()] - [String]$NetAdapterName, - - [Boolean]$AllowManagementOS, - - [ValidateSet("Present","Absent")] - [String]$Ensure = "Present" - ) - - #region input validation - - # Check if Hyper-V module is present for Hyper-V cmdlets - if(!(Get-Module -ListAvailable -Name Hyper-V)) - { - Throw "Please ensure that Hyper-V role is installed with its PowerShell module" - } - - If($Type -eq 'External' -and !($NetAdapterName)) - { - Throw "For external switch type, NetAdapterName must be specified" - } - - - If($Type -ne 'External' -and $NetAdapterName) - { - Throw "For Internal or Private switch type, NetAdapterName should not be specified" - } - #endregion - - try - { - # Check if switch exists - Write-Verbose -Message "Checking if Switch $Name is $Ensure ..." - $switch = Get-VMSwitch -Name $Name -SwitchType $Type -ErrorAction Stop - - # If switch exists - if($switch) - { - Write-Verbose -Message "Switch $Name is Present" - # If switch should be present, check the switch type - if($Ensure -eq 'Present') - { - # If switch is the external type, check additional propeties - if($switch.SwitchType -eq 'External') - { - Write-Verbose -Message "Checking if Switch $Name has correct NetAdapterInterface ..." - if((Get-NetAdapter -Name $NetAdapterName -ErrorAction SilentlyContinue).InterfaceDescription -ne $switch.NetAdapterInterfaceDescription) - { - return $false - } - else - { - Write-Verbose -Message "Switch $Name has correct NetAdapterInterface" - } - - if($PSBoundParameters.ContainsKey("AllowManagementOS")) - { - Write-Verbose -Message "Checking if Switch $Name has AllowManagementOS set correctly..." - if(($switch.AllowManagementOS -ne $AllowManagementOS)) - { - return $false - } - else - { - Write-Verbose -Message "Switch $Name has AllowManagementOS set correctly" - } - } - return $true - } - else - { - return $true - } - } - # If switch should be absent, but is there, return $false - else - { - return $false - } - } - } - - # If no switch was present - catch [System.Management.Automation.ActionPreferenceStopException] - { - Write-Verbose -Message "Switch $Name is not Present" - return ($Ensure -eq 'Absent') - } -} - -Export-ModuleMember -Function *-TargetResource - diff --git a/Resources/cHyper-V/DSCResources/PSHOrg_cVMSwitch/PSHOrg_cVMSwitch.schema.mof b/Resources/cHyper-V/DSCResources/PSHOrg_cVMSwitch/PSHOrg_cVMSwitch.schema.mof deleted file mode 100644 index a6b4478..0000000 --- a/Resources/cHyper-V/DSCResources/PSHOrg_cVMSwitch/PSHOrg_cVMSwitch.schema.mof +++ /dev/null @@ -1,14 +0,0 @@ -[ClassVersion("1.0.0.0"), FriendlyName("cVMSwitch")] -class PSHOrg_cVMSwitch : OMI_BaseResource -{ - [Key, Description("Name of the VM Switch")] String Name; - [Key, Description("Type of switch"), ValueMap{"External","Internal","Private"}, Values{"External","Internal","Private"}] String Type; - [Write, Description("Network adapter name for external switch type")] String NetAdapterName; - [Write, Description("Specify is the VM host has access to the physical NIC")] Boolean AllowManagementOS; - [Write, Description("Whether switch should be present or absent"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; - [Read, Description("Unique ID for the switch")] String Id; - [Read, Description("Description of the network interface")] String NetAdapterInterfaceDescription; -}; - - - diff --git a/Resources/cHyper-V/DSCResources/PSHOrg_cVhdFileDirectory/PSHOrg_cVhdFileDirectory.psm1 b/Resources/cHyper-V/DSCResources/PSHOrg_cVhdFileDirectory/PSHOrg_cVhdFileDirectory.psm1 deleted file mode 100644 index 9e8635a..0000000 --- a/Resources/cHyper-V/DSCResources/PSHOrg_cVhdFileDirectory/PSHOrg_cVhdFileDirectory.psm1 +++ /dev/null @@ -1,380 +0,0 @@ - -<# -# Get the current configuration of the machine -# This function is called when you do Get-DscConfiguration after the configuration is set. -#> -function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] - param - ( - [parameter(Mandatory = $true)] - [System.String] - $VhdPath, - - [parameter(Mandatory = $true)] - [Microsoft.Management.Infrastructure.CimInstance[]] - $FileDirectory - ) - - if ( -not (Test-path $VhdPath)) - { - $item = New-CimInstance -ClassName MSFT_FileDirectoryConfiguration -Property @{DestinationPath = $VhdPath; Ensure = "Absent"} -Namespace root/microsoft/windows/desiredstateconfiguration -ClientOnly - - Return @{ - VhdPath = $VhdPath - FileDirectory = $item - } - } - - # Mount VHD. - $mountVHD = EnsureVHDState -Mounted -vhdPath $vhdPath - - $itemsFound = foreach($Item in $FileDirectory) - { - $item = GetItemToCopy -item $item - $mountedDrive = $mountVHD | Get-Disk | Get-Partition | Get-Volume - $letterDrive = "$($mountedDrive.DriveLetter):\" - - # show the drive letters. - Get-PSDrive | Write-Verbose - - $finalPath = Join-Path $letterDrive $item.DestinationPath - - Write-Verbose "Getting the current value at $finalPath ..." - - if (Test-Path $finalPath) - { - New-CimInstance -ClassName MSFT_FileDirectoryConfiguration -Property @{DestinationPath = $finalPath; Ensure = "Present"} -Namespace root/microsoft/windows/desiredstateconfiguration -ClientOnly - } - else - { - New-CimInstance -ClassName MSFT_FileDirectoryConfiguration -Property @{DestinationPath = $finalPath ; Ensure = "Absent"} -Namespace root/microsoft/windows/desiredstateconfiguration -ClientOnly - } - } - - # Dismount VHD. - EnsureVHDState -Dismounted -vhdPath $VhdPath - - # Return the result. - Return @{ - VhdPath = $VhdPath - FileDirectory = $itemsFound - } -} - - -# This is a resource method that gets called if the Test-TargetResource returns false. -function Set-TargetResource -{ - [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - [System.String] - $VhdPath, - - [parameter(Mandatory = $true)] - [Microsoft.Management.Infrastructure.CimInstance[]] - $FileDirectory - ) - - if (-not (Test-Path $VhdPath)) { throw "Specified destination path $VhdPath does not exist!"} - - # mount the VHD. - $mountedVHD = EnsureVHDState -Mounted -vhdPath $VhdPath - - try - { - # show the drive letters. - Get-PSDrive | Write-Verbose - - $mountedDrive = $mountedVHD | Get-Disk | Get-Partition | Get-Volume - - foreach ($item in $FileDirectory) - { - $itemToCopy = GetItemToCopy -item $item - $letterDrive = "$($mountedDrive.DriveLetter):\" - $finalDestinationPath = $letterDrive - $finalDestinationPath = Join-Path $letterDrive $itemToCopy.DestinationPath - - # if the destination should be removed - if (-not($itemToCopy.Ensure)) - { - if (Test-Path $finalDestinationPath) - { - SetVHDFile -destinationPath $finalDestinationPath -ensure:$false -recurse:($itemToCopy.Recurse) - } - } - else - { - # Copy Scenario - if ($itemToCopy.SourcePath) - { - SetVHDFile -sourcePath $itemToCopy.SourcePath -destinationPath $finalDestinationPath -recurse:($itemToCopy.Recurse) -force:($itemToCopy.Force) - } - elseif ($itemToCopy.Content) - { - "Writing a content to a file" - - # if the type is not specified assume it is a file. - if (-not ($itemToCopy.Type)) - { - $itemToCopy.Type = 'File' - } - - # Create file/folder scenario - SetVHDFile -destinationPath $finalDestinationPath -type $itemToCopy.Type -force:($itemToCopy.Force) -content $itemToCopy.Content - } - - # Set Attribute scenario - if ($itemToCopy.Attributes) - { - SetVHDFile -destinationPath $finalDestinationPath -attribute $itemToCopy.Attributes -force:($itemToCopy.Force) - } - } - - } - } - finally - { - EnsureVHDState -Dismounted -vhdPath $VhdPath - } -} - -# This function returns if the current configuration of the machine is the same as the desired configration for this resource. -function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Boolean])] - param - ( - [parameter(Mandatory = $true)] - [System.String] - $VhdPath, - - [parameter(Mandatory = $true)] - [Microsoft.Management.Infrastructure.CimInstance[]] - $FileDirectory - ) - - # If the VHD path does not exist throw an error and stop. - if ( -not (Test-Path $VhdPath)) - { - throw "VHD does not exist in the specified path $VhdPath" - } - - # mount the vhd. - $mountedVHD = EnsureVHDState -Mounted -vhdPath $VhdPath - - try - { - # Show the drive letters after mount - Get-PSDrive | Write-Verbose - - $mountedDrive = $mountedVHD | Get-Disk | Get-Partition | Get-Volume - $letterDrive = "$($mountedDrive.DriveLetter):\" - Write-Verbose $letterDrive - - # return test result equal to true unless one of the tests in the loop below fails. - $result = $true - - foreach ($item in $FileDirectory) - { - $itemToCopy = GetItemToCopy -item $item - $destination = $itemToCopy.DestinationPath - Write-Verbose ("Testing the file with relative VHD destination $destination") - $destination = $itemToCopy.DestinationPath - $finalDestinationPath = $letterDrive - $finalDestinationPath = Join-Path $letterDrive $destination - if (Test-Path $finalDestinationPath) - { - if( -not ($itemToCopy.Ensure)) - { - $result = $false - break; - } - else - { - if (($itemToCopy.Type -eq "Directory") -and ($itemToCopy.Recurse)) - { - # make sure the child also exists. - $allFilesToCopy = dir "$($itemToCopy.SourcePath)\*.*" -Recurse | % FullName | %{$_.Substring(($itemToCopy.SourcePath).Length)} - $allDestinationFiles = dir "$($itemToCopy.DestinationPath)\*.*" -Recurse | % FullName | %{$_.Substring(($itemToCopy.DestinationPath).Length)} - $allFilesToCopy | % { $result = $result -and $allDestinationFiles.Contains($_)} - - if (-not ($result)) - { - break; - } - } - } - } - else - { - # If Ensure is specified as Present or if Ensure is not specified at all. - if(($itemToCopy.Ensure)) - { - $result = $false - break; - } - } - - # Check the attribute - if ($itemToCopy.Attributes) - { - $currentAttribute = @(Get-ItemProperty -Path $finalDestinationPath |% Attributes) - $result = $currentAttribute.Contains($itemToCopy.Attributes) - } - } - } - finally - { - EnsureVHDState -Dismounted -vhdPath $VhdPath - } - - return $result; -} - -# Assert the state of the VHD. -function EnsureVHDState -{ - [CmdletBinding(DefaultParametersetName="Mounted")] - param( - - [parameter(Mandatory=$false,ParameterSetName = "Mounted")] - [switch]$Mounted, - [parameter(Mandatory=$false,ParameterSetName = "Dismounted")] - [switch]$Dismounted, - [parameter(Mandatory=$true)] - $vhdPath - ) - - if ( -not ( Get-Module -ListAvailable Hyper-v)) - { - throw "Hyper-v-Powershell Windows Feature is required to run this resource. Please install Hyper-v feature and try again" - } - if ($PSCmdlet.ParameterSetName -eq 'Mounted') - { - # Try mounting the VHD. - $mountedVHD = Mount-VHD -Path $vhdPath -Passthru -ErrorAction SilentlyContinue -ErrorVariable var - - # If mounting the VHD failed. Dismount the VHD and mount it again. - if ($var) - { - Write-Verbose "Mounting Failed. Attempting to dismount and mount it back" - Dismount-VHD $vhdPath - $mountedVHD = Mount-VHD -Path $vhdPath -Passthru -ErrorAction SilentlyContinue - - return $mountedVHD - } - else - { - return $mountedVHD - } - } - else - { - Dismount-VHD $vhdPath -ea SilentlyContinue - - } -} - -# Change the Cim Instance objects in to a hash table containing property value pair. -function GetItemToCopy -{ - param([Microsoft.Management.Infrastructure.CimInstance] $item) - - $returnValue = @{ - SourcePath = $item.CimInstanceProperties["SourcePath"].Value - DestinationPath = $item.CimInstanceProperties["DestinationPath"].Value - Ensure = $item.CimInstanceProperties["Ensure"].Value - Recurse = $item.CimInstanceProperties["Recurse"].Value - Force = $item.CimInstanceProperties["Force"].Value - Content = $item.CimInstanceProperties["Content"].Value - Attributes = @($item.CimInstanceProperties["Attributes"].Value) - Type = $item.CimInstanceProperties["Type"].Value - } - - # Assign Default values, if they are not specified. - if ($returnValue.Ensure -eq $null) - { - $returnValue.Ensure = "Present" - } - - if ($returnValue.Force -eq $null) - { - $returnValue.Force = "True" - } - - if ($returnValue.Recurse -eq $null) - { - $returnValue.Recurse = "True" - } - - # Convert string "True" or "False" to boolean for ease of programming. - $returnValue.Force = $returnValue.Force -eq "True" - $returnValue.Recurse = $returnValue.Recurse -eq "True" - $returnValue.Ensure = $returnValue.Ensure -eq "Present" - $returnValue.Keys | %{ Write-Verbose "$_ => $($returnValue[$_])"} - - return $returnValue -} - - -# This is the main function that gets called after the file is mounted to perfom copy,set or new operations on the mounted drive. -function SetVHDFile -{ - [CmdletBinding(DefaultParametersetName="Copy")] - param( - [parameter(Mandatory=$true,ParameterSetName = "Copy")] - $sourcePath, - [switch]$recurse, - [switch]$force, - [parameter(Mandatory=$false,ParameterSetName = "New")] - $type, - [parameter(Mandatory=$false,ParameterSetName = "New")] - $content, - [parameter(Mandatory=$true)] - $destinationPath, - [parameter(Mandatory=$true,ParameterSetName = "Set")] - $attribute, - [parameter(Mandatory=$true,ParameterSetName = "Delete")] - [switch]$ensure - ) - - Write-Verbose "Setting the VHD file $($PSCmdlet.ParameterSetName)" - if ($PSCmdlet.ParameterSetName -eq 'Copy') - { - New-Item -Path (Split-Path $destinationPath) -ItemType Directory -ErrorAction SilentlyContinue - Copy-Item -Path $sourcePath -Destination $destinationPath -Force:$force -Recurse:$recurse -ErrorAction SilentlyContinue - } - elseif ($PSCmdlet.ParameterSetName -eq 'New') - { - If ($type -eq 'Direcotry') - { - New-Item -Path $destinationPath -ItemType $type - } - else - { - New-Item -Path $destinationPath -ItemType $type - $content | Out-File $destinationPath - } - - } - elseif ($PSCmdlet.ParameterSetName -eq 'Set') - { - Write-Verbose "Attempting to change the attribute of the file $destinationPath to value $attribute" - Set-ItemProperty -Path $destinationPath -Name Attributes -Value $attribute - } - elseif (!($ensure)) - { - Remove-Item -Path $destinationPath -Force:$force -Recurse:$recurse - } -} - -Export-ModuleMember -Function *-TargetResource - - - diff --git a/Resources/cHyper-V/DSCResources/PSHOrg_cVhdFileDirectory/PSHOrg_cVhdFileDirectory.schema.mof b/Resources/cHyper-V/DSCResources/PSHOrg_cVhdFileDirectory/PSHOrg_cVhdFileDirectory.schema.mof deleted file mode 100644 index b1c7f63..0000000 --- a/Resources/cHyper-V/DSCResources/PSHOrg_cVhdFileDirectory/PSHOrg_cVhdFileDirectory.schema.mof +++ /dev/null @@ -1,23 +0,0 @@ - -[ClassVersion("1.0.0.0")] -Class PSHOrg_cFileDirectory -{ - [Required] string DestinationPath; - [Write] string SourcePath; - [Write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; - [Write,ValueMap{"File", "Directory"},Values{"File", "Directory"}] string Type; - [Write] boolean Recurse; - [Write] boolean Force ; - [write] string Content; - [Write,ValueMap{"ReadOnly", "Hidden", "System", "Archive"},Values{"ReadOnly", "Hidden", "System", "Archive"}] string Attributes[]; -}; - -[ClassVersion("1.0.0.0"), FriendlyName("cVhdFile")] -class PSHOrg_cVhdFileDirectory : OMI_BaseResource -{ - [Key, Description("Path to the VHD")] String VhdPath; - [Required, EmbeddedInstance("PSHOrg_cFileDirectory"), Description("The FileDirectory objects to copy to the VHD")] String FileDirectory[]; -}; - - - diff --git a/Resources/cHyper-V/Examples/Sample_cVHD_DiffVHD.ps1 b/Resources/cHyper-V/Examples/Sample_cVHD_DiffVHD.ps1 deleted file mode 100644 index dc81719..0000000 --- a/Resources/cHyper-V/Examples/Sample_cVHD_DiffVHD.ps1 +++ /dev/null @@ -1,45 +0,0 @@ -configuration Sample_cVhd_DiffVhd -{ - param - ( - [string[]]$NodeName = 'localhost', - - [Parameter(Mandatory)] - [string]$Name, - - [Parameter(Mandatory)] - [string]$Path, - - [Parameter(Mandatory)] - [string]$ParentPath, - - [ValidateSet("Vhd","Vhdx")] - [string]$Generation = "Vhd", - - [ValidateSet("Present","Absent")] - [string]$Ensure = "Present" - ) - - Import-DscResource -module cHyper-V - - Node $NodeName - { - # Install HyperV feature, if not installed - Server SKU only - WindowsFeature HyperV - { - Ensure = 'Present' - Name = 'Hyper-V' - } - - cVhd DiffVhd - { - Ensure = $Ensure - Name = $Name - Path = $Path - ParentPath = $ParentPath - Generation = $Generation - DependsOn = '[WindowsFeature]HyperV' - } - } -} - diff --git a/Resources/cHyper-V/Examples/Sample_cVHD_NewVHD.ps1 b/Resources/cHyper-V/Examples/Sample_cVHD_NewVHD.ps1 deleted file mode 100644 index 5ae3e5f..0000000 --- a/Resources/cHyper-V/Examples/Sample_cVHD_NewVHD.ps1 +++ /dev/null @@ -1,45 +0,0 @@ -configuration Sample_cVHD_NewVhd -{ - param - ( - [string[]]$NodeName = 'localhost', - - [Parameter(Mandatory)] - [string]$Name, - - [Parameter(Mandatory)] - [string]$Path, - - [Parameter(Mandatory)] - [Uint64]$MaximumSizeBytes, - - [ValidateSet("Vhd","Vhdx")] - [string]$Generation = "Vhd", - - [ValidateSet("Present","Absent")] - [string]$Ensure = "Present" - ) - - Import-DscResource -module cHyper-V - - Node $NodeName - { - # Install HyperV feature, if not installed - Server SKU only - WindowsFeature HyperV - { - Ensure = 'Present' - Name = 'Hyper-V' - } - - cVhd NewVhd - { - Ensure = $Ensure - Name = $Name - Path = $Path - Generation = $Generation - MaximumSizeBytes = $MaximumSizeBytes - DependsOn = '[WindowsFeature]HyperV' - } - } -} - diff --git a/Resources/cHyper-V/Examples/Sample_cVMHost_Paths.ps1 b/Resources/cHyper-V/Examples/Sample_cVMHost_Paths.ps1 deleted file mode 100644 index 3a0ff5c..0000000 --- a/Resources/cHyper-V/Examples/Sample_cVMHost_Paths.ps1 +++ /dev/null @@ -1,32 +0,0 @@ -configuration??Sample_cVMHost?? -{ - - WindowsFeature hypervRole - { - Ensure = 'Present' - Name = 'Hyper-V' - } - - WindowsFeature hypervManagement - { - Ensure = 'Present' - Name = 'Hyper-V-PowerShell' - DependsOn = '[WindowsFeature]hypervRole' - } - -Import-DscResource -module cHyper-V - - PSHOrg_cVMHost hostSettings - { - VMHost = 'localhost' - Ensure = 'Present' - VirtualDiskPath = 'C:\users\public\VHDs' - VirtualMachinePath = 'C:\users\public\VMConfig' - VirtualMachineMigration = $true - EnhancedSessionMode = $false - # ensure the Hyper-V PowerShell module is added - DependsOn = '[WindowsFeature]hypervManagement' - } - -} - diff --git a/Resources/cHyper-V/Examples/Sample_cVMHost_PathsExternalSwitch.ps1 b/Resources/cHyper-V/Examples/Sample_cVMHost_PathsExternalSwitch.ps1 deleted file mode 100644 index d7ed7d4..0000000 --- a/Resources/cHyper-V/Examples/Sample_cVMHost_PathsExternalSwitch.ps1 +++ /dev/null @@ -1,43 +0,0 @@ -configuration??Sample_cVMHost?? -{ - WindowsFeature hypervRole - { - Ensure = 'Present' - Name = 'Hyper-V' - } - - WindowsFeature hypervManagement - { - Ensure = 'Present' - Name = 'Hyper-V-PowerShell' - DependsOn = '[WindowsFeature]hypervRole' - - } - -Import-DscResource -module cHyper-V - - PSHOrg_cVMHost hostSettings - { - VMHost = 'localhost' - Ensure = 'Present' - VirtualDiskPath = 'C:\users\public\VHDs' - VirtualMachinePath = 'C:\users\public\VMConfig' - VirtualMachineMigration = $true - EnhancedSessionMode = $false - # ensure the Hyper-V PowerShell module is added - DependsOn = '[WindowsFeature]hypervManagement' - } - - Import-DscResource -module xHyper-V - - xVMSwitch ExternalSwitch - { - Ensure = 'Present' - Name = 'VMs' - Type = 'External' - NetAdapterName = (Get-NetAdapter)[0].Name - AllowManagementOS = $true - } - -} - diff --git a/Resources/cHyper-V/Examples/Sample_cVMHyperV_Complete.ps1 b/Resources/cHyper-V/Examples/Sample_cVMHyperV_Complete.ps1 deleted file mode 100644 index cd3e60c..0000000 --- a/Resources/cHyper-V/Examples/Sample_cVMHyperV_Complete.ps1 +++ /dev/null @@ -1,69 +0,0 @@ -configuration Sample_cVMHyperV_Complete -{ - param - ( - [string[]]$NodeName = 'localhost', - - [Parameter(Mandatory)] - [string]$VMName, - - [Parameter(Mandatory)] - [string]$VhdPath, - - [Parameter(Mandatory)] - [Uint64]$StartupMemory, - - [Parameter(Mandatory)] - [Uint64]$MinimumMemory, - - [Parameter(Mandatory)] - [Uint64]$MaximumMemory, - - [Parameter(Mandatory)] - [String]$SwitchName, - - [Parameter(Mandatory)] - [String]$Path, - - [Parameter(Mandatory)] - [Uint32]$ProcessorCount, - - [ValidateSet('Off','Paused','Running')] - [String]$State = 'Off', - - [Switch]$WaitForIP - ) - - Import-DscResource -module cHyper-V - - Node $NodeName - { - # Install HyperV feature, if not installed - Server SKU only - WindowsFeature HyperV - { - Ensure = 'Present' - Name = 'Hyper-V' - } - - # Ensures a VM with all the properties - cVMHyperV NewVM - { - Ensure = 'Present' - Name = $VMName - VhdPath = $VhdPath - SwitchName = $SwitchName - State = $State - Path = $Path - Generation = $VhdPath.Split('.')[-1] - StartupMemory = $StartupMemory - MinimumMemory = $MinimumMemory - MaximumMemory = $MaximumMemory - ProcessorCount = $ProcessorCount - MACAddress = $MACAddress - RestartIfNeeded = $true - WaitForIP = $WaitForIP - DependsOn = '[WindowsFeature]HyperV' - } - } -} - diff --git a/Resources/cHyper-V/Examples/Sample_cVMHyperV_DynamicMemory.ps1 b/Resources/cHyper-V/Examples/Sample_cVMHyperV_DynamicMemory.ps1 deleted file mode 100644 index c1a66d2..0000000 --- a/Resources/cHyper-V/Examples/Sample_cVMHyperV_DynamicMemory.ps1 +++ /dev/null @@ -1,47 +0,0 @@ -configuration Sample_cVMHyperV_DynamicMemory -{ - param - ( - [string[]]$NodeName = 'localhost', - - [Parameter(Mandatory)] - [string]$VMName, - - [Parameter(Mandatory)] - [string]$VhdPath, - - [Parameter(Mandatory)] - [Uint64]$StartupMemory, - - [Parameter(Mandatory)] - [Uint64]$MinimumMemory, - - [Parameter(Mandatory)] - [Uint64]$MaximumMemory - ) - - Import-DscResource -module cHyper-V - - Node $NodeName - { - # Install HyperV feature, if not installed - Server SKU only - WindowsFeature HyperV - { - Ensure = 'Present' - Name = 'Hyper-V' - } - - # Ensures a VM with dynamic memory - cVMHyperV NewVM - { - Ensure = 'Present' - Name = $VMName - VhdPath = $VhdPath - Generation = $VhdPath.Split('.')[-1] - StartupMemory = $StartupMemory - MinimumMemory = $MinimumMemory - MaximumMemory = $MaximumMemory - DependsOn = '[WindowsFeature]HyperV' - } - } -} diff --git a/Resources/cHyper-V/Examples/Sample_cVMHyperV_Simple.ps1 b/Resources/cHyper-V/Examples/Sample_cVMHyperV_Simple.ps1 deleted file mode 100644 index 67bb6f0..0000000 --- a/Resources/cHyper-V/Examples/Sample_cVMHyperV_Simple.ps1 +++ /dev/null @@ -1,35 +0,0 @@ -configuration Sample_cVMHyperV_Simple -{ - param - ( - [string[]]$NodeName = 'localhost', - - [Parameter(Mandatory)] - [string]$VMName, - - [Parameter(Mandatory)] - [string]$VhdPath - ) - - Import-DscResource -module cHyper-V - - Node $NodeName - { - # Install HyperV feature, if not installed - Server SKU only - WindowsFeature HyperV - { - Ensure = 'Present' - Name = 'Hyper-V' - } - - # Ensures a VM with default settings - cVMHyperV NewVM - { - Ensure = 'Present' - Name = $VMName - VhdPath = $VhdPath - Generation = $VhdPath.Split('.')[-1] - DependsOn = '[WindowsFeature]HyperV' - } - } -} diff --git a/Resources/cHyper-V/Examples/Sample_cVMSwitch_External.ps1 b/Resources/cHyper-V/Examples/Sample_cVMSwitch_External.ps1 deleted file mode 100644 index 1221deb..0000000 --- a/Resources/cHyper-V/Examples/Sample_cVMSwitch_External.ps1 +++ /dev/null @@ -1,35 +0,0 @@ -configuration Sample_cVMSwitch_External -{ - param - ( - [string[]]$NodeName = 'localhost', - - [Parameter(Mandatory)] - [string]$SwitchName, - - [Parameter(Mandatory)] - [string]$NetAdapterName - ) - - Import-DscResource -module cHyper-V - - Node $NodeName - { - # Install HyperV feature, if not installed - Server SKU only - WindowsFeature HyperV - { - Ensure = 'Present' - Name = 'Hyper-V' - } - - # Ensures a VM with default settings - cVMSwitch ExternalSwitch - { - Ensure = 'Present' - Name = $SwitchName - Type = 'External' - NetAdapterName = $NetAdapterName - DependsOn = '[WindowsFeature]HyperV' - } - } -} diff --git a/Resources/cHyper-V/Examples/Sample_cVMSwitch_Internal.ps1 b/Resources/cHyper-V/Examples/Sample_cVMSwitch_Internal.ps1 deleted file mode 100644 index 0222150..0000000 --- a/Resources/cHyper-V/Examples/Sample_cVMSwitch_Internal.ps1 +++ /dev/null @@ -1,31 +0,0 @@ -configuration Sample_cVMSwitch_Internal -{ - param - ( - [string[]]$NodeName = 'localhost', - - [Parameter(Mandatory)] - [string]$SwitchName - ) - - Import-DscResource -module cHyper-V - - Node $NodeName - { - # Install HyperV feature, if not installed - Server SKU only - WindowsFeature HyperV - { - Ensure = 'Present' - Name = 'Hyper-V' - } - - # Ensures a VM with default settings - cVMSwitch InternalSwitch - { - Ensure = 'Present' - Name = $SwitchName - Type = 'Internal' - DependsOn = '[WindowsFeature]HyperV' - } - } -} diff --git a/Resources/cHyper-V/TechNetDocumentation-cHyperV.docx b/Resources/cHyper-V/TechNetDocumentation-cHyperV.docx deleted file mode 100644 index f64899c..0000000 Binary files a/Resources/cHyper-V/TechNetDocumentation-cHyperV.docx and /dev/null differ diff --git a/Resources/cHyper-V/TechNetDocumentation-cHyperV.md b/Resources/cHyper-V/TechNetDocumentation-cHyperV.md deleted file mode 100644 index e8ae4b2..0000000 --- a/Resources/cHyper-V/TechNetDocumentation-cHyperV.md +++ /dev/null @@ -1,395 +0,0 @@ -## xHyperV Module – Windows PowerShell Desired State Configuration Resource Kit - - -### Introduction -The **xHyper-V** module is a part of the Windows PowerShell Desired State Configuration (DSC) Resource Kit, which is a collection of DSC Resources produced by the PowerShell Team. This module contains the **xVhd**, **xVMHyperV** and **xVMSwitch** resources. These DSC resources allow configuration of Hyper-V host for Vhd, VM and VMSwitch. - -**All of the resources in the DSC Resource Kit are provided AS IS, and are not supported through any Microsoft standard support program or service.** **The “x” in xHyper-V stands for experimental**, which means that these resources will be **fix forward** and monitored by the module owner(s). - -Please leave comments, feature requests, and bug reports in the Q & A tab for this module. -If you would like to modify **xHyper-V**, feel free. When modifying, please update the module name, resource friendly name, and MOF class name (instructions below). As specified in the license, you may copy or modify this resource as long as they are used on the Windows Platform. - -For more information about Windows PowerShell Desired State Configuration, check out the blog posts on the [PowerShell Blog](http://blogs.msdn.com/b/powershell/) ([this](http://blogs.msdn.com/b/powershell/archive/2013/11/01/configuration-in-a-devops-world-windows-powershell-desired-state-configuration.aspx) is a good starting point). There are also great community resources, such as [PowerShell.org](http://powershell.org/wp/tag/dsc/), or [PowerShell Magazine](http://www.powershellmagazine.com/tag/dsc/). For more information on the DSC Resource Kit, check out [this blog post](http://go.microsoft.com/fwlink/?LinkID=389546). - - -### Installation -To install **xHyper-V** module - -* Unzip the content under $env:ProgramFiles\WindowsPowerShell\Modules folder - -To confirm installation: - -* Run **Get-DSCResource** to see that **xVhd**, **xVMHyperV** and **xVMSwitch** are among the DSC Resources listed - - -### Requirements -This module requires the latest version of PowerShell (v4.0, which ships in Windows 8.1 or Windows Server 2012R2). It also requires Hyper-V features. To easily use PowerShell 4.0 on older operating systems, install WMF 4.0. Please read the installation instructions that are present on both the download page and the release notes for WMF 4.0. - -### Description -The xHyper-V module contains the **xVhd**, **xVMHyperV** and **xVMSwitch** DSC Resources. These DSC resources allow you to configure Hyper-V host for its Vhd, VM and VMSwitch. - -### Details -**xVhd** resource has following properties: - -* *Name*: The desired VHD file name -* *Path*: The desired folder where the VHD will be created -* *ParentPath*: Parent VHD file path, for differencing disk -* *MaximumSizeBytes*: Maximum size of Vhd to be created -* *Generation*: Virtual disk format - Vhd or Vhdx -* *Ensure*: Should the VHD be present or absent - -**xVMHyperV** resource has following properties: - -* *Name*: The desired VM name -* *VhdPath*: The desired VHD associated with the VM -* *SwitchName*: Virtual switch associated with the VM -* *State*: State of the VM – Running,Paused,Off -* *Path*: Folder where the VM data will be stored; -* *Generation*: Associated Virtual disk format - Vhd or Vhdx -* *StartupMemory*: Startup RAM for the VM -* *MinimumMemory*: Minimum RAM for the VM. This enables dynamic memory -* *MaximumMemory*: Maximum RAM for the VM. This enable dynamic memory -* *MACAddress*: MAC address of the VM -* *ProcessorCount*: Processor count for the VM -* *WaitForIP*: If specified, waits for VM to get valid IP address -* *RestartIfNeeded*: If specified, shutdowns and restarts the VM as needed for property changes -* *Ensure*: Should the VM be present or absent - -**xVMSwitch** resource has following properties: - -* *Name*: The desired VM Switch name -* *Type*: The desired type of switch – External,Internal,Private -* *NetAdapterName*: Network adapter name for external switch type -* AllowManagementOS: Specify if the VM host has access to the physical NIC -* *Ensure*: Should the VM Switch be present or absent - -### Example: Create a new VHD - -This configuration will create a new VHD on Hyper-V host. - - configuration Sample_xVHD_NewVHD - { - param - ( - [Parameter(Mandatory)] - [string]$Name, - - [Parameter(Mandatory)] - [string]$Path, - - [Parameter(Mandatory)] - [Uint64]$MaximumSizeBytes, - - [ValidateSet("Vhd","Vhdx")] - [string]$Generation = "Vhd", - - [ValidateSet("Present","Absent")] - [string]$Ensure = "Present" - ) - - Import-DscResource -module xHyper-V - - Node localhost - { - xVHD NewVHD - { - Ensure = $Ensure - Name = $Name - Path = $Path - Generation = $Generation - MaximumSizeBytes = $MaximumSizeBytes - } - } - } - -### Example: Create a differencing VHD -This configuration will create a differencing VHD, given a parent VHD, on Hyper-V host. - - configuration Sample_xVhd_DiffVHD - { - param - ( - [Parameter(Mandatory)] - [string]$Name, - - [Parameter(Mandatory)] - [string]$Path, - - [Parameter(Mandatory)] - [string]$ParentPath, - - [ValidateSet("Vhd","Vhdx")] - [string]$Generation = "Vhd", - - [ValidateSet("Present","Absent")] - [string]$Ensure = "Present" - ) - - Import-DscResource -module xHyper-V - - Node localhost - { - xVHD DiffVHD - { - Ensure = $Ensure - Name = $Name - Path = $Path - ParentPath = $ParentPath - Generation = $Generation - } - } - } - -### Example: Create a VM for a given VHD -This configuration will create a VM, given a VHD, on Hyper-V host. - - configuration Sample_xVMHyperV_Simple - { - param - ( - [string[]]$NodeName = 'localhost', - - [Parameter(Mandatory)] - [string]$VMName, - - [Parameter(Mandatory)] - [string]$VhdPath - ) - - Import-DscResource -module xHyper-V - - Node $NodeName - { - # Install HyperV feature, if not installed - Server SKU only - WindowsFeature HyperV - { - Ensure = 'Present' - Name = 'Hyper-V' - } - - # Ensures a VM with default settings - xVMHyperV NewVM - { - Ensure = 'Present' - Name = $VMName - VhdPath = $VhdPath - Generation = $VhdPath.Split('.')[-1] - DependsOn = '[WindowsFeature]HyperV' - } - } - } - -### Example: Create a VM with dynamic memory for a given VHD -This configuration will create a VM with dynamic memory settings, given a VHD, on Hyper-V host. - - configuration Sample_xVMHyperV_DynamicMemory - { - param - ( - [string[]]$NodeName = 'localhost', - - [Parameter(Mandatory)] - [string]$VMName, - - [Parameter(Mandatory)] - [string]$VhdPath, - - [Parameter(Mandatory)] - [Uint64]$StartupMemory, - - [Parameter(Mandatory)] - [Uint64]$MinimumMemory, - - [Parameter(Mandatory)] - [Uint64]$MaximumMemory - ) - - Import-DscResource -module xHyper-V - - Node $NodeName - { - # Install HyperV feature, if not installed - Server SKU only - WindowsFeature HyperV - { - Ensure = 'Present' - Name = 'Hyper-V' - } - - # Ensures a VM with dynamic memory - xVMHyperV NewVM - { - Ensure = 'Present' - Name = $VMName - VhdPath = $VhdPath - Generation = $VhdPath.Split('.')[-1] - StartupMemory = $StartupMemory - MinimumMemory = $MinimumMemory - MaximumMemory = $MaximumMemory - DependsOn = '[WindowsFeature]HyperV' - } - } - } - -### Example: Create a VM with dynamic memory, network interface and processor count for a given VHD -This configuration will create a VM with dynamic memory, network interface and processor count settings, given a VHD, on Hyper-V host. - - configuration Sample_xVMHyperV_Complete - { - param - ( - [string[]]$NodeName = 'localhost', - - [Parameter(Mandatory)] - [string]$VMName, - - [Parameter(Mandatory)] - [string]$VhdPath, - - [Parameter(Mandatory)] - [Uint64]$StartupMemory, - - [Parameter(Mandatory)] - [Uint64]$MinimumMemory, - - [Parameter(Mandatory)] - [Uint64]$MaximumMemory, - - [Parameter(Mandatory)] - [String]$SwitchName, - - [Parameter(Mandatory)] - [String]$Path, - - [Parameter(Mandatory)] - [Uint32]$ProcessorCount, - - [ValidateSet('Off','Paused','Running')] - [String]$State = 'Off', - - [Switch]$WaitForIP - ) - - Import-DscResource -module xHyper-V - - Node $NodeName - { - # Install HyperV feature, if not installed - Server SKU only - WindowsFeature HyperV - { - Ensure = 'Present' - Name = 'Hyper-V' - } - - # Ensures a VM with all the properties - xVMHyperV NewVM - { - Ensure = 'Present' - Name = $VMName - VhdPath = $VhdPath - SwitchName = $SwitchName - State = $State - Path = $Path - Generation = $VhdPath.Split('.')[-1] - StartupMemory = $StartupMemory - MinimumMemory = $MinimumMemory - MaximumMemory = $MaximumMemory - ProcessorCount = $ProcessorCount - MACAddress = $MACAddress - RestartIfNeeded = $true - WaitForIP = $WaitForIP - DependsOn = '[WindowsFeature]HyperV' - } - } - } - -### Example: Create an internal VM Switch -This configuration will create an internal VM Switch, on Hyper-V host. - - configuration Sample_xVMSwitch_Internal - { - param - ( - [string[]]$NodeName = 'localhost', - - [Parameter(Mandatory)] - [string]$SwitchName - ) - - Import-DscResource -module xHyper-V - - Node $NodeName - { - # Install HyperV feature, if not installed - Server SKU only - WindowsFeature HyperV - { - Ensure = 'Present' - Name = 'Hyper-V' - } - - # Ensures a VM with default settings - xVMSwitch InternalSwitch - { - Ensure = 'Present' - Name = $SwitchName - Type = 'Internal' - DependsOn = '[WindowsFeature]HyperV' - } - } - } - -### Example: Create an external VM Switch -This configuration will create an external VM Switch, on Hyper-V host. - - configuration Sample_xVMSwitch_External - { - param - ( - [string[]]$NodeName = 'localhost', - - [Parameter(Mandatory)] - [string]$SwitchName, - - [Parameter(Mandatory)] - [string]$NetAdapterName - ) - - Import-DscResource -module xHyper-V - - Node $NodeName - { - # Install HyperV feature, if not installed - Server SKU only - WindowsFeature HyperV - { - Ensure = 'Present' - Name = 'Hyper-V' - } - - # Ensures a VM with default settings - xVMSwitch ExternalSwitch - { - Ensure = 'Present' - Name = $SwitchName - Type = 'External' - NetAdapterName = $NetAdapterName - DependsOn = '[WindowsFeature]HyperV' - } - } - } -Renaming Requirements - -1. Update the following names by replacing MSFT with your company/community name and replace the “x” with your own prefix (e.g. the resource name should change from MSFT_xComputer to Contoso_myComputer): - * Module name - * Resource Name - * Resource Friendly Name - * MOF class name - * Filename for the .schema.mof -2. Update module and metadata information in the module manifest -3. Update any configuration that use these resources - -### Versions -1.0.0.0 - -* Initial Release with the following resources - * xVhd - * xVMHyperV - * xVMSwitch diff --git a/Resources/cHyper-V/cHyper-V.psd1 b/Resources/cHyper-V/cHyper-V.psd1 deleted file mode 100644 index f88b9c5..0000000 --- a/Resources/cHyper-V/cHyper-V.psd1 +++ /dev/null @@ -1,34 +0,0 @@ -@{ -# Version number of this module. -ModuleVersion = '2.0' - -# ID used to uniquely identify this module -GUID = 'f5a5f169-7026-4053-932a-19a7c37b1ca5' - -# Author of this module -Author = 'Microsoft Corporation' - -# Company or vendor of this module -CompanyName = 'Microsoft Corporation' - -# Copyright statement for this module -Copyright = '(c) 2013 Microsoft Corporation. All rights reserved.' - -# Description of the functionality provided by this module -Description = 'Module with DSC Resources for Hyper-V area' - -# Minimum version of the Windows PowerShell engine required by this module -PowerShellVersion = '4.0' - -# Minimum version of the common language runtime (CLR) required by this module -CLRVersion = '4.0' - -# Functions to export from this module -FunctionsToExport = '*' - -# Cmdlets to export from this module -CmdletsToExport = '*' -} - - - diff --git a/Resources/cNetworking/DSCResources/PSHOrg_cDNSServerAddress/PSHOrg_cDNSServerAddress.psm1 b/Resources/cNetworking/DSCResources/PSHOrg_cDNSServerAddress/PSHOrg_cDNSServerAddress.psm1 deleted file mode 100644 index 8cf55e4..0000000 --- a/Resources/cNetworking/DSCResources/PSHOrg_cDNSServerAddress/PSHOrg_cDNSServerAddress.psm1 +++ /dev/null @@ -1,153 +0,0 @@ -<####################################################################################### - # xDNSServerAddress : DSC Resource that will set/test/get the current DNS Server - # Address, by accepting values among those given in xDNSServerAddress.schema.mof - #######################################################################################> - - - -###################################################################################### -# The Get-TargetResource cmdlet. -# This function will get the present list of DNS ServerAddress DSC Resource schema variables on the system -###################################################################################### -function Get-TargetResource -{ - param - ( - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String[]]$Address, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String]$InterfaceAlias, - - [ValidateSet("IPv4", "IPv6")] - [String]$AddressFamily = "IPv4" - ) - - - $returnValue = @{ - Address = (Get-DnsClientServerAddress -InterfaceAlias $InterfaceAlias -AddressFamily $AddressFamily).ServerAddresses - AddressFamily = $AddressFamily - InterfaceAlias = $InterfaceAlias - } - - $returnValue -} - -###################################################################################### -# The Set-TargetResource cmdlet. -# This function will set a new Server Address in the current node -###################################################################################### -function Set-TargetResource -{ - param - ( - #IP Address that has to be set - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String[]]$Address, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String]$InterfaceAlias, - - [ValidateSet("IPv4", "IPv6")] - [String]$AddressFamily = "IPv4" - ) - - ValidateProperties @PSBoundParameters -Apply -} - -###################################################################################### -# The Test-TargetResource cmdlet. -# This will test if the given Server Address is among the current node's Server Address collection -###################################################################################### -function Test-TargetResource -{ - param - ( - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String[]]$Address, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String]$InterfaceAlias, - - [ValidateSet("IPv4", "IPv6")] - [String]$AddressFamily = "IPv4" - ) - - ValidateProperties @PSBoundParameters -} - - -####################################################################################### -# Helper function that validates the Server Address properties. If the switch parameter -# "Apply" is set, then it will set the properties after a test -####################################################################################### -function ValidateProperties -{ - param - ( - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String[]]$Address, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String]$InterfaceAlias, - - [ValidateSet("IPv4", "IPv6")] - [String]$AddressFamily, - - [Switch]$Apply - ) - $sa =$Address - $sa | %{ - if(!([System.Net.Ipaddress]::TryParse($_, [ref]0))) - { - throw "Server Address *$_* is not in the correct format. Please correct the Address in the configuration and try again" - } - } - try - { - Write-Verbose -Message "Checking the DNS Server Address ..." - #Get the current IP Address based on the parameters given. - $currentAddress = (Get-DnsClientServerAddress -InterfaceAlias $InterfaceAlias -AddressFamily $AddressFamily -ErrorAction Stop).ServerAddresses - - #Check if the Server addresses are the same as the desired addresses. - if(@(Compare-Object -ReferenceObject $currentAddress -DifferenceObject $Address -SyncWindow 0).Length -gt 0) - { - Write-Verbose -Message "DNS Servers are not correct. Expected $Address, actual $currentAddress" - if($Apply) - { - # Set the DNS settings as well - Set-DnsClientServerAddress -InterfaceAlias $InterfaceAlias -ServerAddresses $Address - Write-Verbose -Message "DNS Servers have been set correctly." - } - else - { - return $false - } - } - else - { - #Test will return true in this case - Write-Verbose -Message "DNS Servers are set correctly." - return $true - } - } - catch - { - Write-Verbose -Message $_ - throw "Can not set or find valid DNS Server addresses using InterfaceAlias $InterfaceAlias and AddressFamily $AddressFamily" - } -} - - - -# FUNCTIONS TO BE EXPORTED -Export-ModuleMember -function Get-TargetResource, Set-TargetResource, Test-TargetResource - diff --git a/Resources/cNetworking/DSCResources/PSHOrg_cDNSServerAddress/PSHOrg_cDNSServerAddress.schema.mof b/Resources/cNetworking/DSCResources/PSHOrg_cDNSServerAddress/PSHOrg_cDNSServerAddress.schema.mof deleted file mode 100644 index 84e5e0b..0000000 --- a/Resources/cNetworking/DSCResources/PSHOrg_cDNSServerAddress/PSHOrg_cDNSServerAddress.schema.mof +++ /dev/null @@ -1,8 +0,0 @@ -[ClassVersion("1.0.0"), FriendlyName("cDNSServerAddress")] -class PSHOrg_cDNSServerAddress : OMI_BaseResource -{ - [Required] string Address[]; - [Key] string InterfaceAlias; - [Write,ValueMap{"IPv4", "IPv6"},Values{"IPv4", "IPv6"}] string AddressFamily; -}; - diff --git a/Resources/cNetworking/DSCResources/PSHOrg_cFirewall/PSHOrg_cFirewall.Schema.mof b/Resources/cNetworking/DSCResources/PSHOrg_cFirewall/PSHOrg_cFirewall.Schema.mof deleted file mode 100644 index 0057817..0000000 --- a/Resources/cNetworking/DSCResources/PSHOrg_cFirewall/PSHOrg_cFirewall.Schema.mof +++ /dev/null @@ -1,19 +0,0 @@ -[ClassVersion("1.0.0"), FriendlyName("cFirewall")] -class PSHOrg_cFirewall : OMI_BaseResource -{ - [Key, Description("Name of the Firewall Rule")] String Name; - [Write, Description("Localized, user-facing name of the Firewall Rule being created")] String DisplayName; - [Write, Description("Name of the Firewall Group where we want to put the Firewall Rules")] string DisplayGroup; - [Write, Description("Ensure the presence/absence of the resource"), ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] String Ensure; - [Required, Description("Permit or Block the supplied configuration"), ValueMap{"NotConfigured", "Allow", "Block"},Values{"NotConfigured", "Allow", "Block"}] String Access; - [Write, Description("Enable or disable the supplied configuration"), ValueMap{"Enabled", "Disabled"},Values{"Enabled", "Disabled"}] string State; - [Write, Description("Specifies one or more profiles to which the rule is assigned"), ValueMap{"Any", "Public", "Private", "Domain"},Values{"Any", "Public", "Private", "Domain"}] String Profile[]; - [Write, Description("Direction of the connection"), ValueMap{"Inbound","Outbound"},values{"Inbound","Outbound"}] String Direction; - [Write, Description("Specific Port used for filter. Specified by port number, range, or keyword")] String RemotePort[]; - [Write, Description("Local Port used for the filter")] String LocalPort[]; - [Write, Description("Specific Protocol for filter. Specified by name, number, or range")] String Protocol; - [Write, Description("Documentation for the Rule")] String Description; - [Write, Description("Path and file name of the program for which the rule is applied")] String ApplicationPath; - [Write, Description("Specifies the short name of a Windows service to which the firewall rule applies")] String Service; -}; - diff --git a/Resources/cNetworking/DSCResources/PSHOrg_cFirewall/PSHOrg_cFirewall.psm1 b/Resources/cNetworking/DSCResources/PSHOrg_cFirewall/PSHOrg_cFirewall.psm1 deleted file mode 100644 index fd960b7..0000000 --- a/Resources/cNetworking/DSCResources/PSHOrg_cFirewall/PSHOrg_cFirewall.psm1 +++ /dev/null @@ -1,729 +0,0 @@ -# Default Display Group for the Firewall cmdlets -$DefaultDisplayGroup = "DSC_FirewallRule" - -# DSC uses the Get-TargetResource cmdlet to fetch the status of the resource instance specified in the parameters for the target machine -function Get-TargetResource -{ - param - ( - # Name of the Firewall Rule - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String]$Name, - - # Localized, user-facing name of the Firewall Rule being created - [ValidateNotNullOrEmpty()] - [String]$DisplayName = $Name, - - # Name of the Firewall Group where we want to put the Firewall Rules - [ValidateNotNullOrEmpty()] - [String]$DisplayGroup = $DefaultDisplayGroup, - - # Ensure the presence/absence of the resource - [ValidateSet("Present", "Absent")] - [String]$Ensure, - - # Permit or Block the supplied configuration - [Parameter(Mandatory)] - [ValidateSet("NotConfigured", "Allow", "Block")] - [String]$Access, - - # Enable or disable the supplied configuration - [ValidateSet("Enabled", "Disabled")] - [String]$State, - - # Specifies one or more profiles to which the rule is assigned - [ValidateSet("Any", "Public", "Private", "Domain")] - [String[]]$Profile, - - # Direction of the connection - [ValidateSet("Inbound", "Outbound")] - [String]$Direction, - - # Specific Port used for filter. Specified by port number, range, or keyword - [ValidateNotNullOrEmpty()] - [String[]]$RemotePort, - - # Local Port used for the filter - [ValidateNotNullOrEmpty()] - [String[]]$LocalPort, - - # Specific Protocol for filter. Specified by name, number, or range - [ValidateNotNullOrEmpty()] - [String]$Protocol, - - # Documentation for the Rule - [String]$Description, - - # Path and file name of the program for which the rule is applied - [ValidateNotNullOrEmpty()] - [String]$ApplicationPath, - - # Specifies the short name of a Windows service to which the firewall rule applies - [ValidateNotNullOrEmpty()] - [String]$Service - ) - - # Hash table for Get - $getTargetResourceResult = @{} - - Write-Verbose "GET: Get Generic Settings for Firewall" - $getTargetResourceResult.FirewallSettings = Get-NetFirewallSetting -All - - Write-Verbose "GET: Get Rules for the specified Name[$Name] and DisplayGroup[$DisplayGroup]" - $firewallRules = Get-FirewallRules -Name $Name -DisplayGroup $DisplayGroup - - if ($firewallRules.Count -eq 0) - { - Write-Verbose "GET: Firewall Rule does not exist, there is nothing interesting to do" - - $getTargetResourceResult.Ensure = ($Ensure -eq "Absent") - - return $getTargetResourceResult - } - - $getTargetResourceResult.Ensure = ($Ensure -eq "Present") - - foreach ($firewallRule in $firewallRules) - { - $firewallRuleMap = Get-FirewallRuleProperty -FirewallRule $firewallRule -Property All - $firewallRuleMap.Rule = $firewallRule - - Write-Verbose "GET: Validate each defined parameter against the existing Firewall Rule [$Name]" - if (Test-RuleHasProperties -FirewallRule $firewallRule ` - -Name $Name ` - -DisplayGroup $DisplayGroup ` - -State $State ` - -Profile $Profile ` - -Direction $Direction ` - -Access $Access ` - -RemotePort $RemotePort ` - -LocalPort $LocalPort ` - -Protocol $Protocol ` - -Description $Description ` - -ApplicationPath $ApplicationPath ` - -Service $Service - ) - { - Write-Verbose "GET: Add rule[$Name] to return object" - $getTargetResourceResult[$firewallRule.Name] += @($firewallRuleMap) - } - } - - return $getTargetResourceResult; -} - -# DSC uses Set-TargetResource cmdlet to create, delete or configure the resource instance on the target machine -function Set-TargetResource -{ - param - ( - # Name of the Firewall Rule - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String]$Name, - - # Localized, user-facing name of the Firewall Rule being created - [ValidateNotNullOrEmpty()] - [String]$DisplayName = $Name, - - # Name of the Firewall Group where we want to put the Firewall Rules - [ValidateNotNullOrEmpty()] - [String]$DisplayGroup = $DefaultDisplayGroup, - - # Ensure the presence/absence of the resource - [ValidateSet("Present", "Absent")] - [String]$Ensure = "Present", - - # Permit or Block the supplied configuration - [Parameter(Mandatory)] - [ValidateSet("NotConfigured", "Allow", "Block")] - [String]$Access = "Allow", - - # Enable or disable the supplied configuration - [ValidateSet("Enabled", "Disabled")] - [String]$State = "Enabled", - - # Specifies one or more profiles to which the rule is assigned - [ValidateSet("Any", "Public", "Private", "Domain")] - [String[]]$Profile = ("Any"), - - # Direction of the connection - [ValidateSet("Inbound", "Outbound")] - [String]$Direction, - - # Specific Port used for filter. Specified by port number, range, or keyword - [ValidateNotNullOrEmpty()] - [String[]]$RemotePort, - - # Local Port used for the filter - [ValidateNotNullOrEmpty()] - [String[]]$LocalPort, - - # Specific Protocol for filter. Specified by name, number, or range - [ValidateNotNullOrEmpty()] - [String]$Protocol, - - # Documentation for the Rule - [String]$Description, - - # Path and file name of the program for which the rule is applied - [ValidateNotNullOrEmpty()] - [String]$ApplicationPath, - - # Specifies the short name of a Windows service to which the firewall rule applies - [ValidateNotNullOrEmpty()] - [String]$Service - ) - - Write-Verbose "SET: Find firewall rules with specified parameters for Name = $Name, DisplayGroup = $DisplayGroup" - $firewallRules = Get-FirewallRules -Name $Name -DisplayGroup $DisplayGroup - - $exists = ($firewallRules -ne $null) - - if ($Ensure -eq "Present") - { - Write-Verbose "SET: We want the firewall rule to exist since Ensure is set to $Ensure" - if ($exists) - { - Write-Verbose "SET: We want the firewall rule to exist and it does exist. Check for valid properties" - foreach ($firewallRule in $firewallRules) - { - Write-Verbose "SET: Check each defined parameter against the existing firewall rule - $($firewallRule.Name)" - if (Test-RuleHasProperties -FirewallRule $firewallRule ` - -Name $Name ` - -DisplayGroup $DisplayGroup ` - -State $State ` - -Profile $Profile ` - -Direction $Direction ` - -Access $Access ` - -RemotePort $RemotePort ` - -LocalPort $LocalPort ` - -Protocol $Protocol ` - -Description $Description ` - -ApplicationPath $ApplicationPath ` - -Service $Service - ) - { - } - else - { - - Write-Verbose "SET: Removing existing firewall rule [$Name] to recreate one based on desired configuration" - Remove-NetFirewallRule -Name $Name - - # Set the Firewall rule based on specified parameters - Set-FirewallRule -Name $Name ` - -DisplayName $DisplayName ` - -DisplayGroup $DisplayGroup ` - -State $State ` - -Profile $Profile ` - -Direction $Direction ` - -Access $Access ` - -RemotePort $RemotePort ` - -LocalPort $LocalPort ` - -Protocol $Protocol ` - -Description $Description ` - -ApplicationPath $ApplicationPath ` - -Service $Service -Verbose - } - } - } - else - { - Write-Verbose "SET: We want the firewall rule [$Name] to exist, but it does not" - - # Set the Firewall rule based on specified parameters - Set-FirewallRule -Name $Name ` - -DisplayName $DisplayName ` - -DisplayGroup $DisplayGroup ` - -State $State ` - -Profile $Profile ` - -Direction $Direction ` - -Access $Access ` - -RemotePort $RemotePort ` - -LocalPort $LocalPort ` - -Protocol $Protocol ` - -Description $Description ` - -ApplicationPath $ApplicationPath ` - -Service $Service -Verbose - } - } - elseif ($Ensure -eq "Absent") - { - Write-Verbose "SET: We do not want the firewall rule to exist" - if ($exists) - { - Write-Verbose "SET: We do not want the firewall rule to exist, but it does. Removing the Rule(s)" - foreach ($firewallRule in $firewallRules) - { - Remove-NetFirewallRule -Name $firewallRule.Name - } - } - else - { - Write-Verbose "SET: We do not want the firewall rule to exist, and it does not" - # Do Nothing - } - } -} - -# DSC uses Test-TargetResource cmdlet to check the status of the resource instance on the target machine -function Test-TargetResource -{ - param - ( - # Name of the Firewall Rule - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String]$Name, - - # Localized, user-facing name of the Firewall Rule being created - [ValidateNotNullOrEmpty()] - [String]$DisplayName = $Name, - - # Name of the Firewall Group where we want to put the Firewall Rules - [ValidateNotNullOrEmpty()] - [String]$DisplayGroup, - - # Ensure the presence/absence of the resource - [ValidateSet("Present", "Absent")] - [String]$Ensure = "Present", - - # Permit or Block the supplied configuration - [Parameter(Mandatory)] - [ValidateSet("NotConfigured", "Allow", "Block")] - [String]$Access, - - # Enable or disable the supplied configuration - [ValidateSet("Enabled", "Disabled")] - [String]$State, - - # Specifies one or more profiles to which the rule is assigned - [ValidateSet("Any", "Public", "Private", "Domain")] - [String[]]$Profile, - - # Direction of the connection - [ValidateSet("Inbound", "Outbound")] - [String]$Direction, - - # Specific Port used for filter. Specified by port number, range, or keyword - [ValidateNotNullOrEmpty()] - [String[]]$RemotePort, - - # Local Port used for the filter - [ValidateNotNullOrEmpty()] - [String[]]$LocalPort, - - # Specific Protocol for filter. Specified by name, number, or range - [ValidateNotNullOrEmpty()] - [String]$Protocol, - - # Documentation for the Rule - [String]$Description, - - # Path and file name of the program for which the rule is applied - [ValidateNotNullOrEmpty()] - [String]$ApplicationPath, - - # Specifies the short name of a Windows service to which the firewall rule applies - [ValidateNotNullOrEmpty()] - [String]$Service - ) - - Write-Verbose "TEST: Find rules with specified parameters" - $firewallRules = Get-FirewallRules -Name $Name -DisplayGroup $DisplayGroup - - if (!$firewallRules) - { - Write-Verbose "TEST: Get-FirewallRules returned NULL" - - # Returns whether complies with $Ensure - $returnValue = ($false -eq ($Ensure -eq "Present")) - - Write-Verbose "TEST: Returning $returnValue" - - return $returnValue - } - - $exists = $true - $valid = $true - foreach ($firewallRule in $firewallRules) - { - Write-Verbose "TEST: Check each defined parameter against the existing Firewall Rule - $($firewallRule.Name)" - if (Test-RuleHasProperties -FirewallRule $firewallRule ` - -Name $Name ` - -DisplayGroup $DisplayGroup ` - -State $State ` - -Profile $Profile ` - -Direction $Direction ` - -Access $Access ` - -RemotePort $RemotePort ` - -LocalPort $LocalPort ` - -Protocol $Protocol ` - -Description $Description ` - -ApplicationPath $ApplicationPath ` - -Service $Service - ) - { - } - else - { - $valid = $false - } - } - - # Returns whether or not $exists complies with $Ensure - $returnValue = ($valid -and $exists -eq ($Ensure -eq "Present")) - - Write-Verbose "TEST: Returning $returnValue" - - return $returnValue -} - -#region HelperFunctions - -###################### -## Helper Functions ## -###################### - -# Function to Set a Firewall Rule based on specified parameters -function Set-FirewallRule -{ - param ( - [Parameter(Mandatory)] - [String]$Name, - [String]$DisplayName, - [String]$DisplayGroup, - [String]$State, - [String[]]$Profile, - [String]$Direction, - [String]$Access, - [String[]]$RemotePort, - [String[]]$LocalPort, - [String]$Protocol, - [String]$Description, - [String]$ApplicationPath, - [String]$Service - ) - - $parameters = @{} - $commandName = "New-NetFirewallRule" - - $parameters["Name"] = $Name - - if($DisplayName) - { - $parameters["DisplayName"] = $DisplayName - } - - if($DisplayGroup) - { - $parameters["Group"] = $DisplayGroup - } - else - { - $parameters["Group"] = $DefaultGroup - } - - if($State) - { - if($State -eq "Enabled") - { - $parameters["Enabled"] = "True" - } - else - { - $parameters["Enabled"] = "False" - } - } - - if($Profile) - { - $parameters["Profile"] = $Profile - } - - if($Direction) - { - $parameters["Direction"] = $Direction - } - - if($Access) - { - $parameters["Action"] = $Access - } - - if($RemotePort) - { - $parameters["RemotePort"] = $RemotePort - } - - if($LocalPort) - { - $parameters["LocalPort"] = $LocalPort - } - - if($Protocol) - { - $parameters["Protocol"] = $Protocol - } - - if($Description) - { - $parameters["Description"] = $Description - } - - if($ApplicationPath) - { - $parameters["Program"] = $ApplicationPath - } - - if($Service) - { - $parameters["Service"] = $Service - } - - Write-Verbose "SET: Invoke Set-NetFirewallRule [$Name] with splatting its parameters" - & $commandName @parameters -} - -# Function to validate if the supplied Rule adheres to all parameters set -function Test-RuleHasProperties -{ - param ( - [Parameter(Mandatory)] - $FirewallRule, - [String]$Name, - [String]$DisplayGroup, - [String]$State, - [String[]]$Profile, - [String]$Direction, - [String]$Access, - [String[]]$RemotePort, - [String[]]$LocalPort, - [String]$Protocol, - [String]$Description, - [String]$ApplicationPath, - [String]$Service - ) - - $properties = Get-FirewallRuleProperty -FirewallRule $FirewallRule -Property All - - $desiredConfigurationMatch = $true - - if ($Name -and ($FirewallRule.Name -ne $Name)) - { - Write-Verbose "Test-RuleHasProperties: Name property value - $FirewallRule.Name does not match desired state - $Name" - - $desiredConfigurationMatch = $false - } - - if ($Access -and ($FirewallRule.Action -ne $Access)) - { - Write-Verbose "Test-RuleHasProperties: Access property value - $($FirewallRule.Action) does not match desired state - $Access" - - $desiredConfigurationMatch = $false - } - - if ($State -and ($FirewallRule.Enabled.ToString() -eq ("Enabled" -ne $State))) - { - Write-Verbose "Test-RuleHasProperties: State property value - $FirewallRule.Enabled.ToString() does not match desired state - $State" - - $desiredConfigurationMatch = $false - } - - if ($Profile) - { - [String[]]$networkProfileinRule = $FirewallRule.Profile.ToString() -replace(" ", "") -split(",") - - if ($networkProfileinRule.Count -eq $Profile.Count) - { - foreach($networkProfile in $Profile) - { - if (-not ($networkProfileinRule -contains($networkProfile))) - { - Write-Verbose "Test-RuleHasProperties: Profile property value - '$networkProfileinRule' does not match desired state - '$Profile'" - - $desiredConfigurationMatch = $false - } - } - } - else - { - Write-Verbose "Test-RuleHasProperties: Profile property value - '$networkProfileinRule' does not match desired state - '$Profile'" - - $desiredConfigurationMatch = $false - } - } - - if ($Direction -and ($FirewallRule.Direction -ne $Direction)) - { - Write-Verbose "Test-RuleHasProperties: Direction property value - $FirewallRule.Direction does not match desired state - $Direction" - - $desiredConfigurationMatch = $false - - } - - if ($RemotePort) - { - [String[]]$remotePortInRule = $properties.PortFilters.RemotePort - - if ($remotePortInRule.Count -eq $RemotePort.Count) - { - foreach($port in $RemotePort) - { - if (-not ($remotePortInRule -contains($port))) - { - Write-Verbose "Test-RuleHasProperties: RemotePort property value - '$remotePortInRule' does not match desired state - '$RemotePort'" - - $desiredConfigurationMatch = $false - } - } - } - else - { - Write-Verbose "Test-RuleHasProperties: RemotePort property value - '$remotePortInRule' does not match desired state - '$RemotePort'" - - $desiredConfigurationMatch = $false - } - } - - if ($LocalPort) - { - [String[]]$localPortInRule = $properties.PortFilters.LocalPort - - if ($localPortInRule.Count -eq $LocalPort.Count) - { - foreach($port in $LocalPort) - { - if (-not ($localPortInRule -contains($port))) - { - Write-Verbose "Test-RuleHasProperties: LocalPort property value - '$localPortInRule' does not match desired state - '$LocalPort'" - - $desiredConfigurationMatch = $false - } - } - } - else - { - Write-Verbose "Test-RuleHasProperties: LocalPort property value - '$localPortInRule' does not match desired state - '$LocalPort'" - - $desiredConfigurationMatch = $false - } - } - - if ($Protocol -and ($properties.PortFilters.Protocol -ne $Protocol)) - { - Write-Verbose "Test-RuleHasProperties: Protocol property value - $properties.PortFilters.Protocol does not match desired state - $Protocol" - - $desiredConfigurationMatch = $false - } - - if ($Description -and ($FirewallRule.Description -ne $Description)) - { - Write-Verbose "Test-RuleHasProperties: Description property value - $FirewallRule.Description does not match desired state - $Description" - - $desiredConfigurationMatch = $false - } - - if ($ApplicationPath -and ($properties.ApplicationFilters.Program -ne $ApplicationPath)) - { - Write-Verbose "Test-RuleHasProperties: ApplicationPath property value - $properties.ApplicationFilters.Program does not match desired state - $ApplicationPath" - - $desiredConfigurationMatch = $false - } - - if ($Service -and ($properties.ServiceFilters.Service -ne $Service)) - { - Write-Verbose "Test-RuleHasProperties: Service property value - $properties.ServiceFilters.Service does not match desired state - $Service" - - $desiredConfigurationMatch = $false - } - - Write-Verbose "Test-RuleHasProperties returning $desiredConfigurationMatch" - return $desiredConfigurationMatch -} - -# Returns a list of FirewallRules that comply to the specified parameters. -function Get-FirewallRules -{ - param ( - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String]$Name, - - [String]$DisplayGroup - ) - - $firewallRules = @(Get-NetFirewallRule -Name $Name -ErrorAction SilentlyContinue) - - if (-not $firewallRules) - { - Write-Verbose "Get-FirewallRules: No Firewall Rules found for [$Name]" - return $null - } - else - { - if ($DisplayGroup) - { - foreach ($firewallRule in $firewallRules) - { - if ($firewallRule.DisplayGroup -eq $DisplayGroup) - { - Write-Verbose "Get-FirewallRules: Found a Firewall Rule for Name: [$Name] and DisplayGroup [$DisplayGroup]" - return $firewallRule - } - } - } - } - - return $firewallRules -} - -# Returns the filters associated with the given firewall rule -function Get-FirewallRuleProperty -{ - - param ( - [Parameter(Mandatory)] - $FirewallRule, - - [Parameter(Mandatory)] - [ValidateSet("All", "AddressFilter", "ApplicationFilter", "InterfaceFilter", - "InterfaceTypeFilter", "PortFilter", "Profile", "SecurityFilter", "ServiceFilter")] - $Property - ) - - if ($Property -eq "All") - { - Write-Verbose "Get-FirewallRuleProperty: Get all the properties" - - $properties = @{} - - Write-Verbose "Get-FirewallRuleProperty: Add filter info to rule map" - $properties.AddressFilters = @(Get-NetFirewallAddressFilter -AssociatedNetFirewallRule $FirewallRule) - $properties.ApplicationFilters = @(Get-NetFirewallApplicationFilter -AssociatedNetFirewallRule $FirewallRule) - $properties.InterfaceFilters = @(Get-NetFirewallInterfaceFilter -AssociatedNetFirewallRule $FirewallRule) - $properties.InterfaceTypeFilters = @(Get-NetFirewallInterfaceTypeFilter -AssociatedNetFirewallRule $FirewallRule) - $properties.PortFilters = @(Get-NetFirewallPortFilter -AssociatedNetFirewallRule $FirewallRule) - $properties.Profile = @(Get-NetFirewallProfile -AssociatedNetFirewallRule $FirewallRule) - $properties.SecurityFilters = @(Get-NetFirewallSecurityFilter -AssociatedNetFirewallRule $FirewallRule) - $properties.ServiceFilters = @(Get-NetFirewallServiceFilter -AssociatedNetFirewallRule $FirewallRule) - - return $properties - } - - if ($Property -eq "AddressFilter" -or $Property -eq "ApplicationFilter" -or $Property -eq "InterfaceFilter" ` - -or $Property -eq "InterfaceTypeFilter" -or $Property -eq "PortFilter" -or $Property -eq "Profile" ` - -or $Property -eq "SecurityFilter" -or $Property -eq "ServiceFilter") - { - Write-Verbose "Get-FirewallRuleProperty: Get only [$Property] property" - - return &(Get-Command "Get-NetFirewall$Property") -AssociatedNetFireWallRule $FireWallRule - } -} - -#endregion - -Export-ModuleMember -Function *-TargetResource - diff --git a/Resources/cNetworking/DSCResources/PSHOrg_cIPAddress/PSHOrg_cIPAddress.psm1 b/Resources/cNetworking/DSCResources/PSHOrg_cIPAddress/PSHOrg_cIPAddress.psm1 deleted file mode 100644 index 5261505..0000000 --- a/Resources/cNetworking/DSCResources/PSHOrg_cIPAddress/PSHOrg_cIPAddress.psm1 +++ /dev/null @@ -1,189 +0,0 @@ -<####################################################################################### - # MSDSCPack_IPAddress : DSC Resource that will set/test/get the current IP - # Address, by accepting values among those given in MSDSCPack_IPAddress.schema.mof - #######################################################################################> - - - -###################################################################################### -# The Get-TargetResource cmdlet. -# This function will get the present list of IP Address DSC Resource schema variables on the system -###################################################################################### -function Get-TargetResource -{ - [OutputType([hashtable])] - param - ( - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String]$IPAddress, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String]$InterfaceAlias, - - [byte]$SubnetMask = 16, - - [ValidateNotNullOrEmpty()] - [String]$DefaultGateway, - - [ValidateSet("IPv4", "IPv6")] - [String]$AddressFamily = "IPv4" - ) - - - $returnValue = @{ - IPAddress = [System.String]::Join(", ",(Get-NetIPAddress -InterfaceAlias $InterfaceAlias -AddressFamily $AddressFamily).IPAddress) - SubnetMask = $SubnetMask - DefaultGateway = $DefaultGateway - AddressFamily = $AddressFamily - InterfaceAlias=$InterfaceAlias - } - - $returnValue -} - -###################################################################################### -# The Set-TargetResource cmdlet. -# This function will set a new IP Address in the current node -###################################################################################### -function Set-TargetResource -{ - param - ( - #IP Address that has to be set - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String]$IPAddress, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String]$InterfaceAlias, - - [byte]$SubnetMask, - - [ValidateNotNullOrEmpty()] - [String]$DefaultGateway, - - [ValidateSet("IPv4", "IPv6")] - [String]$AddressFamily = "IPv4" - ) - - - ValidateProperties @PSBoundParameters -Apply -} - -###################################################################################### -# The Test-TargetResource cmdlet. -# This will test if the given IP Address is among the current node's IP Address collection -###################################################################################### -function Test-TargetResource -{ - [OutputType([bool])] - param - ( - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String]$IPAddress, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String]$InterfaceAlias, - - [byte]$SubnetMask, - - [ValidateNotNullOrEmpty()] - [String]$DefaultGateway, - - [ValidateSet("IPv4", "IPv6")] - [String]$AddressFamily = "IPv4" - ) - - ValidateProperties @PSBoundParameters -} - - -####################################################################################### -# Helper function that validates the IP Address properties. If the switch parameter -# "Apply" is set, then it will set the properties after a test -####################################################################################### -function ValidateProperties -{ - param - ( - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String]$IPAddress, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String]$InterfaceAlias, - - [ValidateNotNullOrEmpty()] - [String]$DefaultGateway, - - [byte]$SubnetMask = 16, - - [ValidateSet("IPv4", "IPv6")] - [String]$AddressFamily = "IPv4", - - [Switch]$Apply - ) - $ip=$IPAddress - if(!([System.Net.Ipaddress]::TryParse($ip, [ref]0))) - { - throw "IP Address *$IPAddress* is not in the correct format. Please correct the ipaddress in the configuration and try again" - } - try - { - Write-Verbose -Message "Checking the IPAddress ..." - #Get the current IP Address based on the parameters given. - $currentIP = Get-NetIPAddress -InterfaceAlias $InterfaceAlias -AddressFamily $AddressFamily -ErrorAction Stop - - #Test if the IP Address passed is equal to the current ip address - if(!$currentIP.IPAddress.Contains($IPAddress) -or $currentIP.PrefixOrigin -eq 'dhcp') - { - Write-Verbose -Message "IP configuration not correct. Expected $IPAddress set to manual, actual $($currentIP.IPAddress) set to $($currentIP.PrefixOrigin)" - $Parameters = @{} - - #Apply is true in the case of set - target resource - in which case, it will set the new IP Address - if($Apply) - { - Write-Verbose -Message "Setting IPAddress ..." - $Parameters["IPAddress"] = $IPAddress - $Parameters["PrefixLength"] = $SubnetMask - $Parameters["InterfaceAlias"] = $currentIP[0].InterfaceAlias - - if($DefaultGateway){ $Parameters["DefaultGateWay"] = $DefaultGateway } - - if($currentIP.PrefixOrigin -eq 'dhcp') { - Write-Verbose -Message "IPAddress is $($currentIP.IPAddress) via DHCP. Disabling DHCP" - $null = Set-NetIPInterface -InterfaceAlias $InterfaceAlias -Dhcp Disabled - } - - $null = New-NetIPAddress @Parameters -ErrorAction Stop - - # Make the connection profile private - Get-NetConnectionProfile -InterfaceAlias $InterfaceAlias | Set-NetConnectionProfile -NetworkCategory Private -ErrorAction SilentlyContinue - Write-Verbose -Message "IPAddress is set to $IPAddress." - } - else {return $false} - } - else - { - Write-Verbose -Message "IPAddress is correct." - return $true - } - } - catch - { - Write-Verbose -Message $_ - throw "Can not set or find valid IPAddress using InterfaceAlias $InterfaceAlias and AddressFamily $AddressFamily" - } -} - - - -# FUNCTIONS TO BE EXPORTED -Export-ModuleMember -function Get-TargetResource, Set-TargetResource, Test-TargetResource - diff --git a/Resources/cNetworking/DSCResources/PSHOrg_cIPAddress/PSHOrg_cIPAddress.schema.mof b/Resources/cNetworking/DSCResources/PSHOrg_cIPAddress/PSHOrg_cIPAddress.schema.mof deleted file mode 100644 index 657aa7c..0000000 Binary files a/Resources/cNetworking/DSCResources/PSHOrg_cIPAddress/PSHOrg_cIPAddress.schema.mof and /dev/null differ diff --git a/Resources/cNetworking/Examples/Sample_cDnsServerAddress.ps1 b/Resources/cNetworking/Examples/Sample_cDnsServerAddress.ps1 deleted file mode 100644 index 254b392..0000000 --- a/Resources/cNetworking/Examples/Sample_cDnsServerAddress.ps1 +++ /dev/null @@ -1,28 +0,0 @@ -configuration Sample_cDnsServerAddress -{ - param - ( - [string[]]$NodeName = 'localhost', - - [Parameter(Mandatory)] - [string]$DnsServerAddress, - - [Parameter(Mandatory)] - [string]$InterfaceAlias, - - [ValidateSet("IPv4","IPv6")] - [string]$AddressFamily = 'IPv4' - ) - - Import-DscResource -Module cNetworking - - Node $NodeName - { - cDnsServerAddress DnsServerAddress - { - Address = $DnsServerAddress - InterfaceAlias = $InterfaceAlias - AddressFamily = $AddressFamily - } - } -} diff --git a/Resources/cNetworking/Examples/Sample_cIPAddress_FixedValue.ps1 b/Resources/cNetworking/Examples/Sample_cIPAddress_FixedValue.ps1 deleted file mode 100644 index f6ed968..0000000 --- a/Resources/cNetworking/Examples/Sample_cIPAddress_FixedValue.ps1 +++ /dev/null @@ -1,20 +0,0 @@ -configuration Sample_cIPAddress_FixedValue -{ - param - ( - [string[]]$NodeName = 'localhost' - ) - - Import-DscResource -Module cNetworking - - Node $NodeName - { - cIPAddress NewIPAddress - { - IPAddress = "2001:4898:200:7:6c71:a102:ebd8:f482" - InterfaceAlias = "Ethernet" - SubnetMask = 24 - AddressFamily = "IPV6" - } - } -} diff --git a/Resources/cNetworking/Examples/Sample_cIPAddress_Parameterized.ps1 b/Resources/cNetworking/Examples/Sample_cIPAddress_Parameterized.ps1 deleted file mode 100644 index 2f4488a..0000000 --- a/Resources/cNetworking/Examples/Sample_cIPAddress_Parameterized.ps1 +++ /dev/null @@ -1,37 +0,0 @@ -configuration Sample_cIPAddress_Parameterized -{ - param - ( - - [string[]]$NodeName = 'localhost', - - [Parameter(Mandatory)] - [string]$IPAddress, - - [Parameter(Mandatory)] - [string]$InterfaceAlias, - - [Parameter(Mandatory)] - [string]$DefaultGateway, - - [int]$SubnetMask = 16, - - [ValidateSet("IPv4","IPv6")] - [string]$AddressFamily = 'IPv4' - ) - - Import-DscResource -Module cNetworking - - Node $NodeName - { - cIPAddress NewIPAddress - { - IPAddress = $IPAddress - InterfaceAlias = $InterfaceAlias - DefaultGateway = $DefaultGateway - SubnetMask = $SubnetMask - AddressFamily = $AddressFamily - } - } -} - diff --git a/Resources/cNetworking/TechNetDocumentation-cNetworking.docx b/Resources/cNetworking/TechNetDocumentation-cNetworking.docx deleted file mode 100644 index 7bcf55b..0000000 Binary files a/Resources/cNetworking/TechNetDocumentation-cNetworking.docx and /dev/null differ diff --git a/Resources/cNetworking/TechNetDocumentation-cNetworking.md b/Resources/cNetworking/TechNetDocumentation-cNetworking.md deleted file mode 100644 index a641382..0000000 --- a/Resources/cNetworking/TechNetDocumentation-cNetworking.md +++ /dev/null @@ -1,150 +0,0 @@ -## xNetworking Module Windows PowerShell Desired State Configuration Resource Kit - - -### Introduction -The **xNetworking** module is a part of Windows PowerShell Desired State Configuration (DSC) Resource Kit, which is a collection of DSC Resources produced by the PowerShell Team. This module contains the **xIPAddress** and **xDnsServerAddress** resources. These DSC Resources allow configuration of a nodes IP Address and DNS Server Address. - -**All of the resources in the DSC Resource Kit are provided AS IS, and are not supported through any Microsoft standard support program or service. The x in xNetworking stands for experimental,** which means that these resources will be **fix forward** and monitored by the module owner(s). - -Please leave comments, feature requests, and bug reports in the Q & A tab for this module. - -If you would like to modify **xNetworking** module, feel free. When modifying, please update the module name, resource friendly name, and MOF class name (instructions below). As specified in the license, you may copy or modify this resource as long as they are used on the Windows Platform. - -For more information about Windows PowerShell Desired State Configuration, check out the blog posts on the [PowerShell Blog](http://blogs.msdn.com/b/powershell/) ([this](http://blogs.msdn.com/b/powershell/archive/2013/11/01/configuration-in-a-devops-world-windows-powershell-desired-state-configuration.aspx) is a good starting point). There are also great community resources, such as [PowerShell.org](http://powershell.org/wp/tag/dsc/), or [PowerShell Magazine](http://www.powershellmagazine.com/tag/dsc/). For more information on the DSC Resource Kit, check out [this blog post](http://go.microsoft.com/fwlink/?LinkID=389546). - -### Installation -To install **xNetworking** module -* Unzip the content under $env:ProgramFiles\WindowsPowerShell\Modules folder - -To confirm installation: -* Run **Get-DSCResource** to see that **xIPAddress** and **xDnsServerAddress** are among the DSC Resources listed - -### Requirements -This module requires the latest version of PowerShell (v4.0, which ships in Windows 8.1 or Windows Server 2012R2). It also requires **** features. To easily use PowerShell 4.0 on older operating systems, [install WMF 4.0](http://www.microsoft.com/en-us/download/details.aspx?id=40855). Please read the installation instructions that are present on both the download page and the release notes for WMF 4.0. - -### Description -The **xNetworking** module contains two DSC Resources: **xIPAddress** and **xDnsServerAddress**. Instead of needing to know and remember the functionality and syntax for the IPAddress and DNS cmdlets, these DSC Resources allow you to easily configure and maintain your networking settings by writing simple configurations. - -### Details -**xIPAddress** resource has following properties: -* IPAddress: The desired IP Address -* InterfaceAlias: Alias of the network interface for which IP Address is set -* DefaultGateway: Specifies the IP address of the default gateway for the host -* SubnetMask: Local subnet size using IP address format -* AddressFamily: IP address family - IPv4 or IPv6 - -**xDnsServerAddress** resource has following properties: -* Address: The desired DNS Server addresses -* InterfaceAlias: Alias of the network interface for which DNS Server Address is set -* AddressFamily: IP address family - IPv4 or IPv6 - -### Example: Set IP Address on Ethernet NIC -This configuration will set IP Address with some typical values for network interface alias = Ethernet - - configuration Sample_xIPAddress_FixedValue - { - param - ( - [string[]]$NodeName # 'localhost' - ) - - Import-DscResource -Module xNetworking - - Node $NodeName - { - xIPAddress NewIPAddress - { - IPAddress # "2001:4898:200:7:6c71:a102:ebd8:f482" - InterfaceAlias # "Ethernet" - SubnetMask # 24 - AddressFamily # "IPV6" - } - } - } - -### Example: Set IP Address with parameterized values -This configuration will set IP Address along with default gateway on a network interface that is identified by its alias - - configuration Sample_xIPAddress_Parameterized - { - param - ( - - [string[]]$NodeName # 'localhost', - - [Parameter(Mandatory)] - [string]$IPAddress, - - [Parameter(Mandatory)] - [string]$InterfaceAlias, - - [Parameter(Mandatory)] - [string]$DefaultGateway, - - [int]$SubnetMask # 16, - - [ValidateSet("IPv4","IPv6")] - [string]$AddressFamily # 'IPv4' - ) - - Import-DscResource -Module xNetworking - - Node $NodeName - { - xIPAddress NewIPAddress - { - IPAddress # $IPAddress - InterfaceAlias # $InterfaceAlias - DefaultGateway # $DefaultGateway - SubnetMask # $SubnetMask - AddressFamily # $AddressFamily - } - } - } - -### Example: Set DNS Server Address -This configuration will set DNS Server Address on a network interface that is identified by its alias - - configuration Sample_xDnsServerAddress - { - param - ( - [string[]]$NodeName # 'localhost', - - [Parameter(Mandatory)] - [string]$DnsServerAddress, - - [Parameter(Mandatory)] - [string]$InterfaceAlias, - - [ValidateSet("IPv4","IPv6")] - [string]$AddressFamily # 'IPv4' - ) - Import-DscResource -Module xNetworking - - Node $NodeName - { - xDnsServerAddress DnsServerAddress - { - Address # $DnsServerAddress - InterfaceAlias # $InterfaceAlias - AddressFamily # $AddressFamily - } - } - } - -### Renaming Requirements -1. Update the following names by replacing MSFT with your company/community name and replace the x with your own prefix (e.g. the resource name should change from MSFT_xComputer to Contoso_myComputer): - * Module name - * Resource Name - * Resource Friendly Name - * MOF class name - * Filename for the .schema.mof -1. Update module and metadata information in the module manifest -1. Update any configuration that use these resources - -### Versions -1.0.0.0 -* Initial Release with the following resources - * xIPAddress - * xDnsServerAddress diff --git a/Resources/cNetworking/cNetworking.psd1 b/Resources/cNetworking/cNetworking.psd1 deleted file mode 100644 index 028822d..0000000 --- a/Resources/cNetworking/cNetworking.psd1 +++ /dev/null @@ -1,32 +0,0 @@ -@{ -# Version number of this module. -ModuleVersion = '2.0.1' - -# ID used to uniquely identify this module -GUID = 'e6647cc3-ce9c-4c86-9eb8-2ee8919bf358' - -# Author of this module -Author = 'Microsoft Corporation' - -# Company or vendor of this module -CompanyName = 'Microsoft Corporation' - -# Copyright statement for this module -Copyright = '(c) 2013 Microsoft Corporation. All rights reserved.' - -# Description of the functionality provided by this module -Description = 'Module with DSC Resources for Networking area' - -# Minimum version of the Windows PowerShell engine required by this module -PowerShellVersion = '4.0' - -# Minimum version of the common language runtime (CLR) required by this module -CLRVersion = '4.0' - -# Functions to export from this module -FunctionsToExport = '*' - -# Cmdlets to export from this module -CmdletsToExport = '*' -} - diff --git a/Resources/cPSDesiredStateConfiguration/DSCResources/PSHOrg_cDSCWebService/PSHOrg_cDSCWebService.Schema.mof b/Resources/cPSDesiredStateConfiguration/DSCResources/PSHOrg_cDSCWebService/PSHOrg_cDSCWebService.Schema.mof deleted file mode 100644 index f2c2b7d..0000000 --- a/Resources/cPSDesiredStateConfiguration/DSCResources/PSHOrg_cDSCWebService/PSHOrg_cDSCWebService.Schema.mof +++ /dev/null @@ -1,15 +0,0 @@ -[ClassVersion("1.0.0"), FriendlyName("cDSCWebService")] -class PSHOrg_cDSCWebService : OMI_BaseResource -{ - [Key] string EndpointName; - [required] string CertificateThumbPrint; - [write] uint32 Port; - [write] string PhysicalPath; - [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; - [write,ValueMap{"Started","Stopped"},Values{"Started", "Stopped"}] string State; - [write] string ModulePath; - [write] string ConfigurationPath; - [write] boolean IsComplianceServer; - [read] string DSCServerUrl; -}; - diff --git a/Resources/cPSDesiredStateConfiguration/DSCResources/PSHOrg_cDSCWebService/PSHOrg_cDSCWebService.psm1 b/Resources/cPSDesiredStateConfiguration/DSCResources/PSHOrg_cDSCWebService/PSHOrg_cDSCWebService.psm1 deleted file mode 100644 index 4b93fcb..0000000 --- a/Resources/cPSDesiredStateConfiguration/DSCResources/PSHOrg_cDSCWebService/PSHOrg_cDSCWebService.psm1 +++ /dev/null @@ -1,427 +0,0 @@ -# The Get-TargetResource cmdlet. -function Get-TargetResource -{ - [OutputType([Hashtable])] - param - ( - # Prefix of the WCF SVC File - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string]$EndpointName, - - # Thumbprint of the Certificate in CERT:\LocalMachine\MY\ for Pull Server - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string]$CertificateThumbPrint - ) - - try - { - $webSite = Get-Website -Name $EndpointName - - if ($webSite) - { - # Get Full Path for Web.config file - $webConfigFullPath = Join-Path $website.physicalPath "web.config" - - $modulePath = Get-WebConfigAppSetting -WebConfigFullPath $webConfigFullPath -AppSettingName "ModulePath" - $ConfigurationPath = Get-WebConfigAppSetting -WebConfigFullPath $webConfigFullPath -AppSettingName "ConfigurationPath" - - $UrlPrefix = $website.bindings.Collection[0].protocol + "://" - - $fqdn = $env:COMPUTERNAME - if ($env:USERDNSDOMAIN) - { - $fqdn = $env:COMPUTERNAME + "." + $env:USERDNSDOMAIN - } - - $iisPort = $website.bindings.Collection[0].bindingInformation.Split(":")[1] - - $svcFileName = (Get-ChildItem -Path $website.physicalPath -Filter "*.svc").Name - - $serverUrl = $UrlPrefix + $fqdn + ":" + $iisPort + "/" + $webSite.name + "/" + $svcFileName - - $webBinding = Get-WebBinding -Name $EndpointName - $certificateThumbPrint = $webBinding.certificateHash - - @{ - EndpointName = $EndpointName - Port = $website.bindings.Collection[0].bindingInformation.Split(":")[1] - PhysicalPath = $website.physicalPath - State = $webSite.state - ModulePath = $modulePath - ConfigurationPath = $ConfigurationPath - DSCServerUrl = $serverUrl - CertificateThumbPrint = $certificateThumbPrint - } - } - } - catch - { - Write-Error "An error occured while retrieving settings for the website" - } -} - -# The Set-TargetResource cmdlet. -function Set-TargetResource -{ - param - ( - # Prefix of the WCF SVC File - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string]$EndpointName, - - # Port number of the DSC Pull Server IIS Endpoint - [Uint32]$Port = $( if ($IsComplianceServer) { 7070 } else { 8080 } ), - - # Physical path for the IIS Endpoint on the machine (usually under inetpub/wwwroot) - [string]$PhysicalPath = "$env:SystemDrive\inetpub\wwwroot\$EndpointName", - - # Thumbprint of the Certificate in CERT:\LocalMachine\MY\ for Pull Server - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string]$CertificateThumbPrint, - - [ValidateSet("Present", "Absent")] - [string]$Ensure = "Present", - - [ValidateSet("Started", "Stopped")] - [string]$State = "Started", - - # Location on the disk where the Modules are stored - [string]$ModulePath = "$env:PROGRAMFILES\WindowsPowerShell\DscService\Modules", - - # Location on the disk where the Configuration is stored - [string]$ConfigurationPath = "$env:PROGRAMFILES\WindowsPowerShell\DscService\Configuration", - - # Is the endpoint for a DSC Compliance Server - [boolean] $IsComplianceServer - ) - - # Initialize with default values - $pathPullServer = "$pshome\modules\PSDesiredStateConfiguration\PullServer" - $rootDataPath ="$env:PROGRAMFILES\WindowsPowerShell\DscService" - $jet4provider = "System.Data.OleDb" - $jet4database = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=$env:PROGRAMFILES\WindowsPowerShell\DscService\Devices.mdb;" - $eseprovider = "ESENT"; - $esedatabase = "$env:PROGRAMFILES\WindowsPowerShell\DscService\Devices.edb"; - - $culture = Get-Culture - $language = $culture.TwoLetterISOLanguageName - - $os = [System.Environment]::OSVersion.Version - $IsBlue = $false; - if($os.Major -eq 6 -and $os.Minor -eq 3) - { - $IsBlue = $true; - } - - # Use Pull Server values for defaults - $webConfigFileName = "$pathPullServer\PSDSCPullServer.config" - $svcFileName = "$pathPullServer\PSDSCPullServer.svc" - $pswsMofFileName = "$pathPullServer\PSDSCPullServer.mof" - $pswsDispatchFileName = "$pathPullServer\PSDSCPullServer.xml" - - # Update only if Compliance Server install is requested - if ($IsComplianceServer) - { - $webConfigFileName = "$pathPullServer\PSDSCComplianceServer.config" - $svcFileName = "$pathPullServer\PSDSCComplianceServer.svc" - $pswsMofFileName = "$pathPullServer\PSDSCComplianceServer.mof" - $pswsDispatchFileName = "$pathPullServer\PSDSCComplianceServer.xml" - } - - Write-Verbose "Create the IIS endpoint" - cPSDesiredStateConfiguration\New-PSWSEndpoint -site $EndpointName ` - -path $PhysicalPath ` - -cfgfile $webConfigFileName ` - -port $Port ` - -applicationPoolIdentityType LocalSystem ` - -app $EndpointName ` - -svc $svcFileName ` - -mof $pswsMofFileName ` - -dispatch $pswsDispatchFileName ` - -asax "$pathPullServer\Global.asax" ` - -dependentBinaries "$pathPullServer\Microsoft.Powershell.DesiredStateConfiguration.Service.dll" ` - -language $language ` - -dependentMUIFiles "$pathPullServer\$language\Microsoft.Powershell.DesiredStateConfiguration.Service.Resources.dll" ` - -certificateThumbPrint $CertificateThumbPrint ` - -EnableFirewallException $true -Verbose - - Update-LocationTagInApplicationHostConfigForAuthentication -WebSite $EndpointName -Authentication "anonymous" - Update-LocationTagInApplicationHostConfigForAuthentication -WebSite $EndpointName -Authentication "basic" - Update-LocationTagInApplicationHostConfigForAuthentication -WebSite $EndpointName -Authentication "windows" - - - if ($IsBlue) - { - Write-Verbose "Set values into the web.config that define the repository for BLUE OS" - Set-AppSettingsInWebconfig -path $PhysicalPath -key "dbprovider" -value $eseprovider - Set-AppSettingsInWebconfig -path $PhysicalPath -key "dbconnectionstr"-value $esedatabase - } - else - { - Write-Verbose "Set values into the web.config that define the repository for non-BLUE Downlevel OS" - $repository = Join-Path "$rootDataPath" "Devices.mdb" - Copy-Item "$pathPullServer\Devices.mdb" $repository -Force - - Set-AppSettingsInWebconfig -path $PhysicalPath -key "dbprovider" -value $jet4provider - Set-AppSettingsInWebconfig -path $PhysicalPath -key "dbconnectionstr" -value $jet4database - } - - if ($IsComplianceServer) - { - Write-Verbose "Compliance Server: Set values into the web.config that indicate this is the admin endpoint" - Set-AppSettingsInWebconfig -path $PhysicalPath -key "AdminEndPoint" -value "true" - } - else - { - Write-Verbose "Pull Server: Set values into the web.config that indicate the location of repository, configuration, modules" - - # Create the application data directory calculated above - $null = New-Item -path $rootDataPath -itemType "directory" -Force - - # Set values into the web.config that define the repository and where - # configuration and modules files are stored. Also copy an empty database - # into place. - Set-AppSettingsInWebconfig -path $PhysicalPath -key "dbprovider" -value $eseprovider - Set-AppSettingsInWebconfig -path $PhysicalPath -key "dbconnectionstr" -value $esedatabase - - $repository = Join-Path $rootDataPath "Devices.mdb" - Copy-Item "$pathPullServer\Devices.mdb" $repository -Force - - $null = New-Item -path "$ConfigurationPath" -itemType "directory" -Force - - Set-AppSettingsInWebconfig -path $PhysicalPath -key "ConfigurationPath" -value $ConfigurationPath - - $null = New-Item -path "$ModulePath" -itemType "directory" -Force - - Set-AppSettingsInWebconfig -path $PhysicalPath -key "ModulePath" -value $ModulePath - } -} - -# The Test-TargetResource cmdlet. -function Test-TargetResource -{ - [OutputType([Boolean])] - param - ( - # Prefix of the WCF SVC File - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string]$EndpointName, - - # Port number of the DSC Pull Server IIS Endpoint - [Uint32]$Port = $( if ($IsComplianceServer) { 7070 } else { 8080 } ), - - # Physical path for the IIS Endpoint on the machine (usually under inetpub/wwwroot) - [string]$PhysicalPath = "$env:SystemDrive\inetpub\wwwroot\$EndpointName", - - # Thumbprint of the Certificate in CERT:\LocalMachine\MY\ for Pull Server - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string]$CertificateThumbPrint = "AllowUnencryptedTraffic", - - [ValidateSet("Present", "Absent")] - [string]$Ensure = "Present", - - [ValidateSet("Started", "Stopped")] - [string]$State = "Started", - - # Location on the disk where the Modules are stored - [string]$ModulePath = "$env:PROGRAMFILES\WindowsPowerShell\DscService\Modules", - - # Location on the disk where the Configuration is stored - [string]$ConfigurationPath = "$env:PROGRAMFILES\WindowsPowerShell\DscService\Configuration", - - # Is the endpoint for a DSC Compliance Server - [boolean] $IsComplianceServer - ) - - $desiredConfigurationMatch = $true; - - $website = Get-Website -Name $EndpointName - $stop = $true - - Do - { - Write-Verbose "Check Ensure" - if(($Ensure -eq "Present" -and $website -eq $null) -or ($Ensure -eq "Absent" -and $website -ne $null)) - { - $DesiredConfigurationMatch = $false - Write-Verbose "The Website $EndpointName is not present" - break - } - - Write-Verbose "Check Port" - $actualPort = $website.bindings.Collection[0].bindingInformation.Split(":")[1] - if ($Port -ne $actualPort) - { - $DesiredConfigurationMatch = $false - Write-Verbose "Port for the Website $EndpointName does not match the desired state." - break - } - - Write-Verbose "Check Physical Path property" - if(Test-WebsitePath -EndpointName $EndpointName -PhysicalPath $PhysicalPath) - { - $DesiredConfigurationMatch = $false - Write-Verbose "Physical Path of Website $EndpointName does not match the desired state." - break - } - - Write-Verbose "Check State" - if($website.state -ne $State -and $State -ne $null) - { - $DesiredConfigurationMatch = $false - Write-Verbose "The state of Website $EndpointName does not match the desired state." - break - } - - Write-Verbose "Get Full Path for Web.config file" - $webConfigFullPath = Join-Path $website.physicalPath "web.config" - if ($IsComplianceServer -eq $false) - { - Write-Verbose "Check ModulePath" - if ($ModulePath) - { - if (-not (Test-WebConfigAppSetting -WebConfigFullPath $webConfigFullPath -AppSettingName "ModulePath" -ExpectedAppSettingValue $ModulePath)) - { - $DesiredConfigurationMatch = $false - break - } - } - - Write-Verbose "Check ConfigurationPath" - if ($ConfigurationPath) - { - if (-not (Test-WebConfigAppSetting -WebConfigFullPath $webConfigFullPath -AppSettingName "ConfigurationPath" -ExpectedAppSettingValue $ConfigurationPath)) - { - $DesiredConfigurationMatch = $false - break - } - } - } - $stop = $false - } - While($stop) - - $desiredConfigurationMatch; -} - -# Helper function used to validate website path -function Test-WebsitePath -{ - param - ( - [string] $EndpointName, - [string] $PhysicalPath - ) - - $pathNeedsUpdating = $false - - if((Get-ItemProperty "IIS:\Sites\$EndpointName" -Name physicalPath) -ne $PhysicalPath) - { - $pathNeedsUpdating = $true - } - - $pathNeedsUpdating -} - -# Helper function to Test the specified Web.Config App Setting -function Test-WebConfigAppSetting -{ - param - ( - [string] $WebConfigFullPath, - [string] $AppSettingName, - [string] $ExpectedAppSettingValue - ) - - $returnValue = $true - - if (Test-Path $WebConfigFullPath) - { - $webConfigXml = [xml](get-content $WebConfigFullPath) - $root = $webConfigXml.get_DocumentElement() - - foreach ($item in $root.appSettings.add) - { - if( $item.key -eq $AppSettingName ) - { - break - } - } - - if($item.value -ne $ExpectedAppSettingValue) - { - $returnValue = $false - Write-Verbose "The state of Web.Config AppSetting $AppSettingName does not match the desired state." - } - - } - $returnValue -} - -# Helper function to Get the specified Web.Config App Setting -function Get-WebConfigAppSetting -{ - param - ( - [string] $WebConfigFullPath, - [string] $AppSettingName - ) - - $appSettingValue = "" - if (Test-Path $WebConfigFullPath) - { - $webConfigXml = [xml](get-content $WebConfigFullPath) - $root = $webConfigXml.get_DocumentElement() - - foreach ($item in $root.appSettings.add) - { - if( $item.key -eq $AppSettingName ) - { - $appSettingValue = $item.value - break - } - } - } - - $appSettingValue -} - -# Helper to get current script Folder -function Get-ScriptFolder -{ - $Invocation = (Get-Variable MyInvocation -Scope 1).Value - Split-Path $Invocation.MyCommand.Path -} - -# Allow this Website to enable/disable specific Auth Schemes by adding tag in applicationhost.config -function Update-LocationTagInApplicationHostConfigForAuthentication -{ - param ( - # Name of the WebSite - [String] $WebSite, - - # Authentication Type - [ValidateSet('anonymous', 'basic', 'windows')] - [String] $Authentication - ) - - [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Administration") | Out-Null - - $webAdminSrvMgr = new-object Microsoft.Web.Administration.ServerManager - - $appHostConfig = $webAdminSrvMgr.GetApplicationHostConfiguration() - - $authenticationType = $Authentication + "Authentication" - $appHostConfigSection = $appHostConfig.GetSection("system.webServer/security/authentication/$authenticationType", $WebSite) - $appHostConfigSection.OverrideMode="Allow" - $webAdminSrvMgr.CommitChanges() -} - -Export-ModuleMember -Function *-TargetResource - diff --git a/Resources/cPSDesiredStateConfiguration/PSWSIISEndpoint.psm1 b/Resources/cPSDesiredStateConfiguration/PSWSIISEndpoint.psm1 deleted file mode 100644 index 162d734..0000000 --- a/Resources/cPSDesiredStateConfiguration/PSWSIISEndpoint.psm1 +++ /dev/null @@ -1,584 +0,0 @@ -# This module file contains a utility to perform PSWS IIS Endpoint setup -# Module exports New-PSWSEndpoint function to perform the endpoint setup -# -# Copyright (c) Microsoft Corporation, 2013 -# -# Author: Raghu Shantha [RaghuS@Microsoft.com] -# ChangeLog: 7/11/2013 - Providing Dispatch/Port is now optional; Removed taking backup of existing endpoints since this was unnecessary and not performant; Logging only if something fails -# - -# Validate supplied configuration to setup the PSWS Endpoint -# Function checks for the existence of PSWS Schema files, IIS config -# Also validate presence of IIS on the target machine -# -function Initialize-Endpoint -{ - param ( - $site, - $path, - $cfgfile, - $port, - $app, - $applicationPoolIdentityType, - $svc, - $mof, - $dispatch, - $asax, - $dependentBinaries, - $language, - $dependentMUIFiles, - $psFiles, - $removeSiteFiles = $false, - $certificateThumbPrint) - - if (!(Test-Path $cfgfile)) - { - throw "ERROR: $cfgfile does not exist" - } - - if (!(Test-Path $svc)) - { - throw "ERROR: $svc does not exist" - } - - if (!(Test-Path $mof)) - { - throw "ERROR: $mof does not exist" - } - - if (!(Test-Path $asax)) - { - throw "ERROR: $asax does not exist" - } - - if ($certificateThumbPrint -ne "AllowUnencryptedTraffic") - { - Write-Verbose "Verify that the certificate with the provided thumbprint exists in CERT:\LocalMachine\MY\" - $certificate = Get-childItem CERT:\LocalMachine\MY\ | Where {$_.Thumbprint -eq $certificateThumbPrint} - if (!$Certificate) - { - throw "ERROR: Certificate with thumbprint $certificateThumbPrint does not exist in CERT:\LocalMachine\MY\" - } - } - - Test-IISInstall - - $appPool = "PSWS" - - Write-Verbose "Delete the App Pool if it exists" - Remove-AppPool -apppool $appPool - - Write-Verbose "Remove the site if it already exists" - Update-Site -siteName $site -siteAction Remove - - if ($removeSiteFiles) - { - if(Test-Path $path) - { - Remove-Item -Path $path -Recurse -Force - } - } - - Copy-Files -path $path -cfgfile $cfgfile -svc $svc -mof $mof -dispatch $dispatch -asax $asax -dependentBinaries $dependentBinaries -language $language -dependentMUIFiles $dependentMUIFiles -psFiles $psFiles - - Update-AllSites Stop - Update-DefaultAppPool Stop - Update-DefaultAppPool Start - - New-IISWebSite -site $site -path $path -port $port -app $app -apppool $appPool -applicationPoolIdentityType $applicationPoolIdentityType -certificateThumbPrint $certificateThumbPrint -} - -# Validate if IIS and all required dependencies are installed on the target machine -# -function Test-IISInstall -{ - Write-Verbose "Checking IIS requirements" - $iisVersion = (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\InetStp -ErrorAction silentlycontinue).MajorVersion + (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\InetStp -ErrorAction silentlycontinue).MinorVersion - - if ($iisVersion -lt 7.0) - { - throw "ERROR: IIS Version detected is $iisVersion , must be running higher than 7.0" - } - - $wsRegKey = (Get-ItemProperty hklm:\SYSTEM\CurrentControlSet\Services\W3SVC -ErrorAction silentlycontinue).ImagePath - if ($wsRegKey -eq $null) - { - throw "ERROR: Cannot retrive W3SVC key. IIS Web Services may not be installed" - } - - if ((Get-Service w3svc).Status -ne "running") - { - throw "ERROR: service W3SVC is not running" - } -} - -# Verify if a given IIS Site exists -# -function Test-IISSiteExists -{ - param ($siteName) - - if (Get-Website -Name $siteName) - { - return $true - } - - return $false -} - -# Perform an action (such as stop, start, delete) for a given IIS Site -# -function Update-Site -{ - param ( - [Parameter(ParameterSetName = 'SiteName', Mandatory, Position = 0)] - [ValidateNotNullOrEmpty()] - [String]$siteName, - - [Parameter(ParameterSetName = 'Site', Mandatory, Position = 0)] - $site, - - [Parameter(ParameterSetName = 'SiteName', Mandatory, Position = 1)] - [Parameter(ParameterSetName = 'Site', Mandatory, Position = 1)] - [String]$siteAction) - - [String]$name = $null - if ($PSCmdlet.ParameterSetName -eq 'SiteName') - { - $name = $siteName - } - elseif ($PSCmdlet.ParameterSetName -eq 'Site') - { - $name = $site.Name - } - - if (Test-IISSiteExists $name) - { - switch ($siteAction) - { - "Start" {Start-Website -Name $name} - "Stop" {Stop-Website -Name $name -ErrorAction SilentlyContinue} - "Remove" {Remove-Website -Name $name} - } - } -} - -# Delete the given IIS Application Pool -# This is required to cleanup any existing conflicting apppools before setting up the endpoint -# -function Remove-AppPool -{ - param ($appPool) - - Remove-WebAppPool -Name $appPool -ErrorAction SilentlyContinue -} - -# Perform given action(start, stop, delete) on all IIS Sites -# -function Update-AllSites -{ - param ($action) - - foreach ($site in Get-Website) - { - Update-Site $site $action - } -} - -# Perform given action(start, stop) on the default app pool -# -function Update-DefaultAppPool -{ - param ($action) - - switch ($action) - { - "Start" {Start-WebAppPool -Name "DefaultAppPool"} - "Stop" {Stop-WebAppPool -Name "DefaultAppPool"} - "Remove" {Remove-WebAppPool -Name "DefaultAppPool"} - } -} - -# Generate an IIS Site Id while setting up the endpoint -# The Site Id will be the max available in IIS config + 1 -# -function New-SiteID -{ - return ((Get-Website | % { $_.Id } | Measure-Object -Maximum).Maximum + 1) -} - -# Validate the PSWS config files supplied and copy to the IIS endpoint in inetpub -# -function Copy-Files -{ - param ( - $path, - $cfgfile, - $svc, - $mof, - $dispatch, - $asax, - $dependentBinaries, - $language, - $dependentMUIFiles, - $psFiles) - - if (!(Test-Path $cfgfile)) - { - throw "ERROR: $cfgfile does not exist" - } - - if (!(Test-Path $svc)) - { - throw "ERROR: $svc does not exist" - } - - if (!(Test-Path $mof)) - { - throw "ERROR: $mof does not exist" - } - - if (!(Test-Path $asax)) - { - throw "ERROR: $asax does not exist" - } - - if (!(Test-Path $path)) - { - $null = New-Item -ItemType container -Path $path - } - - foreach ($dependentBinary in $dependentBinaries) - { - if (!(Test-Path $dependentBinary)) - { - throw "ERROR: $dependentBinary does not exist" - } - } - - foreach ($dependentMUIFile in $dependentMUIFiles) - { - if (!(Test-Path $dependentMUIFile)) - { - throw "ERROR: $dependentMUIFile does not exist" - } - } - - Write-Verbose "Create the bin folder for deploying custom dependent binaries required by the endpoint" - $binFolderPath = Join-Path $path "bin" - $null = New-Item -path $binFolderPath -itemType "directory" -Force - Copy-Item $dependentBinaries $binFolderPath -Force - - if ($language) - { - $muiPath = Join-Path $binFolderPath $language - - if (!(Test-Path $muiPath)) - { - $null = New-Item -ItemType container $muiPath - } - Copy-Item $dependentMUIFiles $muiPath -Force - } - - foreach ($psFile in $psFiles) - { - if (!(Test-Path $psFile)) - { - throw "ERROR: $psFile does not exist" - } - - Copy-Item $psFile $path -Force - } - - Copy-Item $cfgfile (Join-Path $path "web.config") -Force - Copy-Item $svc $path -Force - Copy-Item $mof $path -Force - - if ($dispatch) - { - Copy-Item $dispatch $path -Force - } - - if ($asax) - { - Copy-Item $asax $path -Force - } -} - -# Setup IIS Apppool, Site and Application -# -function New-IISWebSite -{ - param ( - $site, - $path, - $port, - $app, - $appPool, - $applicationPoolIdentityType, - $certificateThumbPrint) - - $siteID = New-SiteID - - Write-Verbose "Adding App Pool" - $null = New-WebAppPool -Name $appPool - - Write-Verbose "Set App Pool Properties" - $appPoolIdentity = 4 - if ($applicationPoolIdentityType) - { - # LocalSystem = 0, LocalService = 1, NetworkService = 2, SpecificUser = 3, ApplicationPoolIdentity = 4 - if ($applicationPoolIdentityType -eq "LocalSystem") - { - $appPoolIdentity = 0 - } - elseif ($applicationPoolIdentityType -eq "LocalService") - { - $appPoolIdentity = 1 - } - elseif ($applicationPoolIdentityType -eq "NetworkService") - { - $appPoolIdentity = 2 - } - } - - $appPoolItem = Get-Item IIS:\AppPools\$appPool - $appPoolItem.managedRuntimeVersion = "v4.0" - $appPoolItem.enable32BitAppOnWin64 = $true - $appPoolItem.processModel.identityType = $appPoolIdentity - $appPoolItem | Set-Item - - Write-Verbose "Add and Set Site Properties" - if ($certificateThumbPrint -eq "AllowUnencryptedTraffic") - { - $webSite = New-WebSite -Name $site -Id $siteID -Port $port -IPAddress "*" -PhysicalPath $path -ApplicationPool $appPool - } - else - { - $webSite = New-WebSite -Name $site -Id $siteID -Port $port -IPAddress "*" -PhysicalPath $path -ApplicationPool $appPool -Ssl - - # Remove existing binding for $port - Remove-Item IIS:\SSLBindings\0.0.0.0!$port -ErrorAction Ignore - - # Create a new binding using the supplied certificate - $null = Get-Item CERT:\LocalMachine\MY\$certificateThumbPrint | New-Item IIS:\SSLBindings\0.0.0.0!$port - } - - Write-Verbose "Delete application" - Remove-WebApplication -Name $app -Site $site -ErrorAction SilentlyContinue - - Write-Verbose "Add and Set Application Properties" - $null = New-WebApplication -Name $app -Site $site -PhysicalPath $path -ApplicationPool $appPool - - Update-Site -siteName $site -siteAction Start -} - -# Allow Clients outsite the machine to access the setup endpoint on a User Port -# -function New-FirewallRule -{ - param ($firewallPort) - - Write-Verbose "Disable Inbound Firewall Notification" - Set-NetFirewallProfile -Profile Domain,Public,Private -NotifyOnListen False - - Write-Verbose "Add Firewall Rule for port $firewallPort" - $null = New-NetFirewallRule -DisplayName "Allow Port $firewallPort for PSWS" -Direction Inbound -LocalPort $firewallPort -Protocol TCP -Action Allow -} - -# Enable & Clear PSWS Operational/Analytic/Debug ETW Channels -# -function Enable-PSWSETW -{ - # Disable Analytic Log - & $script:wevtutil sl Microsoft-Windows-ManagementOdataService/Analytic /e:false /q | Out-Null - - # Disable Debug Log - & $script:wevtutil sl Microsoft-Windows-ManagementOdataService/Debug /e:false /q | Out-Null - - # Clear Operational Log - & $script:wevtutil cl Microsoft-Windows-ManagementOdataService/Operational | Out-Null - - # Enable/Clear Analytic Log - & $script:wevtutil sl Microsoft-Windows-ManagementOdataService/Analytic /e:true /q | Out-Null - - # Enable/Clear Debug Log - & $script:wevtutil sl Microsoft-Windows-ManagementOdataService/Debug /e:true /q | Out-Null -} - -<# -.Synopsis - Create PowerShell WebServices IIS Endpoint -.DESCRIPTION - Creates a PSWS IIS Endpoint by consuming PSWS Schema and related dependent files -.EXAMPLE - New a PSWS Endpoint [@ http://Server:39689/PSWS_Win32Process] by consuming PSWS Schema Files and any dependent scripts/binaries - New-PSWSEndpoint -site Win32Process -path $env:HOMEDRIVE\inetpub\wwwroot\PSWS_Win32Process -cfgfile Win32Process.config -port 39689 -app Win32Process -svc PSWS.svc -mof Win32Process.mof -dispatch Win32Process.xml -dependentBinaries ConfigureProcess.ps1, Rbac.dll -psFiles Win32Process.psm1 -#> -function New-PSWSEndpoint -{ -[CmdletBinding()] - param ( - - # Unique Name of the IIS Site - [String] $site = "PSWS", - - # Physical path for the IIS Endpoint on the machine (under inetpub/wwwroot) - [String] $path = "$env:HOMEDRIVE\inetpub\wwwroot\PSWS", - - # Web.config file - [String] $cfgfile = "web.config", - - # Port # for the IIS Endpoint - [Int] $port = 8080, - - # IIS Application Name for the Site - [String] $app = "PSWS", - - # IIS App Pool Identity Type - must be one of LocalService, LocalSystem, NetworkService, ApplicationPoolIdentity - [ValidateSet('LocalService', 'LocalSystem', 'NetworkService', 'ApplicationPoolIdentity')] - [String] $applicationPoolIdentityType, - - # WCF Service SVC file - [String] $svc = "PSWS.svc", - - # PSWS Specific MOF Schema File - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String] $mof, - - # PSWS Specific Dispatch Mapping File [Optional] - [ValidateNotNullOrEmpty()] - [String] $dispatch, - - # Global.asax file [Optional] - [ValidateNotNullOrEmpty()] - [String] $asax, - - # Any dependent binaries that need to be deployed to the IIS endpoint, in the bin folder - [ValidateNotNullOrEmpty()] - [String[]] $dependentBinaries, - - # MUI Language [Optional] - [ValidateNotNullOrEmpty()] - [String] $language, - - # Any dependent binaries that need to be deployed to the IIS endpoint, in the bin\mui folder [Optional] - [ValidateNotNullOrEmpty()] - [String[]] $dependentMUIFiles, - - # Any dependent PowerShell Scipts/Modules that need to be deployed to the IIS endpoint application root - [ValidateNotNullOrEmpty()] - [String[]] $psFiles, - - # True to remove all files for the site at first, false otherwise - [Boolean]$removeSiteFiles = $false, - - # Enable Firewall Exception for the supplied port - [Boolean] $EnableFirewallException, - - # Enable and Clear PSWS ETW - [switch] $EnablePSWSETW, - - # Thumbprint of the Certificate in CERT:\LocalMachine\MY\ for Pull Server - [String] $certificateThumbPrint = "AllowUnencryptedTraffic") - - $script:wevtutil = "$env:windir\system32\Wevtutil.exe" - - $svcName = Split-Path $svc -Leaf - $protocol = "https:" - if ($certificateThumbPrint -eq "AllowUnencryptedTraffic") - { - $protocol = "http:" - } - - # Get Machine Name and Domain - $cimInstance = Get-CimInstance -ClassName Win32_ComputerSystem - - Write-Verbose ("SETTING UP ENDPOINT at - $protocol//" + $cimInstance.Name + "." + $cimInstance.Domain + ":" + $port + "/" + $site + "/" + $svcName) - Initialize-Endpoint -site $site -path $path -cfgfile $cfgfile -port $port -app $app ` - -applicationPoolIdentityType $applicationPoolIdentityType -svc $svc -mof $mof ` - -dispatch $dispatch -asax $asax -dependentBinaries $dependentBinaries ` - -language $language -dependentMUIFiles $dependentMUIFiles -psFiles $psFiles ` - -removeSiteFiles $removeSiteFiles -certificateThumbPrint $certificateThumbPrint - - if ($EnableFirewallException -eq $true) - { - Write-Verbose "Enabling firewall exception for port $port" - $null = New-FirewallRule $port - } - - if ($EnablePSWSETW) - { - Enable-PSWSETW - } - - Update-AllSites start - -} - -<# -.Synopsis - Set the option into the web.config for an endpoint -.DESCRIPTION - Set the options into the web.config for an endpoint allowing customization. -.EXAMPLE -#> -function Set-AppSettingsInWebconfig -{ - param ( - - # Physical path for the IIS Endpoint on the machine (possibly under inetpub/wwwroot) - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String] $path, - - # Key to add/update - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String] $key, - - # Value - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String] $value - - ) - - $webconfig = Join-Path $path "web.config" - [bool] $Found = $false - - if (Test-Path $webconfig) - { - $xml = [xml](get-content $webconfig) - $root = $xml.get_DocumentElement() - - foreach( $item in $root.appSettings.add) - { - if( $item.key -eq $key ) - { - $item.value = $value; - $Found = $true; - } - } - - if( -not $Found) - { - $newElement = $xml.CreateElement("add") - $nameAtt1 = $xml.CreateAttribute("key") - $nameAtt1.psbase.value = $key; - $null = $newElement.SetAttributeNode($nameAtt1) - - $nameAtt2 = $xml.CreateAttribute("value") - $nameAtt2.psbase.value = $value; - $null = $newElement.SetAttributeNode($nameAtt2) - - $null = $xml.configuration["appSettings"].AppendChild($newElement) - } - } - - $xml.Save($webconfig) -} - -Export-ModuleMember -function New-PSWSEndpoint, Set-AppSettingsInWebconfig - diff --git a/Resources/cPSDesiredStateConfiguration/cPSDesiredStateConfiguration.psd1 b/Resources/cPSDesiredStateConfiguration/cPSDesiredStateConfiguration.psd1 deleted file mode 100644 index 2c8b4e6..0000000 --- a/Resources/cPSDesiredStateConfiguration/cPSDesiredStateConfiguration.psd1 +++ /dev/null @@ -1,36 +0,0 @@ -@{ -# Version number of this module. -ModuleVersion = '1.1.0.0' - -# ID used to uniquely identify this module -GUID = 'cc8dc021-fa5f-4f96-8ecf-dfd68a6d9d48' - -# Author of this module -Author = 'Microsoft Corporation' - -# Company or vendor of this module -CompanyName = 'Microsoft Corporation' - -# Copyright statement for this module -Copyright = '(c) 2014 Microsoft Corporation. All rights reserved.' - -# Description of the functionality provided by this module -Description = 'Module with DSC Resources for configuring Pull Server' - -# Minimum version of the Windows PowerShell engine required by this module -PowerShellVersion = '4.0' - -# Minimum version of the common language runtime (CLR) required by this module -CLRVersion = '4.0' - -# Script module or binary module file associated with this manifest. -RootModule = 'PSWSIISEndpoint.psm1' - -# Functions to export from this module -FunctionsToExport = '*' - -# Cmdlets to export from this module -CmdletsToExport = '*' -} - - diff --git a/Resources/cPSGet/DSCResources/PSHOrg_cPSGet/PSHOrg_cPSGet.psm1 b/Resources/cPSGet/DSCResources/PSHOrg_cPSGet/PSHOrg_cPSGet.psm1 deleted file mode 100644 index 2daa702..0000000 --- a/Resources/cPSGet/DSCResources/PSHOrg_cPSGet/PSHOrg_cPSGet.psm1 +++ /dev/null @@ -1,106 +0,0 @@ -function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] - param - ( - [parameter(Mandatory = $true)] - [System.String] - $Name, - - [parameter(Mandatory = $true)] - [ValidateSet("Absent","Present")] - [System.String] - $Ensure - ) - - Write-Verbose "Gathering Module info" - $return = @{ - Name = (Get-Module -Name $Name -ListAvailable).Name - Ensure = $Ensure - } -} - - -function Set-TargetResource -{ - [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - [System.String] - $Name, - - [parameter(Mandatory = $true)] - [ValidateSet("Absent","Present")] - [System.String] - $Ensure - ) - switch ($Ensure) - { - 'Present' { - Write-Verbose "adding module $Name" - Write-Debug "Module to be loaded: $Name" - Install-Module -Name $Name -Force - } - 'Absent' { - $path = (Get-Module -Name $Name -ListAvailable).ModuleBase - Write-Verbose "Removing module: $Name" - Write-Debug "Module path: $path" - Remove-Item -Path $path -Force -Recurse - } - } -} - - -function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Boolean])] - param - ( - [parameter(Mandatory = $true)] - [System.String] - $Name, - - [parameter(Mandatory = $true)] - [ValidateSet("Absent","Present")] - [System.String] - $Ensure - ) - if (Get-Module -Name $Name -ListAvailable) {$Exists = $true} - Else {$Exists = $false} - Switch ($Ensure) - { - 'Present' { - Switch ($Exists) - { - $true { - Write-Verbose "Module $Name is present on the system and ensure is set to $Ensure" - $true - } - $false { - Write-Verbose "Module $Name is absent from the system and ensure is set to $Ensure" - $false - } - } - } - 'Absent' { - Switch ($Exists) - { - $true { - Write-Verbose "Module $Name is present on the system and ensure is set to $Ensure" - $false - } - $false { - Write-Verbose "Module $Name is absent from the system and ensure is set to $Ensure" - $true - } - } - } - } - -} - - -Export-ModuleMember -Function *-TargetResource diff --git a/Resources/cPSGet/DSCResources/PSHOrg_cPSGet/PSHOrg_cPSGet.schema.mof b/Resources/cPSGet/DSCResources/PSHOrg_cPSGet/PSHOrg_cPSGet.schema.mof deleted file mode 100644 index 017e4a8..0000000 --- a/Resources/cPSGet/DSCResources/PSHOrg_cPSGet/PSHOrg_cPSGet.schema.mof +++ /dev/null @@ -1,8 +0,0 @@ - -[ClassVersion("1.0.0"), FriendlyName("cPSGet")] -class PSHOrg_cPSGet : OMI_BaseResource -{ - [Key, Description("Module name")] String Name; - [Required, ValueMap{"Absent","Present"}, Values{"Absent","Present"}] String Ensure; -}; - diff --git a/Resources/cPSGet/Readme.txt b/Resources/cPSGet/Readme.txt deleted file mode 100644 index 7356f62..0000000 --- a/Resources/cPSGet/Readme.txt +++ /dev/null @@ -1,28 +0,0 @@ -Hello, - -Thank you for evaluating cPSGet, the community DSC resource for PowerShellGet. - -This resource will allow you to use the PowerShellGet module from DSC. - -Example: -Configuration PSGet -{ -Param ($computername) - Import-DSCResource -ModuleName cPSGet - Node $ComputerName - { - cPSGet Testing - { - Name = 'bing' - Ensure = 'Present' - } - } -} - -***Warning*** -As of this writing, 7/18/2014, PowerShellGet requires the May WMF 5.0 preview. On an x64 system with windows 8.1 with update the nuget.exe file used by the SYSTEM account with PowerShellGet will fail to run. - -This issue has been filed with microsoft here: -https://connect.microsoft.com/PowerShell/feedback/details/922914/wmf-5-may-preview-powershellget-nuget-exe-wont-launch-when-running-as-system - -You can fix this issue by replacing the nuget.exe file at %winddir%\System32\config\systemprofile\AppData\Local\Microsoft\Windows\PowerShell\PowerShellGet\nuget.exe with a working version of nuget.exe. diff --git a/Resources/cPSGet/cPSGet.psd1 b/Resources/cPSGet/cPSGet.psd1 deleted file mode 100644 index 2cf0378..0000000 --- a/Resources/cPSGet/cPSGet.psd1 +++ /dev/null @@ -1,96 +0,0 @@ -# -# Module manifest for module 'PSHOrg_cPSGet' -# -# Generated by: @RJasonMorgan -# -# Generated on: 7/13/2014 -# - -@{ - -# Script module or binary module file associated with this manifest. -# RootModule = '' - -# Version number of this module. -ModuleVersion = '1.0' - -# ID used to uniquely identify this module -GUID = 'b06caa81-65c4-48ef-9b6a-9bc0eff34b94' - -# Author of this module -Author = 'Jason Morgan' - -# Company or vendor of this module -CompanyName = 'SpiderMan' - -# Copyright statement for this module -Copyright = '(c) 2014 no one at all. All rights reserved.' - -# Description of the functionality provided by this module -# Description = '' - -# Minimum version of the Windows PowerShell engine required by this module -# PowerShellVersion = '' - -# Name of the Windows PowerShell host required by this module -# PowerShellHostName = '' - -# Minimum version of the Windows PowerShell host required by this module -# PowerShellHostVersion = '' - -# Minimum version of Microsoft .NET Framework required by this module -# DotNetFrameworkVersion = '' - -# Minimum version of the common language runtime (CLR) required by this module -# CLRVersion = '' - -# Processor architecture (None, X86, Amd64) required by this module -# ProcessorArchitecture = '' - -# Modules that must be imported into the global environment prior to importing this module -RequiredModules = @('PowerShellGet') - -# Assemblies that must be loaded prior to importing this module -# RequiredAssemblies = @() - -# Script files (.ps1) that are run in the caller's environment prior to importing this module. -# ScriptsToProcess = @() - -# Type files (.ps1xml) to be loaded when importing this module -# TypesToProcess = @() - -# Format files (.ps1xml) to be loaded when importing this module -# FormatsToProcess = @() - -# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess -# NestedModules = @() - -# Functions to export from this module -FunctionsToExport = '*' - -# Cmdlets to export from this module -CmdletsToExport = '*' - -# Variables to export from this module -VariablesToExport = '*' - -# Aliases to export from this module -AliasesToExport = '*' - -# List of all modules packaged with this module -# ModuleList = @() - -# List of all files packaged with this module -# FileList = @() - -# Private data to pass to the module specified in RootModule/ModuleToProcess -# PrivateData = '' - -# HelpInfo URI of this module -# HelpInfoURI = '' - -# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. -# DefaultCommandPrefix = '' - -} - diff --git a/Resources/cRDPEnabled/DSCResources/PSHOrg_cRDPEnabled/PSHOrg_cRDPEnabled.psm1 b/Resources/cRDPEnabled/DSCResources/PSHOrg_cRDPEnabled/PSHOrg_cRDPEnabled.psm1 deleted file mode 100644 index 108987a..0000000 --- a/Resources/cRDPEnabled/DSCResources/PSHOrg_cRDPEnabled/PSHOrg_cRDPEnabled.psm1 +++ /dev/null @@ -1,160 +0,0 @@ -function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] - param - ( - [parameter(Mandatory = $true)] - [System.Boolean] - $Enabled, - - [System.Boolean] - $NLARequired = $true, - - [System.Boolean] - $EnableDefaultFirewallRule = $true - ) - - Write-Verbose "Starting Get operation" - [Boolean]$CurrentRDPEnabled = (Get-CimInstance -Namespace root/cimv2/TerminalServices -ClassName Win32_TerminalServiceSetting -ErrorAction Stop).AllowTSConnections - [Boolean]$CurrentNLARequired = (Get-CimInstance -Namespace root/cimv2/TerminalServices -ClassName Win32_TSGeneralSetting -ErrorAction Stop).UserAuthenticationRequired - [Boolean]$CurrentEnableDefaultFirewallRule = $true - $FirewallRules = Get-NetFirewallRule -DisplayName "Remote Desktop - User Mode (TCP-In)","Remote Desktop - User Mode (UDP-In)" -ErrorAction Stop - - if ($CurrentRDPEnabled) { - foreach ($rule in $FirewallRules) { - if ($rule.Enabled -ne "True") { - $CurrentEnableDefaultFirewallRule = $false - break - } - } - } - else { # We don't care about the result if RDP is not enabled - $CurrentEnableDefaultFirewallRule = $false - } - - @{ - Enabled = $CurrentRDPEnabled; - NLARequired = $CurrentNLARequired; - EnableDefaultFirewallRule = $CurrentEnableDefaultFirewallRule - } - - Write-Verbose "Completed Get operation" -} - - -function Set-TargetResource -{ - [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - [System.Boolean] - $Enabled, - - [System.Boolean] - $NLARequired = $true, - - [System.Boolean] - $EnableDefaultFirewallRule = $true - ) - - Write-Verbose "Starting Set operation" - Write-Debug "Calling Invoke-CimMethod on win32_TerminalServiceSetting" - Switch ($Enabled) - { - $true { - Write-Verbose 'Beginning operation to set RDP to enabled' - - try { - Get-CimInstance -Namespace root\cimv2\TerminalServices -ClassName Win32_TerminalServiceSetting -ErrorAction Stop | - Invoke-CimMethod -MethodName SetAllowTSConnections -Arguments @{AllowTSConnections=1} -ErrorAction Stop - } - catch { - Write-Error "Error during Invoke-CimMethod. This might happen if you have a GPO that forces the RDP configuration on the server.`n$_" - } - - Write-Verbose 'Completed Set RDP to enabled.' - - if ($EnableDefaultFirewallRule) { - Write-Verbose "Beginning operation to enable default Remote Desktop firewall rules" - Get-NetFirewallRule -DisplayName "Remote Desktop - User Mode (TCP-In)","Remote Desktop - User Mode (UDP-In)" -ErrorAction Stop | Enable-NetFirewallRule -ErrorAction Stop - Write-Verbose 'Completed operation to enable default Remote Desktop firewall rules' - } - } - $false { - Write-Verbose 'Beginning operation to set RDP to disabled' - - try { - Get-CimInstance -Namespace root\cimv2\TerminalServices -ClassName Win32_TerminalServiceSetting -ErrorAction Stop | - Invoke-CimMethod -MethodName SetAllowTSConnections -Arguments @{AllowTSConnections=0;ModifyFirewallException=1} -ErrorAction Stop # ModifyFirewallException will close the 'Remote Desktop' group firewall rule, if it's enabled - } - catch { - Write-Error "Error during Invoke-CimMethod. This might happen if you have a GPO that forces the RDP configuration on the server.`n$_" - } - - Write-Verbose 'Completed Set RDP to disabled.' - } - } - Write-Debug "Completed Invoke-CimMethod on win32_TerminalServiceSetting" - - Write-Debug "Calling Invoke-CimMethod on win32_TSGeneralSetting" - - Write-Verbose "Beginning operation to set NLA required to $NLARequired" - Get-CimInstance -Class "win32_TSGeneralSetting" -Namespace root\cimv2\terminalservices -Filter "TerminalName='RDP-tcp'" -ErrorAction Stop | - Invoke-CimMethod -MethodName SetUserAuthenticationRequired -Arguments @{UserAuthenticationRequired=[int]$NLARequired} - - Write-Debug "Completed Invoke-CimMethod on win32_TSGeneralSetting" - - Write-Verbose "Set operation complete" - -} - - -function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Boolean])] - param - ( - [parameter(Mandatory = $true)] - [System.Boolean] - $Enabled, - - [System.Boolean] - $NLARequired = $true, - - [System.Boolean] - $EnableDefaultFirewallRule = $true - ) - - Write-Verbose "Beginning Test operation" - [Boolean]$CurrentRDPEnabled = (Get-CimInstance -Namespace root/cimv2/TerminalServices -ClassName Win32_TerminalServiceSetting -ErrorAction Stop).AllowTSConnections - [Boolean]$CurrentNLARequired = (Get-CimInstance -Namespace root/cimv2/TerminalServices -ClassName Win32_TSGeneralSetting -Filter "TerminalName='RDP-tcp'" -ErrorAction Stop).UserAuthenticationRequired - $fwRules = Get-NetFirewallRule -DisplayName "Remote Desktop - User Mode (TCP-In)","Remote Desktop - User Mode (UDP-In)" -ErrorAction Stop - - if ($CurrentRDPEnabled -ne $Enabled) { - Write-Verbose ("Configuration mismatch for Enabled. Current value: {0}. Expected value: {1}" -f $CurrentRDPEnabled, $Enabled) - return $false - } - - if ($CurrentNLARequired -ne $NLARequired) { - Write-Verbose ("Configuration mismatch for NLARequired. Current value: {0}. Expected value: {1}" -f $CurrentNLARequired, $NLARequired) - return $false - } - - if ($CurrentRDPEnabled -and $EnableDefaultFirewallRule) { # We don't care about the result if RDP is not enabled - foreach ($rule in $fwRules) { - if (($rule.Enabled -eq "True") -ne $true) { - Write-Verbose ("Configuration mismatch for EnableDefaultFirewallRule. {0} is {1}. Expected {2}" -f $rule.DisplayName, $rule.Enabled, $EnableDefaultFirewallRule) - return $false - } - } - } - - Write-Verbose "Test operation complete without configuration mismatch" - - return $true -} - -Export-ModuleMember -Function *-TargetResource \ No newline at end of file diff --git a/Resources/cRDPEnabled/DSCResources/PSHOrg_cRDPEnabled/PSHOrg_cRDPEnabled.schema.mof b/Resources/cRDPEnabled/DSCResources/PSHOrg_cRDPEnabled/PSHOrg_cRDPEnabled.schema.mof deleted file mode 100644 index 0785f70..0000000 --- a/Resources/cRDPEnabled/DSCResources/PSHOrg_cRDPEnabled/PSHOrg_cRDPEnabled.schema.mof +++ /dev/null @@ -1,9 +0,0 @@ - -[ClassVersion("1.0.0.0"), FriendlyName("cRDPEnabled")] -class PSHOrg_cRDPEnabled : OMI_BaseResource -{ - [Key, Description("Set to indicate if RDP for remote administration should be enabled or not")] Boolean Enabled; - [Write, Description("Require Network Level Authentication. Default value is true")] Boolean NLARequired; - [Write, Description("Enables the default Remote Desktop firewall rules in Windows Firewall. If set to false, the firewall rules will be left as is, no changes will be made. Default value is true")] Boolean EnableDefaultFirewallRule; -}; - diff --git a/Resources/cRDPEnabled/cRDPEnabled.psd1 b/Resources/cRDPEnabled/cRDPEnabled.psd1 deleted file mode 100644 index 71159a6..0000000 --- a/Resources/cRDPEnabled/cRDPEnabled.psd1 +++ /dev/null @@ -1,96 +0,0 @@ -# -# Module manifest for module 'cRDPEnabled' -# -# Generated by: jmorg_000 -# -# Generated on: 7/15/2014 -# - -@{ - -# Script module or binary module file associated with this manifest. -# RootModule = '' - -# Version number of this module. -ModuleVersion = '1.1.2' - -# ID used to uniquely identify this module -GUID = 'c099d5e8-d953-44b7-8f84-ccde92926be7' - -# Author of this module -Author = 'jmorg_000. Modified by Dennis Rye (llstrk)' - -# Company or vendor of this module -CompanyName = 'Unknown' - -# Copyright statement for this module -Copyright = '(c) 2014 jmorg_000. All rights reserved.' - -# Description of the functionality provided by this module -# Description = '' - -# Minimum version of the Windows PowerShell engine required by this module -# PowerShellVersion = '' - -# Name of the Windows PowerShell host required by this module -# PowerShellHostName = '' - -# Minimum version of the Windows PowerShell host required by this module -# PowerShellHostVersion = '' - -# Minimum version of Microsoft .NET Framework required by this module -# DotNetFrameworkVersion = '' - -# Minimum version of the common language runtime (CLR) required by this module -# CLRVersion = '' - -# Processor architecture (None, X86, Amd64) required by this module -# ProcessorArchitecture = '' - -# Modules that must be imported into the global environment prior to importing this module -# RequiredModules = @() - -# Assemblies that must be loaded prior to importing this module -# RequiredAssemblies = @() - -# Script files (.ps1) that are run in the caller's environment prior to importing this module. -# ScriptsToProcess = @() - -# Type files (.ps1xml) to be loaded when importing this module -# TypesToProcess = @() - -# Format files (.ps1xml) to be loaded when importing this module -# FormatsToProcess = @() - -# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess -# NestedModules = @() - -# Functions to export from this module -FunctionsToExport = '*' - -# Cmdlets to export from this module -CmdletsToExport = '*' - -# Variables to export from this module -VariablesToExport = '*' - -# Aliases to export from this module -AliasesToExport = '*' - -# List of all modules packaged with this module -# ModuleList = @() - -# List of all files packaged with this module -# FileList = @() - -# Private data to pass to the module specified in RootModule/ModuleToProcess -# PrivateData = '' - -# HelpInfo URI of this module -# HelpInfoURI = '' - -# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. -# DefaultCommandPrefix = '' - -} - diff --git a/Resources/cSmbShare/DscResources/PSHOrg_cSmbShare/PSHOrg_cSmbShare.psm1 b/Resources/cSmbShare/DscResources/PSHOrg_cSmbShare/PSHOrg_cSmbShare.psm1 deleted file mode 100644 index cc9ef85..0000000 --- a/Resources/cSmbShare/DscResources/PSHOrg_cSmbShare/PSHOrg_cSmbShare.psm1 +++ /dev/null @@ -1,352 +0,0 @@ -function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] - param - ( - [parameter(Mandatory = $true)] - [System.String] - $Name, - - [parameter(Mandatory = $true)] - [System.String] - $Path - ) - - $smbShare = Get-SmbShare -Name $Name -ErrorAction SilentlyContinue - $changeAccess = @() - $readAccess = @() - $fullAccess = @() - $noAccess = @() - if ($smbShare -ne $null) - { - $smbShareAccess = Get-SmbShareAccess -Name $Name - $smbShareAccess | % { - $access = $_; - if ($access.AccessRight -eq 'Change' -and $access.AccessControlType -eq 'Allow') - { - $changeAccess += $access.AccountName - } - elseif ($access.AccessRight -eq 'Read' -and $access.AccessControlType -eq 'Allow') - { - $readAccess += $access.AccountName - } - elseif ($access.AccessRight -eq 'Full' -and $access.AccessControlType -eq 'Allow') - { - $fullAccess += $access.AccountName - } - elseif ($access.AccessRight -eq 'Full' -and $access.AccessControlType -eq 'Deny') - { - $noAccess += $access.AccountName - } - } - } - else - { - Write-Verbose "Share with name $Name does not exist" - } - - $returnValue = @{ - Name = $smbShare.Name - Path = $smbShare.Path - Description = $smbShare.Description - ConcurrentUserLimit = $smbShare.ConcurrentUserLimit - EncryptData = $smbShare.EncryptData - FolderEnumerationMode = $smbShare.FolderEnumerationMode - ShareState = $smbShare.ShareState - ShareType = $smbShare.ShareType - ShadowCopy = $smbShare.ShadowCopy - Special = $smbShare.Special - ChangeAccess = $changeAccess - ReadAccess = $readAccess - FullAccess = $fullAccess - NoAccess = $noAccess - Ensure = if($smbShare) {"Present"} else {"Absent"} - } - - $returnValue -} - -function Set-AccessPermission -{ - [CmdletBinding()] - Param - ( - $ShareName, - - [string[]] - $UserName, - - [string] - [ValidateSet("Change","Full","Read","No")] - $AccessPermission - ) - $formattedString = '{0}{1}' -f $AccessPermission,"Access" - Write-Verbose -Message "Setting $formattedString for $UserName" - - if ($AccessPermission -eq "Change" -or $AccessPermission -eq "Read" -or $AccessPermission -eq "Full") - { - Grant-SmbShareAccess -Name $Name -AccountName $UserName -AccessRight $AccessPermission -Force - } - else - { - Block-SmbShareAccess -Name $Name -AccountName $userName -Force - } -} - -function Remove-AccessPermission -{ - [CmdletBinding()] - Param - ( - $ShareName, - - [string[]] - $UserName, - - [string] - [ValidateSet("Change","Full","Read","No")] - $AccessPermission - ) - $formattedString = '{0}{1}' -f $AccessPermission,"Access" - Write-Debug -Message "Removing $formattedString for $UserName" - - if ($AccessPermission -eq "Change" -or $AccessPermission -eq "Read" -or $AccessPermission -eq "Full") - { - Revoke-SmbShareAccess -Name $Name -AccountName $UserName -Force - } - else - { - UnBlock-SmbShareAccess -Name $Name -AccountName $userName -Force - } -} - -function Set-TargetResource -{ - [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - [System.String] - $Name, - - [parameter(Mandatory = $true)] - [System.String] - $Path, - - [System.String] - $Description, - - [System.String[]] - $ChangeAccess, - - [System.UInt32] - $ConcurrentUserLimit, - - [System.Boolean] - $EncryptData, - - [ValidateSet("AccessBased","Unrestricted")] - [System.String] - $FolderEnumerationMode, - - [System.String[]] - $FullAccess, - - [System.String[]] - $NoAccess, - - [System.String[]] - $ReadAccess, - - [ValidateSet("Present","Absent")] - [System.String] - $Ensure - ) - - $psboundparameters.Remove("Debug") - - $shareExists = $false - $smbShare = Get-SmbShare -Name $Name -ErrorAction SilentlyContinue - if($smbShare -ne $null) - { - Write-Verbose -Message "Share with name $Name exists" - $shareExists = $true - } - if ($Ensure -eq "Present") - { - if ($shareExists -eq $false) - { - $psboundparameters.Remove("Ensure") - Write-Verbose "Creating share $Name to ensure it is Present" - New-SmbShare @psboundparameters - } - else - { - # Need to call either Set-SmbShare or *ShareAccess cmdlets - if ($psboundparameters.ContainsKey("ChangeAccess")) - { - $changeAccessValue = $psboundparameters["ChangeAccess"] - $psboundparameters.Remove("ChangeAccess") - } - if ($psboundparameters.ContainsKey("ReadAccess")) - { - $readAccessValue = $psboundparameters["ReadAccess"] - $psboundparameters.Remove("ReadAccess") - } - if ($psboundparameters.ContainsKey("FullAccess")) - { - $fullAccessValue = $psboundparameters["FullAccess"] - $psboundparameters.Remove("FullAccess") - } - if ($psboundparameters.ContainsKey("NoAccess")) - { - $noAccessValue = $psboundparameters["NoAccess"] - $psboundparameters.Remove("NoAccess") - } - - # Use Set-SmbShare for performing operations other than changing access - $psboundparameters.Remove("Ensure") - $psboundparameters.Remove("Path") - Set-SmbShare @PSBoundParameters -Force - - # Use *SmbShareAccess cmdlets to change access - $smbshareAccessValues = Get-SmbShareAccess -Name $Name - if ($ChangeAccess -ne $null) - { - # Blow off whatever is in there and replace it with this list - $smbshareAccessValues | ? {$_.AccessControlType -eq 'Allow' -and $_.AccessRight -eq 'Change'} ` - | % { - Remove-AccessPermission -ShareName $Name -UserName $_.AccountName -AccessPermission Change - } - - $changeAccessValue | % { - Set-AccessPermission -ShareName $Name -AccessPermission "Change" -Username $_ - } - } - $smbshareAccessValues = Get-SmbShareAccess -Name $Name - if ($ReadAccess -ne $null) - { - # Blow off whatever is in there and replace it with this list - $smbshareAccessValues | ? {$_.AccessControlType -eq 'Allow' -and $_.AccessRight -eq 'Read'} ` - | % { - Remove-AccessPermission -ShareName $Name -UserName $_.AccountName -AccessPermission Read - } - - $readAccessValue | % { - Set-AccessPermission -ShareName $Name -AccessPermission "Read" -Username $_ - } - } - $smbshareAccessValues = Get-SmbShareAccess -Name $Name - if ($FullAccess -ne $null) - { - # Blow off whatever is in there and replace it with this list - $smbshareAccessValues | ? {$_.AccessControlType -eq 'Allow' -and $_.AccessRight -eq 'Full'} ` - | % { - Remove-AccessPermission -ShareName $Name -UserName $_.AccountName -AccessPermission Full - } - - $fullAccessValue | % { - Set-AccessPermission -ShareName $Name -AccessPermission "Full" -Username $_ - } - } - $smbshareAccessValues = Get-SmbShareAccess -Name $Name - if ($NoAccess -ne $null) - { - # Blow off whatever is in there and replace it with this list - $smbshareAccessValues | ? {$_.AccessControlType -eq 'Deny'} ` - | % { - Remove-AccessPermission -ShareName $Name -UserName $_.AccountName -AccessPermission No - } - $noAccessValue | % { - Set-AccessPermission -ShareName $Name -AccessPermission "No" -Username $_ - } - } - } - } - else - { - Write-Verbose "Removing share $Name to ensure it is Absent" - Remove-SmbShare -name $Name -Force - } -} - -function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Boolean])] - param - ( - [parameter(Mandatory = $true)] - [System.String] - $Name, - - [parameter(Mandatory = $true)] - [System.String] - $Path, - - [System.String] - $Description, - - [System.String[]] - $ChangeAccess, - - [System.UInt32] - $ConcurrentUserLimit, - - [System.Boolean] - $EncryptData, - - [ValidateSet("AccessBased","Unrestricted")] - [System.String] - $FolderEnumerationMode, - - [System.String[]] - $FullAccess, - - [System.String[]] - $NoAccess, - - [System.String[]] - $ReadAccess, - - [ValidateSet("Present","Absent")] - [System.String] - $Ensure - ) - $testResult = $false; - $share = Get-SmbShare -Name $Name -ErrorAction SilentlyContinue -ErrorVariable ev - if ($Ensure -eq "Present") - { - if ($share -eq $null) - { - $testResult = $false - } - elseif ($share -ne $null -and $PSBoundParameters.Count -gt 3) - # This means some other parameter in addition to Name, Path, Ensure could have been specified - # Which means we need to modify something - { - $testResult = $false - } - else - { - $testResult = $true - } - } - else - { - if ($share -eq $null) - { - $testResult = $true - } - else - { - $testResult = $false - } - } - - $testResult -} - -Export-ModuleMember -Function *-TargetResource - diff --git a/Resources/cSmbShare/DscResources/PSHOrg_cSmbShare/PSHOrg_cSmbShare.schema.mof b/Resources/cSmbShare/DscResources/PSHOrg_cSmbShare/PSHOrg_cSmbShare.schema.mof deleted file mode 100644 index ac5cde9..0000000 --- a/Resources/cSmbShare/DscResources/PSHOrg_cSmbShare/PSHOrg_cSmbShare.schema.mof +++ /dev/null @@ -1,23 +0,0 @@ - -[ClassVersion("1.0.0.0"), FriendlyName("cSmbShare")] -class PSHOrg_cSmbShare : OMI_BaseResource -{ - [Key, Description("Name of the SMB Share")] String Name; - [Required, Description("Path to the share")] String Path; - [Write, Description("Description of the share")] String Description; - [Write, Description("Specifies which user will be granted modify permission to access the share")] String ChangeAccess[]; - [Write, Description("Specifies the maximum number of concurrently connected users that the new SMB share may accommodate. If this parameter is set to zero (0), then the number of users is unlimited. The default value is zero (0).")] Uint32 ConcurrentUserLimit; - [Write, Description("Indicates that the share is encrypted.")] Boolean EncryptData; - [Write, Description("Specifies which files and folders in the new SMB share are visible to users."), ValueMap{"AccessBased","Unrestricted"}, Values{"AccessBased","Unrestricted"}] String FolderEnumerationMode; - [Write, Description("Specifies which accounts are granted full permission to access the share.")] String FullAccess[]; - [Write, Description("Specifies which accounts are denied access to the share.")] String NoAccess[]; - [Write, Description("Specifies which user is granted read permission to access the share.")] String ReadAccess[]; - [Write, Description("Specifies if the share should be added or removed"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; - [Read, Description("Specfies the state of the share")] String ShareState; - [Read, Description("Specfies the type of the share")] String ShareType; - [Read, Description("Specifies if this share is a ShadowCopy")] String ShadowCopy; - [Read, Description("Specifies if this share is a Special Share. Admin share, default shares, IPC$ share are examples.")] String Special; -}; - - - diff --git a/Resources/cSmbShare/cSmbShare.psd1 b/Resources/cSmbShare/cSmbShare.psd1 deleted file mode 100644 index 6b7a8dd..0000000 --- a/Resources/cSmbShare/cSmbShare.psd1 +++ /dev/null @@ -1,34 +0,0 @@ -@{ -# Version number of this module. -ModuleVersion = '1.0' - -# ID used to uniquely identify this module -GUID = '8831ca9a-3c47-4a5b-b401-29635dd24381' - -# Author of this module -Author = 'Microsoft Corporation' - -# Company or vendor of this module -CompanyName = 'Microsoft Corporation' - -# Copyright statement for this module -Copyright = '(c) 2013 Microsoft Corporation. All rights reserved.' - -# Description of the functionality provided by this module -Description = 'Module with DSC Resources for SmbShare area' - -# Minimum version of the Windows PowerShell engine required by this module -PowerShellVersion = '4.0' - -# Minimum version of the common language runtime (CLR) required by this module -CLRVersion = '4.0' - -# Functions to export from this module -FunctionsToExport = '*' - -# Cmdlets to export from this module -CmdletsToExport = '*' -} - - - diff --git a/Resources/cSqlPs/DSCResources/PSHOrg_cSqlHAEndPoint/PSHOrg_cSqlHAEndPoint.psm1 b/Resources/cSqlPs/DSCResources/PSHOrg_cSqlHAEndPoint/PSHOrg_cSqlHAEndPoint.psm1 deleted file mode 100644 index f360626..0000000 --- a/Resources/cSqlPs/DSCResources/PSHOrg_cSqlHAEndPoint/PSHOrg_cSqlHAEndPoint.psm1 +++ /dev/null @@ -1,157 +0,0 @@ -# -# xSqlEndPoint: DSC resouce to configure the given instance of Sql High Availability Service to listen port 5022 -# with given name, and to assign $AllowedUser to communicate the service through that endpoint. -# - -# -# The Get-TargetResource cmdlet. -# -function Get-TargetResource -{ - param - ( - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $InstanceName, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $AllowedUser, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $Name, - - [ValidateRange(1000,9999)] - [Uint32] $PortNumber = 5022 - ) - - $bConfigured = Test-TargetResource -InstanceName $InstanceName -AllowedUser $AllowedUser -Name $Name - - $returnValue = @{ - ServerInstance = $InstanceName - AllowedUser = $AllowedUser - EndPointName = $Name - PortNumber = $PortNumber - Configured = $bConfigured - } - - $returnValue -} - -# -# The Set-TargetResource cmdlet. -# -function Set-TargetResource -{ - param - ( - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $InstanceName, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $AllowedUser, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $Name, - - [ValidateRange(1000,9999)] - [Uint32] $PortNumber = 5022 - ) - - Write-Verbose -Message "Set EndPoint $Name on instance $InstanceName ..." - - try - { - $endpoint = New-SqlHadrEndpoint $Name -Port $PortNumber -Path "SQLSERVER:\SQL\$InstanceName" - Set-SqlHadrEndpoint -InputObject $endpoint -State "Started" - - OSQL -S $InstanceName -E -Q "GRANT CONNECT ON ENDPOINT::[$Name] TO [$AllowedUser]" - } - catch { - Write-Verbose -Message "Set EndPoint $Name on instance $InstanceName reached exception." - throw $_ - } - -} - -# -# The Test-TargetResource cmdlet. -# -function Test-TargetResource -{ - param - ( - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $InstanceName, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $AllowedUser, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $Name, - - [ValidateRange(1000,9999)] - [Uint32] $PortNumber = 5022 - ) - - if (!(Check-SqlInstance -InstanceName $InstanceName)) - { - Write-Verbose -Message "Can't find Sql Server instance $InstanceName" - return $false - } - - - Write-Verbose -Message "Test EndPoint $Name on instance $InstanceName ..." - - $endpoint = OSQL -S $InstanceName -E -Q "select count(*) from master.sys.endpoints where name = '$Name'" -h-1 - - return ([bool] [int] $endpoint[0].Trim() ) -} - -function Get-PureInstanceName ($InstanceName) -{ - $list = $InstanceName.Split("\") - if ($list.Count -gt 1) - { - $list[1] - } - else - { - "MSSQLSERVER" - } -} - -function Check-SqlInstance($InstanceName) -{ - $list = Get-Service -Name MSSQL* - $retInstanceName = $null - - $pureInstanceName = Get-PureInstanceName -InstanceName $InstanceName - - if ($pureInstanceName -eq "MSSQLSERVER") - { - if ($list.Name -contains "MSSQLSERVER") - { - $retInstanceName = $InstanceName - } - } - elseif ($list.Name -contains $("MSSQL$" + $pureInstanceName)) - { - Write-Verbose -Message "SQL Instance $InstanceName is present" - $retInstanceName = $pureInstanceName - } - - return ($retInstanceName -ne $null) -} - - -Export-ModuleMember -Function *-TargetResource - - diff --git a/Resources/cSqlPs/DSCResources/PSHOrg_cSqlHAEndPoint/PSHOrg_cSqlHAEndPoint.schema.mof b/Resources/cSqlPs/DSCResources/PSHOrg_cSqlHAEndPoint/PSHOrg_cSqlHAEndPoint.schema.mof deleted file mode 100644 index 5b4101a..0000000 --- a/Resources/cSqlPs/DSCResources/PSHOrg_cSqlHAEndPoint/PSHOrg_cSqlHAEndPoint.schema.mof +++ /dev/null @@ -1,13 +0,0 @@ -#pragma namespace("\\\\.\\root\\microsoft\\windows\\DesiredStateConfiguration") - -[ClassVersion("1.0.0"), FriendlyName("cSqlHAEndPoint")] -class PSHOrg_cSqlHAEndPoint : OMI_BaseResource -{ - [key, Description("Name of Sql Instance.")] string InstanceName; - - [required, Description("Windows Account that could access the HA database mirroring endpoing.")] string AllowedUser; - [key, Description("Unique name for HA database mirroring endpoint of the sql instance.")] string Name; - [write, Description("The single port number(nnnn) on which the Sql HA to listen to.")] Uint32 PortNumber; -}; - - diff --git a/Resources/cSqlPs/DSCResources/PSHOrg_cSqlHAGroup/PSHOrg_cSqlHAGroup.psm1 b/Resources/cSqlPs/DSCResources/PSHOrg_cSqlHAGroup/PSHOrg_cSqlHAGroup.psm1 deleted file mode 100644 index e339126..0000000 --- a/Resources/cSqlPs/DSCResources/PSHOrg_cSqlHAGroup/PSHOrg_cSqlHAGroup.psm1 +++ /dev/null @@ -1,424 +0,0 @@ -# -# xSqlHAGroup: DSC resource to configure a Sql High Availability (HA) Group. If the HA Group does not exist, it will -# create one with given name on given sql instance, it also adds the database(s) to the group. If the HA group -# already exists, it will join sql instance to the group, replicate the database(s) in the group to local instance. -# - -# -# The Get-TargetResource cmdlet. -# -function Get-TargetResource -{ - param - ( - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $Name, - - [parameter(Mandatory)] - [ValidateNotNull()] - [string[]] $Database, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $ClusterName, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $DatabaseBackupPath, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $InstanceName, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $EndpointName, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [PSCredential] $DomainCredential, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [PSCredential] $SqlAdministratorCredential - ) - - if ($Database.Count -lt 1) - { - throw "Parameter Database does not have any database" - } - - $bConfigured = Test-TargetResource -Name $Name -Database $Database -ClusterName $ClusterName -DatabaseBackupPath $DatabaseBackupPath -InstanceName $InstanceName -EndpointName $EndpointName -DomainCredential $DomainCredential -SqlAdministratorCredential $SqlAdministratorCredential - - $returnValue = @{ - - Database = $Database - Name = $Name - ClusterName = $ClusterName - DatabaseBackupPath = $DatabaseBackupPath - InstanceName = $InstanceName - EndpointName = $EndpointName - - DomainCredential = $DomainCredential.UserName - SqlAdministratorCredential = $SqlAdministratorCredential.UserName - - Configured = $bConfigured - } - - $returnValue -} - -# -# The Set-TargetResource cmdlet. -# -function Set-TargetResource -{ - param - ( - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $Name, - - [parameter(Mandatory)] - [ValidateNotNull()] - [string[]] $Database, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $ClusterName, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $DatabaseBackupPath, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $InstanceName, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $EndpointName, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [PSCredential] $DomainCredential, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [PSCredential] $SqlAdministratorCredential - ) - - if ($Database.Count -lt 1) - { - throw "Parameter Database does not have any database" - } - - Write-Verbose -Message "Checking if SQL HAG $Name is present ..." - Write-Verbose -Message "Cluster: $ClusterName, Database: $Database" - - $bHAGExist = $false - $primaryReplica = $InstanceName - - $sa = $SqlAdministratorCredential.UserName - $saPassword = $SqlAdministratorCredential.GetNetworkCredential().Password - - try - { - ($oldToken, $context, $newToken) = ImpersonateAs -cred $DomainCredential - $nodes = Get-ClusterNode -Cluster $ClusterName - } - finally - { - if ($context) - { - $context.Undo() - $context.Dispose() - - CloseUserToken($newToken) - } - } - - foreach ($node in $nodes.Name) - { - $instance = Get-SQLInstanceName -node $node -InstanceName $InstanceName - - $bCheck = Check-SQLHAGroup -InstanceName $instance -Name $Name -sa $sa -saPassword $saPassword - if ($bCheck) - { - Write-Verbose -Message "Found SQL HAG $Name on instance $instance" - $bHAGExist = $true - - # check if it is the primary replica - $bPrimaryCheck = Check-SQLHAGroupPrimaryReplica -InstanceName $instance -Name $Name -sa $sa -saPassword $saPassword - if ($bPrimaryCheck) - { - $primaryReplica = $instance - } - } - } - - if ($bHAGExist) - { - Write-Verbose -Message "Add instance $InstanceName to SQL HAG $Name" - - $bCheckPreviousInstance = Check-SQLHAGroupReplicaExist -InstanceName $InstanceName -Name $Name -PrimaryInstanceName $primaryReplica -sa $sa -saPassword $saPassword - if ($bCheckPreviousInstance) - { - Write-Verbose -Message "SQLHAGroup $Name already has the instance $InstanceName, clean up first" - $query = "alter availability group $Name ` - remove replica on '$InstanceName'" - - Write-Verbose -Message "Query: $query" - osql -S $primaryReplica -U $sa -P $saPassword -Q $query - } - - - # Add this instance to HAG group on instance $primaryInstance - $query = "alter availability group $Name ` - add replica on '$InstanceName' with ` - ( ` - EndPoint_URL = 'TCP://$EndpointName', ` - Availability_Mode = Synchronous_Commit, ` - Failover_Mode = Automatic, ` - Secondary_Role(Allow_connections = ALL) ` - ) " - - Write-Verbose -Message "Query: $query" - osql -S $primaryReplica -U $sa -P $saPassword -Q $query - - # Add this node to HAG - osql -S $InstanceName -U $sa -P $saPassword -Q "ALTER AVAILABILITY GROUP $Name JOIN" - - # restore database - foreach($db in $Database) - { - $query = "restore database $db from disk = '$DatabaseBackupPath\$db.bak' with norecovery" - Write-Verbose -Message "Instance $InstanceName Query: $query" - osql -S $InstanceName -U $sa -P $saPassword -Q $query - - - $query = "restore log $db from disk = '$DatabaseBackupPath\$db.log' with norecovery " - Write-Verbose -Message "Query: $query" - osql -S $InstanceName -U $sa -P $saPassword -Q $query - - # Add database to HAG - osql -S $InstanceName -U $sa -P $saPassword -Q "ALTER DATABASE $db SET HADR AVAILABILITY GROUP = $Name" - } - } - - else # create - { - Write-Verbose -Message "Create SQL HAG $Name and primary instance $InstanceName" - - foreach($db in $Database) - { - Write-Verbose -Message "Create database $db ..." - osql -S $InstanceName -U $sa -P $saPassword -Q "if not exists (select * from master.sys.databases where name = '$db') begin Create database $db end;" - - Write-Verbose -Message "Backup to $DatabaseBackupPath .." - osql -S $InstanceName -U $sa -P $saPassword -Q "backup database $db to disk = '$DatabaseBackupPath\$db.bak' with format" - } - - $dblist = "$Database" -replace " ", ", " - - Write-Verbose -Message "AG: $Name " - $query = "Create Availability Group $Name ` - For Database $Database ` - Replica ON ` - '$InstanceName' with ` - ( ` - ENDPOINT_URL = 'TCP://$EndpointName', ` - Availability_Mode = Synchronous_Commit, ` - Failover_Mode = Automatic ` - )" - - Write-Verbose -Message "Create HAG : $query.." - osql -S $InstanceName -U $sa -P $saPassword -Q $query - - foreach($db in $Database) - { - Write-Verbose -Message "Backup Log to $DatabaseBackupPath .." - osql -S $InstanceName -U $sa -P $saPassword -Q "backup log $db to disk = '$DatabaseBackupPath\$db.log' with NOFormat" - } - } - - -} - -# -# The Test-TargetResource cmdlet. -# -function Test-TargetResource -{ - param - ( - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $Name, - - [parameter(Mandatory)] - [ValidateNotNull()] - [string[]] $Database, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $ClusterName, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $DatabaseBackupPath, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $InstanceName, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $EndpointName, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [PSCredential] $DomainCredential, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [PSCredential] $SqlAdministratorCredential - ) - - if ($Database.Count -lt 1) - { - throw "Parameter Database does not have any database" - } - - Write-Verbose -Message "Checking if SQL HA Group $Name on instance $InstanceName present ..." - - $sa = $SqlAdministratorCredential.UserName - $saPassword = $SqlAdministratorCredential.GetNetworkCredential().Password - - $bFound = Check-SQLHAGroup -InstanceName $InstanceName -Name $Name -sa $sa -saPassword $saPassword - if ($bFound) - { - Write-Verbose -Message "SQL HA Group $Name is present" - $true - } - else - { - Write-Verbose -Message "SQL HA Group $Name not found" - $false - } -} - - -function Check-SQLHAGroup($InstanceName, $Name, $sa, $saPassword) -{ - Write-Verbose -Message "Check HAG $Name including instance $InstanceName ..." - $query = OSQL -S $InstanceName -U $sa -P $saPassword -Q "select count(name) from master.sys.availability_groups where name = '$Name'" -h-1 - - Write-Verbose -Message "SQL: $query" - - [bool] [int] ([String] $query[0]).Trim() -} - - -function Check-SQLHAGroupPrimaryReplica($InstanceName, $Name, $sa, $saPassword) -{ - $query = OSQL -S $InstanceName -U $sa -P $saPassword -Q "select count(replica_id) from sys.dm_hadr_availability_replica_states s ` - inner join sys.availability_groups g on g.group_id = s.group_id ` - where g.name = '$Name' and s.role_desc = 'PRIMARY' and s.is_local = 1" -h-1 - [bool] [int] ([string] $query[0]).Trim() -} - -function Check-SQLHAGroupReplicaExist($InstanceName, $Name, $PrimaryInstanceName, $sa, $saPassword) -{ - $query = OSQL -S $PrimaryInstanceName -U $sa -P $saPassword -Q "select count(replica_id) from sys.availability_replicas r ` - inner join sys.availability_groups g on g.group_id = r.group_id ` - where g.name = '$Name' and r.replica_server_name = '$InstanceName' " -h-1 - [bool] [int] ([string] $query[0]).Trim() - -} - -function Get-PureInstanceName ($InstanceName) -{ - $list = $InstanceName.Split("\") - if ($list.Count -gt 1) - { - $list[1] - } - else - { - "MSSQLSERVER" - } -} - -function Get-SQLInstanceName ($node, $InstanceName) -{ - $pureInstanceName = Get-PureInstanceName -InstanceName $InstanceName - - if ("MSSQLSERVER" -eq $pureInstanceName) - { - $node - } - else - { - $node + "\" + $pureInstanceName - } -} - - -function Get-ImpersonatetLib -{ - if ($script:ImpersonateLib) - { - return $script:ImpersonateLib - } - - $sig = @' -[DllImport("advapi32.dll", SetLastError = true)] -public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); - -[DllImport("kernel32.dll")] -public static extern Boolean CloseHandle(IntPtr hObject); -'@ - $script:ImpersonateLib = Add-Type -PassThru -Namespace 'Lib.Impersonation' -Name ImpersonationLib -MemberDefinition $sig - - return $script:ImpersonateLib - -} - -function ImpersonateAs([PSCredential] $cred) -{ - [IntPtr] $userToken = [Security.Principal.WindowsIdentity]::GetCurrent().Token - $userToken - $ImpersonateLib = Get-ImpersonatetLib - - $bLogin = $ImpersonateLib::LogonUser($cred.GetNetworkCredential().UserName, $cred.GetNetworkCredential().Domain, $cred.GetNetworkCredential().Password, - 9, 0, [ref]$userToken) - - if ($bLogin) - { - $Identity = New-Object Security.Principal.WindowsIdentity $userToken - $context = $Identity.Impersonate() - } - else - { - throw "Can't Logon as User $cred.GetNetworkCredential().UserName." - } - $context, $userToken -} - -function CloseUserToken([IntPtr] $token) -{ - $ImpersonateLib = Get-ImpersonatetLib - - $bLogin = $ImpersonateLib::CloseHandle($token) - if (!$bLogin) - { - throw "Can't close token" - } -} - - -Export-ModuleMember -Function *-TargetResource - - diff --git a/Resources/cSqlPs/DSCResources/PSHOrg_cSqlHAGroup/PSHOrg_cSqlHAGroup.schema.mof b/Resources/cSqlPs/DSCResources/PSHOrg_cSqlHAGroup/PSHOrg_cSqlHAGroup.schema.mof deleted file mode 100644 index eaa6c4b..0000000 --- a/Resources/cSqlPs/DSCResources/PSHOrg_cSqlHAGroup/PSHOrg_cSqlHAGroup.schema.mof +++ /dev/null @@ -1,20 +0,0 @@ -#pragma namespace("\\\\.\\root\\microsoft\\windows\\DesiredStateConfiguration") - -[ClassVersion("1.0.0"), FriendlyName("cSqlHAGroup")] -class PSHOrg_cSqlHAGroup : OMI_BaseResource -{ - [key, Description("The name of sql availability group")] string Name; - [required, Description("Array of databases on the local sql instance. Each database can belong to only one HA group.")] string Database[]; - [required, Description("The name of windows failover cluster for the availability group")] string ClusterName; - [required, Description("The net share for Sql replication initialization")] string DatabaseBackupPath; - [required, Description("Name of sql instance")] string InstanceName; - [required, Description("Name of EndPoint to access High Availability sql instance.")] string EndPointName; - - [Required, EmbeddedInstance("MSFT_Credential"), Description("Domain credential could get list of cluster nodes.")] - String DomainCredential; - - [Required, EmbeddedInstance("MSFT_Credential"), Description("Sql sa credential.")] - String SqlAdministratorCredential; -}; - - diff --git a/Resources/cSqlPs/DSCResources/PSHOrg_cSqlHAService/PSHOrg_cSqlHAService.psm1 b/Resources/cSqlPs/DSCResources/PSHOrg_cSqlHAService/PSHOrg_cSqlHAService.psm1 deleted file mode 100644 index 75489cf..0000000 --- a/Resources/cSqlPs/DSCResources/PSHOrg_cSqlHAService/PSHOrg_cSqlHAService.psm1 +++ /dev/null @@ -1,224 +0,0 @@ -# -# xSQLService: DSC resource to enable Sql High Availability (HA) service on the given sql instance. -# - - -function RestartSqlServer() -{ - $list = Get-Service -Name MSSQL* - - foreach ($s in $list) - { - Set-Service -Name $s.Name -StartupType Automatic - if ($s.Status -ne "Stopped") - { - $s.Stop() - $s.WaitForStatus("Stopped") - $s.Refresh() - } - if ($s.Status -ne "Running") - { - $s.Start() - $s.WaitForStatus("Running") - $s.Refresh() - } - } -} - -function IsSQLLogin($SqlInstance, $SAPassword, $Login ) -{ - $query = OSQL -S $SqlInstance -U sa -P $SAPassword -Q "select count(name) from master.sys.server_principals where name = '$Login'" -h-1 - return ($query[0].Trim() -eq "1") -} - -function IsSrvRoleMember($SqlInstance, $SAPassword, $Login ) -{ - $query = OSQL -S $SqlInstance -U sa -P $SAPassword -Q "select IS_srvRoleMember('sysadmin', '$Login')" -h-1 - return ($query[0].Trim() -eq "1") -} - -function IsHAEnabled($SqlInstance, $SAPassword) -{ - $query = OSQL -S $SqlInstance -U sa -P $SAPassword -Q "select ServerProperty('IsHadrEnabled')" -h-1 - return ($query[0].Trim() -eq "1") -} - -# -# The Get-TargetResource cmdlet. -# -function Get-TargetResource -{ - param - ( - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $InstanceName, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [PSCredential] $SqlAdministratorCredential, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [PSCredential]$ServiceCredential - ) - - Write-Verbose -Message "Set SQL Service configuration ..." - - $SAPassword = $SqlAdministratorCredential.GetNetworkCredential().Password - - $ServiceAccount = $ServiceCredential.UserName - - - $bServiceAccountInSqlLogin = IsSQLLogin -SqlInstance $InstanceName -SAPassword $SAPassword -Login $ServiceAccount - - $bServiceAccountInSrvRole = IsSrvRoleMember -SqlInstance $InstanceName -SAPassword $SAPassword -Login $ServiceCredential.UserName - - $bSystemAccountInSrvRole = IsSrvRoleMember -SqlInstance $InstanceName -SAPassword $SAPassword -Login "NT AUTHORITY\SYSTEM" - - $bHAEnabled = IsHAEnabled -SqlInstance $InstanceName -SAPassword $SAPassword - - return @{ - ServiceAccount = $ServiceAccount - ServiceAccountInSqlLogin = $bServiceAccountInSqlLogin - ServiceAccountInSrvRole = $bServiceAccountInSrvRole - SystemAccountInSrvRole = $bSystemAccountInSrvRole - HAEnabled = $bHAEnabled - } -} - -# -# The Set-TargetResource cmdlet. -# -function Set-TargetResource -{ - param - ( - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $InstanceName, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [PSCredential] $SqlAdministratorCredential, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [PSCredential]$ServiceCredential - ) - - Write-Verbose -Message "Set SQL Service configuration ..." - - $SAPassword = $SqlAdministratorCredential.GetNetworkCredential().Password - - $ServiceAccount = $ServiceCredential.UserName - $ServicePassword = $ServiceCredential.GetNetworkCredential().Password - - $bCheck = IsSQLLogin -SqlInstance $InstanceName -SAPassword $SAPassword -Login $ServiceAccount - if ($false -eq $bCheck) - { - osql -S $InstanceName -U sa -P $SAPassword -Q "Create Login [$ServiceAccount] From Windows" - } - - $bCheck = IsSrvRoleMember -SqlInstance $InstanceName -SAPassword $SAPassword -Login $ServiceAccount - if ($false -eq $bCheck) - { - osql -S $InstanceName -U sa -P $SAPassword -Q "Exec master.sys.sp_addsrvrolemember '$ServiceAccount', 'sysadmin'" - } - - $bCheck = IsSrvRoleMember -SqlInstance $InstanceName -SAPassword $SAPassword -Login "NT AUTHORITY\SYSTEM" - if ($false -eq $bCheck) - { - osql -S $InstanceName -U sa -P $SAPassword -Q "Exec master.sys.sp_addsrvrolemember 'NT AUTHORITY\SYSTEM', 'sysadmin'" - } - - $serviceName = Get-SqlServiceName -InstanceName $InstanceName - $service = Get-WmiObject Win32_Service | ? { $_.Name -eq $serviceName } - $service.Change($null,$null,$null,$null,$null,$null,$ServiceAccount,$ServicePassword,$null,$null,$null) - - RestartSqlServer - - $bCheck = IsHAEnabled -SqlInstance $InstanceName -SAPassword $SAPassword - if ($false -eq $bCheck) - { - Enable-SqlAlwaysOn -ServerInstance $InstanceName -Force - RestartSqlServer - } - - # Tell the DSC Engine to restart the machine - #$global:DSCMachineStatus = 1 -} - -# -# The Test-TargetResource cmdlet. -# -function Test-TargetResource -{ - param - ( - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $InstanceName, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [PSCredential] $SqlAdministratorCredential, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [PSCredential]$ServiceCredential - ) - - Write-Verbose -Message "Test SQL Service configuration ..." - - $SAPassword = $SqlAdministratorCredential.GetNetworkCredential().Password - $ServiceAccount = $ServiceCredential.UserName - - $ret = IsSQLLogin -SqlInstance $InstanceName -SAPassword $SAPassword -Login $ServiceAccount - if ($false -eq $ret) - { - Write-Verbose -Message "$ServiceAccount is NOT in SqlServer login" - return $false - } - - $ret = IsSrvRoleMember -SqlInstance $InstanceName -SAPassword $SAPassword -Login $ServiceCredential.UserName - if ($false -eq $ret) - { - Write-Verbose -Message "$ServiceCredential.UserName is NOT in admin role" - return $false - } - - $ret = IsSrvRoleMember -SqlInstance $InstanceName -SAPassword $SAPassword -Login "NT AUTHORITY\SYSTEM" - if ($false -eq $ret) - { - Write-Verbose -Message "NT AUTHORITY\SYSTEM is NOT in admin role" - return $false - } - - $ret = IsHAEnabled -SqlInstance $InstanceName -SAPassword $SAPassword - if ($false -eq $ret) - { - Write-Verbose -Message "$InstanceName does NOT enable SQL HA." - return $false - } - - return $ret -} - - -function Get-SqlServiceName ($InstanceName) -{ - $list = $InstanceName.Split("\") - if ($list.Count -gt 1) - { - "MSSQL$" + $list[1] - } - else - { - "MSSQLSERVER" - } -} - -Export-ModuleMember -Function *-TargetResource - - diff --git a/Resources/cSqlPs/DSCResources/PSHOrg_cSqlHAService/PSHOrg_cSqlHAService.schema.mof b/Resources/cSqlPs/DSCResources/PSHOrg_cSqlHAService/PSHOrg_cSqlHAService.schema.mof deleted file mode 100644 index 0be014c..0000000 --- a/Resources/cSqlPs/DSCResources/PSHOrg_cSqlHAService/PSHOrg_cSqlHAService.schema.mof +++ /dev/null @@ -1,16 +0,0 @@ -#pragma namespace("\\\\.\\root\\microsoft\\windows\\DesiredStateConfiguration") - -[ClassVersion("1.0.0"), FriendlyName("cSqlHAService")] -class PSHOrg_cSqlHAService : OMI_BaseResource -{ - [key, Description("The name of Sql instance.")] - string InstanceName; - - [required, EmbeddedInstance("MSFT_Credential"), Description("Sql sa credential")] - string SqlAdministratorCredential; - - [required, EmbeddedInstance("MSFT_Credential"), Description("Domain credential to run sql service")] - String ServiceCredential; -}; - - diff --git a/Resources/cSqlPs/DSCResources/PSHOrg_cSqlServerInstall/PSHOrg_cSqlServerInstall.psm1 b/Resources/cSqlPs/DSCResources/PSHOrg_cSqlServerInstall/PSHOrg_cSqlServerInstall.psm1 deleted file mode 100644 index be2d96a..0000000 --- a/Resources/cSqlPs/DSCResources/PSHOrg_cSqlServerInstall/PSHOrg_cSqlServerInstall.psm1 +++ /dev/null @@ -1,243 +0,0 @@ -# -# cSQLServerInstall: DSC resource to install Sql Server Enterprise version. -# - - -# -# The Get-TargetResource cmdlet. -# -function Get-TargetResource -{ - [OutputType([hashtable])] - param - ( - [parameter(Mandatory)] - [string] $InstanceName = "MSSQLSERVER", - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $SourcePath, - - [PSCredential] $SourcePathCredential, - - [string] $Features="SQLEngine,SSMS", - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [PSCredential] $SqlAdministratorCredential, - - [parameter(Mandatory=$false)] - [string] $SqlSvcAccount='NT AUTHORITY\Network Service', - - [parameter(Mandatory=$false)] - [PSCredential] $SqlSvcAccountCredential, - - - [parameter(Mandatory=$false)] - [string] $AGTSVCACCOUNT='NT AUTHORITY\Network Service', - - [parameter(Mandatory=$false)] - [PSCredential] $AGTSVCACCOUNTCredential, - - [parameter(Mandatory=$false)] - [string] $SQLSYSADMINACCOUNTS='NT AUTHORITY\System' - ) - - $list = Get-Service -Name MSSQL* - $retInstanceName = $null - - if ($InstanceName -eq "MSSQLSERVER") - { - if ($list.Name -contains "MSSQLSERVER") - { - $retInstanceName = $InstanceName - } - } - elseif ($list.Name -contains $("MSSQL$" + $InstanceName)) - { - Write-Verbose -Message "SQL Instance $InstanceName is present" - $retInstanceName = $InstanceName - } - - - $returnValue = @{ - InstanceName = $retInstanceName - } - - return $returnValue -} - - -# -# The Set-TargetResource cmdlet. -# -function Set-TargetResource -{ - param - ( - [parameter(Mandatory)] - [string] $InstanceName = "MSSQLSERVER", - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $SourcePath, - - [PSCredential] $SourcePathCredential, - - [string] $Features="SQLEngine,SSMS", - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [PSCredential] $SqlAdministratorCredential, - - [parameter(Mandatory=$false)] - [string] $SqlSvcAccount='NT AUTHORITY\Network Service', - - [parameter(Mandatory=$false)] - [PSCredential] $SqlSvcAccountCredential, - - - [parameter(Mandatory=$false)] - [string] $AGTSVCACCOUNT='NT AUTHORITY\Network Service', - - [parameter(Mandatory=$false)] - [PSCredential] $AGTSVCACCOUNTCredential, - - [parameter(Mandatory=$false)] - [string] $SQLSYSADMINACCOUNTS='NT AUTHORITY\System' - ) - - $LogPath = Join-Path $env:SystemDrive -ChildPath "Logs" - - if (!(Test-Path $LogPath)) - { - New-Item $LogPath -ItemType Directory - } - - $logFile = Join-Path $LogPath -ChildPath "sqlInstall-log.txt" - - $saPwd = $SqlAdministratorCredential.GetNetworkCredential().Password - $SqlSvcPwd = $SqlSvcAccountCredential.GetNetworkCredential().Password - $AgtSvcPwd = $AGTSVCACCOUNTCredential.GetNetworkCredential().Password - if($SQLSYSADMINACCOUNTS -notcontains "NT AUTHORITY\System"){ - $SQLSYSADMINACCOUNTS += ",NT AUTHORITY\System" - } - $adminAccounts = $SQLSYSADMINACCOUNTS.Split(",") - $adminAccountsString = "" - foreach($account in $adminAccounts){ - $adminAccountsString += "`"$account`" " - } - - $AGTSVCACCOUNT = "`"$AGTSVCACCOUNT`"" - $SqlSvcAccount = "`"$SqlSvcAccount`"" - - $cmd = Join-Path $SourcePath -ChildPath "Setup.exe" - - $cmd += " /Q /ACTION=Install /IACCEPTSQLSERVERLICENSETERMS /UpdateEnabled=false /IndicateProgress " - $cmd += " /FEATURES=$Features /INSTANCENAME=$InstanceName " - $cmd += " /SQLSVCACCOUNT=$SqlSvcAccount /SQLSVCPASSWORD=$SqlSvcPwd " - $cmd += " /SQLSYSADMINACCOUNTS=$adminAccountsString " - $cmd += " /AGTSVCACCOUNT=$AGTSVCACCOUNT /AGTSVCPASSWORD=$AgtSvcPwd " - $cmd += " /SECURITYMODE=SQL /SAPWD=$saPwd " - $cmd += " > $logFile 2>&1 " - - Write-Verbose "Submitting setup command: $cmd" - - NetUse -SharePath $SourcePath -SharePathCredential $SourcePathCredential -Ensure "Present" - try - { - Invoke-Expression $cmd - } - finally - { - NetUse -SharePath $SourcePath -SharePathCredential $SourcePathCredential -Ensure "Absent" - } - - # Tell the DSC Engine to restart the machine - $global:DSCMachineStatus = 1 -} - -# -# The Test-TargetResource cmdlet. -# -function Test-TargetResource -{ - [OutputType([bool])] - param - ( - [parameter(Mandatory)] - [string] $InstanceName = "MSSQLSERVER", - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $SourcePath, - - [PSCredential] $SourcePathCredential, - - [string] $Features="SQLEngine,SSMS", - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [PSCredential] $SqlAdministratorCredential, - - [parameter(Mandatory=$false)] - [string] $SqlSvcAccount='NT AUTHORITY\Network Service', - - [parameter(Mandatory=$false)] - [PSCredential] $SqlSvcAccountCredential, - - - [parameter(Mandatory=$false)] - [string] $AGTSVCACCOUNT='NT AUTHORITY\Network Service', - - [parameter(Mandatory=$false)] - [PSCredential] $AGTSVCACCOUNTCredential, - - [parameter(Mandatory=$false)] - [string] $SQLSYSADMINACCOUNTS='NT AUTHORITY\System' - ) - - $info = Get-TargetResource -InstanceName $InstanceName -SourcePath $SourcePath -SqlAdministratorCredential $SqlAdministratorCredential - - return ($info.InstanceName -eq $InstanceName) -} - - - -function NetUse -{ - param - ( - [parameter(Mandatory)] - [string] $SharePath, - - [PSCredential]$SharePathCredential, - - [string] $Ensure = "Present" - ) - - if ($null -eq $SharePathCredential) - { - return; - } - - Write-Verbose -Message "NetUse set share $SharePath ..." - - if ($Ensure -eq "Absent") - { - $cmd = "net use $SharePath /DELETE" - } - else - { - $cred = $SharePathCredential.GetNetworkCredential() - $pwd = $cred.Password - $user = $cred.Domain + "\" + $cred.UserName - $cmd = "net use $SharePath $pwd /user:$user" - } - - Invoke-Expression $cmd -} - -Export-ModuleMember -Function *-TargetResource - - diff --git a/Resources/cSqlPs/DSCResources/PSHOrg_cSqlServerInstall/PSHOrg_cSqlServerInstall.schema.mof b/Resources/cSqlPs/DSCResources/PSHOrg_cSqlServerInstall/PSHOrg_cSqlServerInstall.schema.mof deleted file mode 100644 index bc26d1e..0000000 Binary files a/Resources/cSqlPs/DSCResources/PSHOrg_cSqlServerInstall/PSHOrg_cSqlServerInstall.schema.mof and /dev/null differ diff --git a/Resources/cSqlPs/DSCResources/PSHOrg_cWaitForSqlHAGroup/PSHOrg_cWaitForSqlHAGroup.psm1 b/Resources/cSqlPs/DSCResources/PSHOrg_cWaitForSqlHAGroup/PSHOrg_cWaitForSqlHAGroup.psm1 deleted file mode 100644 index ed47dac..0000000 --- a/Resources/cSqlPs/DSCResources/PSHOrg_cWaitForSqlHAGroup/PSHOrg_cWaitForSqlHAGroup.psm1 +++ /dev/null @@ -1,285 +0,0 @@ -# -# xWaitForSqlHAGroup: DSC resource to wait for existency of given name of Sql HA group, it checks the state of -# the HA group with given interval until it exists or the number of retries is reached. -# - - -# -# The Get-TargetResource cmdlet. -# -function Get-TargetResource -{ - param - ( - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $Name, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $ClusterName, - - [UInt64] $RetryIntervalSec = 10, - [UInt32] $RetryCount = 10, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $InstanceName, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [PSCredential]$DomainCredential, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [PSCredential]$SqlAdministratorCredential - ) - - $sa = $SqlAdministratorCredential.UserName - $saPassword = $SqlAdministratorCredential.GetNetworkCredential().Password - - $bFound = Check-SQLHAGroup -InstanceName $InstanceName -Name $Name -sa $sa -saPassword $saPassword - - $returnValue = @{ - Name = $Name - InstanceName = $InstanceName - RetryIntervalSec = $RetryIntervalSec - RetryCount = $RetryCount - - HAGroupExist = $bFound - } - - $returnValue -} - -# -# The Set-TargetResource cmdlet. -# -function Set-TargetResource -{ - param - ( - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $Name, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $ClusterName, - - [UInt64] $RetryIntervalSec = 10, - [UInt32] $RetryCount = 10, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $InstanceName, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [PSCredential]$DomainCredential, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [PSCredential]$SqlAdministratorCredential - ) - - $bFound = $false - Write-Verbose -Message "Checking for SQL HA Group $Name on instance $InstanceName ..." - - $sa = $SqlAdministratorCredential.UserName - $saPassword = $SqlAdministratorCredential.GetNetworkCredential().Password - - for ($count = 0; $count -lt $RetryCount; $count++) - { - $bFound = Check-SQLHAGroupExist -ClusterName $ClusterName -Name $Name -domainCred $DomainCredential -sa $sa -saPassword $saPassword - if ($bFound) - { - Write-Verbose -Message "Found SQL HA Group $Name on instance $InstanceName" - break; - } - else - { - Write-Verbose -Message "SQL HA Group $Name on instance $InstanceName not found. Will retry again after $RetryIntervalSec sec" - Start-Sleep -Seconds $RetryIntervalSec - } - } - - - if (!$bFound) - { - throw "SQL HA Group $Name on instance $InstanceName not found afater $count attempt with $RetryIntervalSec sec interval" - } -} - -# -# The Test-TargetResource cmdlet. -# -function Test-TargetResource -{ - param - ( - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $Name, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $ClusterName, - - [UInt64] $RetryIntervalSec = 10, - [UInt32] $RetryCount = 10, - - [parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $InstanceName, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [PSCredential]$DomainCredential, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [PSCredential]$SqlAdministratorCredential - ) - - Write-Verbose -Message "Checking for SQL HA Group $Name on instance $InstanceName ..." - - $sa = $SqlAdministratorCredential.UserName - $saPassword = $SqlAdministratorCredential.GetNetworkCredential().Password - - $bFound = Check-SQLHAGroup -InstanceName $InstanceName -Name $Name -sa $sa -saPassword $saPassword - if ($bFound) - { - Write-Verbose -Message "Found SQL HA Group $Name on instance $InstanceName" - $true - } - else - { - Write-Verbose -Message "SQL HA Group $Name on instance $InstanceName not found" - $false - } -} - - -function Check-SQLHAGroup($InstanceName, $Name, $sa, $saPassword) -{ - $query = OSQL -S $InstanceName -U $sa -P $saPassword -Q "select count(name) from master.sys.availability_groups where name = '$Name'" -h-1 - [bool] [int] $query[0].Trim() -} - -function Check-SQLHAGroupExist($ClusterName, $Name, $sa, $saPassword, $domainCred) -{ - $bHAGExist = $false - - try - { - ($oldToken, $context, $newToken) = ImpersonateAs -cred $domainCred - $nodes = Get-ClusterNode -Cluster $ClusterName - } - finally - { - if ($context) - { - $context.Undo() - $context.Dispose() - - CloseUserToken($newToken) - } - } - - - foreach ($node in $nodes.Name) - { - $instance = Get-SQLInstanceName -node $node -InstanceName $InstanceName - $bCheck = Check-SQLHAGroup -InstanceName $instance -Name $Name -sa $sa -saPassword $saPassword - if ($bCheck) - { - $bHAGExist = $true - break - } - } - - $bHAGExist -} - -function Get-ImpersonatetLib -{ - if ($script:ImpersonateLib) - { - return $script:ImpersonateLib - } - - $sig = @' -[DllImport("advapi32.dll", SetLastError = true)] -public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); - -[DllImport("kernel32.dll")] -public static extern Boolean CloseHandle(IntPtr hObject); -'@ - $script:ImpersonateLib = Add-Type -PassThru -Namespace 'Lib.Impersonation' -Name ImpersonationLib -MemberDefinition $sig - - return $script:ImpersonateLib - -} - -function ImpersonateAs([PSCredential] $cred) -{ - [IntPtr] $userToken = [Security.Principal.WindowsIdentity]::GetCurrent().Token - $userToken - $ImpersonateLib = Get-ImpersonatetLib - - $bLogin = $ImpersonateLib::LogonUser($cred.GetNetworkCredential().UserName, $cred.GetNetworkCredential().Domain, $cred.GetNetworkCredential().Password, - 9, 0, [ref]$userToken) - - if ($bLogin) - { - $Identity = New-Object Security.Principal.WindowsIdentity $userToken - $context = $Identity.Impersonate() - } - else - { - throw "Can't Logon as User $cred.GetNetworkCredential().UserName." - } - $context, $userToken -} - -function CloseUserToken([IntPtr] $token) -{ - $ImpersonateLib = Get-ImpersonatetLib - - $bLogin = $ImpersonateLib::CloseHandle($token) - if (!$bLogin) - { - throw "Can't close token" - } -} - -function Get-PureInstanceName ($InstanceName) -{ - $list = $InstanceName.Split("\") - if ($list.Count -gt 1) - { - $list[1] - } - else - { - "MSSQLSERVER" - } -} - -function Get-SQLInstanceName ($node, $InstanceName) -{ - $pureInstanceName = Get-PureInstanceName -InstanceName $InstanceName - - if ("MSSQLSERVER" -eq $pureInstanceName) - { - $node - } - else - { - $node + "\" + $pureInstanceName - } -} - -Export-ModuleMember -Function *-TargetResource - diff --git a/Resources/cSqlPs/DSCResources/PSHOrg_cWaitForSqlHAGroup/PSHOrg_cWaitForSqlHAGroup.schema.mof b/Resources/cSqlPs/DSCResources/PSHOrg_cWaitForSqlHAGroup/PSHOrg_cWaitForSqlHAGroup.schema.mof deleted file mode 100644 index a7f12e4..0000000 --- a/Resources/cSqlPs/DSCResources/PSHOrg_cWaitForSqlHAGroup/PSHOrg_cWaitForSqlHAGroup.schema.mof +++ /dev/null @@ -1,19 +0,0 @@ -#pragma namespace("\\\\.\\root\\microsoft\\windows\\DesiredStateConfiguration") - -[ClassVersion("1.0.0.0"), FriendlyName("cWaitForSqlHAGroup")] -class PSHOrg_cWaitForSqlHAGroup : OMI_BaseResource -{ - [Key, Description("The name of Sql High Availability group")] String Name; - [required, Description("The name of windows failover cluster for the availability group.")] string ClusterName; - [Write, Description("Interval to check the HA group existency")] Uint64 RetryIntervalSec; - [Write, Description("Maximum number of retries to check HA group existency")] Uint32 RetryCount; - - [required, Description("The name of sql instance.")] string InstanceName; - - [Required, EmbeddedInstance("MSFT_Credential"), Description("Domain credential could get list of cluster nodes.")] - String DomainCredential; - - [Required, EmbeddedInstance("MSFT_Credential"), Description("Sql sa credential")] - String SqlAdministratorCredential; -}; - diff --git a/Resources/cSqlPs/DSCResources/cScriptResource/cScriptResource.psm1 b/Resources/cSqlPs/DSCResources/cScriptResource/cScriptResource.psm1 deleted file mode 100644 index 83c2d4a..0000000 --- a/Resources/cSqlPs/DSCResources/cScriptResource/cScriptResource.psm1 +++ /dev/null @@ -1,284 +0,0 @@ - -data LocalizedData -{ - # culture="en-US" - ConvertFrom-StringData @' -SetScriptWhatIfMessage=Executing the SetScript with the user supplied credential -InValidResultFromGetScriptError=Failure to get the results from the script in a hash table format. -InValidResultFromTestScriptError=Failure to get a valid result from the execution of TestScript. The Test script should return True or False. -ScriptBlockProviderScriptExecutionFailureError=Failure to successfully execute the script. -GetTargetResourceStartVerboseMessage=Begin executing Get Script. -GetTargetResourceEndVerboseMessage=End executing Get Script. -SetTargetResourceStartVerboseMessage=Begin executing Set Script. -SetTargetResourceEndVerboseMessage=End executing Set Script. -TestTargetResourceStartVerboseMessage=Begin executing Test Script. -TestTargetResourceEndVerboseMessage=End executing Test Script. -ExecutingScriptMessage=Executing Script: {0} - -'@ -} - -$GenericMessageEventID=0x1005; -$ClassName="MSFT_ScriptResource" - - -Import-LocalizedData LocalizedData -filename MSFT_ScriptResourceStrings - - -# The Get-TargetResource cmdlet is used to fetch the desired state of the DSC managed node through a powershell script. -# This cmdlet executes the user supplied script (i.e., the script is responsible for validating the desired state of the -# DSC managed node). The result of the script execution is in the form of a hashtable containing all the inormation -# gathered from the GetScript execution. -function Get-TargetResource -{ - [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $GetScript, - - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string]$SetScript, - - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $TestScript, - - [Parameter(Mandatory=$false)] - [System.Management.Automation.PSCredential] - $Credential - ) - - $getTargetResourceResult = $null; - - $getTargetResourceStartVerboseMessage = $($LocalizedData.GetTargetResourceStartVerboseMessage); - Write-Debug -Message $getTargetResourceStartVerboseMessage; - - $script = [ScriptBlock]::Create($GetScript); - $parameters = $psboundparameters.Remove("GetScript"); - $psboundparameters.Add("ScriptBlock", $script); - - # TODO: sharatg - Remove these additional paramters once the PS infrasturcure can selectively pass input parameters. - $parameters = $psboundparameters.Remove("SetScript"); - $parameters = $psboundparameters.Remove("TestScript"); - - $scriptResult = ScriptExecutionHelper @psboundparameters; - - $scriptResultAsErrorRescord = $scriptResult -as [System.Management.Automation.ErrorRecord] - if($null -ne $scriptResultAsErrorRescord) - { - $PSCmdlet.ThrowTerminatingError($scriptResultAsErrorRescord); - } - - $scriptResultAsHasTable = $scriptResult -as [hashtable] - - if($null -ne $scriptResultAsHasTable) - { - $getTargetResourceResult = $scriptResultAsHasTable ; - } - else - { - # Error message indicating failure to get valid hashtable as the result of the Get script execution. - $errorId = "InValidResultFromGetScript"; - $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidResult; - $exception = New-Object System.InvalidOperationException $($LocalizedData.InValidResultFromGetScriptError); - $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $null - - $PSCmdlet.ThrowTerminatingError($errorRecord); - } - - $getTargetResourceEndVerboseMessage = $($LocalizedData.GetTargetResourceEndVerboseMessage); - Write-Debug -Message $getTargetResourceEndVerboseMessage; - - $getTargetResourceResult; -} - - -# The Set-TargetResource cmdlet is used to Set the desired state of the DSC managed node through a powershell script. -# The method executes the user supplied script (i.e., the script is responsible for validating the desired state of the -# DSC managed node). If the DSC managed node requires a restart either during or after the execution of the SetScript, -# the SetScript notifies the PS Infrasturcure by setting the variable $DSCMachineStatus.IsRestartRequired to $true. -function Set-TargetResource -{ - [CmdletBinding(SupportsShouldProcess=$true)] - param - ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $SetScript, - - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $GetScript, - - [Parameter(Mandatory=$false)] - [System.Management.Automation.PSCredential] - $Credential, - - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $TestScript - - ) - - $setscriptmessage = '$SetScript:' + $SetScript - $testscriptmessage = '$TestScript:' + $TestScript - if ($pscmdlet.ShouldProcess($($LocalizedData.SetScriptWhatIfMessage))) - { - $setTargetResourceStartVerboseMessage = $($LocalizedData.SetTargetResourceStartVerboseMessage); - Write-Debug -Message $setTargetResourceStartVerboseMessage; - - $script = [ScriptBlock]::Create($SetScript); - $parameters = $psboundparameters.Remove("SetScript"); - $psboundparameters.Add("ScriptBlock", $script); - - $parameters = $psboundparameters.Remove("GetScript"); - $parameters = $psboundparameters.Remove("TestScript"); - - $scriptResult = ScriptExecutionHelper @psboundparameters ; - - $scriptResultAsErrorRescord = $scriptResult -as [System.Management.Automation.ErrorRecord] - if($null -ne $scriptResultAsErrorRescord) - { - $PSCmdlet.ThrowTerminatingError($scriptResultAsErrorRescord); - } - - $setTargetResourceEndVerboseMessage = $($LocalizedData.SetTargetResourceEndVerboseMessage); - Write-Debug -Message $setTargetResourceEndVerboseMessage; - } -} - - -# The Test-TargetResource cmdlet is used to validate the desired state of the DSC managed node through a powershell script. -# The method executes the user supplied script (i.e., the script is responsible for validating the desired state of the -# DSC managed node). The result of the script execution should be true if the DSC managed machine is in the desired state -# or else false should be returned. -function Test-TargetResource -{ - param - ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $TestScript, - - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string]$SetScript, - - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string]$GetScript, - - [Parameter(Mandatory=$false)] - [System.Management.Automation.PSCredential] - $Credential - ) - $testTargetResourceResult = $false; - - $testTargetResourceStartVerboseMessage = $($LocalizedData.TestTargetResourceStartVerboseMessage); - Write-Debug -Message $testTargetResourceStartVerboseMessage; - - $script = [ScriptBlock]::Create($TestScript); - $parameters = $psboundparameters.Remove("TestScript"); - $psboundparameters.Add("ScriptBlock", $script); - - $parameters = $psboundparameters.Remove("GetScript"); - $parameters = $psboundparameters.Remove("SetScript"); - - $scriptResult = ScriptExecutionHelper @psboundparameters ; - - $scriptResultAsErrorRescord = $scriptResult -as [System.Management.Automation.ErrorRecord] - if($null -ne $scriptResultAsErrorRescord) - { - $PSCmdlet.ThrowTerminatingError($scriptResultAsErrorRescord); - } - - if($null -eq $scriptResult) - { - $errorId = "InValidResultFromTestScript"; - $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidResult; - $exception = New-Object System.InvalidOperationException $($LocalizedData.InValidResultFromTestScriptError) ; - $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $null - - $PSCmdlet.ThrowTerminatingError($errorRecord); - } - - # If the script is returing multiple objects, then we consider the last object to be the result of script execution. - if($scriptResult.GetType().ToString() -eq 'System.Object[]') - { - $reultObject = $scriptResult[$scriptResult.Length -1]; - } - else - { - $reultObject = $scriptResult; - } - - if(($null -ne $reultObject) -and - (($reultObject -eq $true) -or ($reultObject -eq $false))) - { - $testTargetResourceResult = $reultObject; - } - else - { - $errorId = "InValidResultFromTestScript"; - $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidResult; - $exception = New-Object System.InvalidOperationException $($LocalizedData.InValidResultFromTestScriptError) ; - $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $null - - $PSCmdlet.ThrowTerminatingError($errorRecord); - } - - $testTargetResourceEndVerboseMessage = $($LocalizedData.TestTargetResourceEndVerboseMessage); - Write-Debug -Message $testTargetResourceEndVerboseMessage; - - $testTargetResourceResult; -} - - -function ScriptExecutionHelper -{ - param - ( - [ScriptBlock] - $ScriptBlock, - - [System.Management.Automation.PSCredential] - $Credential - ) - - $scriptExecutionResult = $null; - - try - { - - $executingScriptMessage = $($LocalizedData.ExecutingScriptMessage) -f ${ScriptBlock} ; - Write-Debug -Message $executingScriptMessage; - - if($null -ne $Credential) - { - $scriptExecutionResult = Invoke-Command -ScriptBlock $ScriptBlock -ComputerName . -Credential $Credential - } - else - { - $scriptExecutionResult = &$ScriptBlock; - } - $scriptExecutionResult; - } - catch - { - # Surfacing the error thrown by the execution of Get/Set/Test script. - $_; - } -} - -Export-ModuleMember -function Get-TargetResource, Set-TargetResource, Test-TargetResource - - diff --git a/Resources/cSqlPs/DSCResources/cScriptResource/cScriptResource.schema.mof b/Resources/cSqlPs/DSCResources/cScriptResource/cScriptResource.schema.mof deleted file mode 100644 index c05e8b8..0000000 --- a/Resources/cSqlPs/DSCResources/cScriptResource/cScriptResource.schema.mof +++ /dev/null @@ -1,17 +0,0 @@ -#pragma namespace("\\\\.\\root\\microsoft\\windows\\DesiredStateConfiguration") - -[ClassVersion("1.0.0"),FriendlyName("Script")] -class cScriptResource : OMI_BaseResource -{ - [Key] string GetScript; - [Key] string SetScript; - [Key] string TestScript; - [Write, EmbeddedInstance("MSFT_KeyValuePair")] String GetScriptParam; - [Write, EmbeddedInstance("MSFT_KeyValuePair")] String SetScriptParam; - [Write, EmbeddedInstance("MSFT_KeyValuePair")] String TestScriptParam; - [write,EmbeddedInstance("MSFT_Credential")] string Credential; - [Read] string Result; -}; - - - diff --git a/Resources/cSqlPs/DSCResources/cScriptResource/en-US/cScriptResource.schema.mfl b/Resources/cSqlPs/DSCResources/cScriptResource/en-US/cScriptResource.schema.mfl deleted file mode 100644 index 307e496..0000000 --- a/Resources/cSqlPs/DSCResources/cScriptResource/en-US/cScriptResource.schema.mfl +++ /dev/null @@ -1,10 +0,0 @@ -#pragma namespace("\\\\.\\root\\microsoft\\windows\\DesiredStateConfiguration") -instance of __namespace{ name="ms_409";}; -#pragma namespace("\\\\.\\root\\microsoft\\windows\\DesiredStateConfiguration\\ms_409") - -[Description("This resource is used to perform Get, Set and Test functionality on the DSC managed nodes through Powershell scripts. \n") : Amended,AMENDMENT, LOCALE(0x0409)] -class MSFT_ScriptResource : OMI_BaseResource -{ -}; - - diff --git a/Resources/cSqlPs/DSCResources/cScriptResource/en-US/cScriptResourceStrings.psd1 b/Resources/cSqlPs/DSCResources/cScriptResource/en-US/cScriptResourceStrings.psd1 deleted file mode 100644 index 92e20f7..0000000 --- a/Resources/cSqlPs/DSCResources/cScriptResource/en-US/cScriptResourceStrings.psd1 +++ /dev/null @@ -1,2 +0,0 @@ -# Localized 09/04/2013 09:51 AM (GMT) 303:4.80.0411 MSFT_ScriptResourceStrings.psd1 # Localized MSFT_ScriptResourceStrings.psd1 ConvertFrom-StringData @' ###PSLOC SetScriptWhatIfMessage=Executing the SetScript with the user supplied credential InValidResultFromGetScriptError=Failure to get the results from the script in a hash table format. InValidResultFromTestScriptError=Failure to get a valid result from the execution of TestScript. The Test script should return True or False. ScriptBlockProviderScriptExecutionFailureError=Failure to successfully execute the script. GetTargetResourceStartVerboseMessage=Begin executing Get Script. GetTargetResourceEndVerboseMessage=End executing Get Script. SetTargetResourceStartVerboseMessage=Begin executing Set Script. SetTargetResourceEndVerboseMessage=End executing Set Script. TestTargetResourceStartVerboseMessage=Begin executing Test Script. TestTargetResourceEndVerboseMessage=End executing Test Script. ExecutingScriptMessage=Executing Script: {0} ###PSLOC '@ - diff --git a/Resources/cSqlPs/cSqlPs.psd1 b/Resources/cSqlPs/cSqlPs.psd1 deleted file mode 100644 index ad13c9d..0000000 --- a/Resources/cSqlPs/cSqlPs.psd1 +++ /dev/null @@ -1,19 +0,0 @@ - - -@{ - - -ModuleVersion = '1.1.2' -GUID = 'abee25c0-d40a-4bf2-a04e-ed059aba377b' - -Author = 'Microsoft Corporation' -CompanyName = 'Microsoft Corporation' -Copyright = '(c) 2014 Microsoft Corporation. All rights reserved.' - -Description = 'Module containing PowerShell Desired State Configuration (DSC) resources that can be used to configure SQL Server.' - - - -} - - diff --git a/Resources/cSystemCenterManagement/DSCResources/ICG_SCOMAgentMgmtGroup/ICG_SCOMAgentMgmtGroup.psm1 b/Resources/cSystemCenterManagement/DSCResources/ICG_SCOMAgentMgmtGroup/ICG_SCOMAgentMgmtGroup.psm1 deleted file mode 100644 index 69e63d6..0000000 --- a/Resources/cSystemCenterManagement/DSCResources/ICG_SCOMAgentMgmtGroup/ICG_SCOMAgentMgmtGroup.psm1 +++ /dev/null @@ -1,78 +0,0 @@ -####################################################################### -# OMAgentMgmtGroup DSC Resource -# DSC Resource to manage SCOM 2012 Agent Management Group settings. -# 201401127 - Joe Thompson, Infront Consulting Group -####################################################################### - -####################################################################### -# The Get-TargetResource cmdlet. -####################################################################### -function Get-TargetResource -{ - param - ( - [parameter(Mandatory)] - [String] $ManagementGroupName, - [parameter(Mandatory)] - [String] $ManagementServerName - ) - - Try { $objCfg = New-Object -ComObject AgentConfigManager.MgmtSvcCfg } - - Catch { Throw "Monitoring Agent not installed." } - - $objMGs = $objCfg.GetManagementGroups() | %{$_.managementGroupName} - - If ($objMGs -contains $ManagementGroupName) - { - $objMG = $objCfg.GetManagementGroup($ManagementGroupName) - $returnValue = @{ - ManagementGroupName = $objMG.ManagementGroupName - ManagementServerName = $objMG.ManagementServer - } - } - Else - { - $returnValue = @{ - ManagementGroupName = $null - ManagementServerName = $null - } - } - - $returnValue -} - -######################################################################## -# The Set-TargetResource cmdlet. -######################################################################## -function Set-TargetResource -{ - param - ( - [ValidateSet("Present", "Absent")] [String] $Ensure = "Present", [parameter(Mandatory)] [String] $ManagementGroupName, [parameter(Mandatory)] [String] $ManagementServerName - ) - -Try { $objCfg = New-Object -ComObject AgentConfigManager.MgmtSvcCfg } catch { throw "Monitoring Agent not installed." } $objMGs = $objCfg.GetManagementGroups() | %{$_.managementGroupName} If ($objMGs -contains $ManagementGroupName) { If ($Ensure -eq "Absent") { Write-Verbose -Message "Monitoring Agent should not report to $ManagementGroupName, removing..." $objCfg.RemoveManagementGroup($ManagementGroupName) } } Else { If ($Ensure -eq "Present") { Write-Verbose -Message "Monitoring Agent is not reporting to $ManagementGroupName, adding it..." $objCfg.AddManagementGroup($ManagementGroupName, $ManagementServerName, 5723) } } } - -####################################################################### -# The Test-TargetResource cmdlet. -####################################################################### -function Test-TargetResource -{ - [CmdletBinding()] [OutputType([System.Boolean])] - param - ( - [ValidateSet("Present", "Absent")] [String] $Ensure = "Present", - [parameter(Mandatory)] [String] $ManagementGroupName, [parameter(Mandatory)] [String] $ManagementServerName - ) - - - Write-Verbose -Message "Checking if Monitoring Agent reports to $ManagementGroupName Management Group" - - Try { $objCfg = New-Object -ComObject AgentConfigManager.MgmtSvcCfg } catch { throw "Monitoring Agent not installed." } $objMGs = $objCfg.GetManagementGroups() | %{$_.managementGroupName} If ($objMGs -contains $ManagementGroupName) { If ($Ensure -eq "Present") { Write-Verbose -Message "Monitoring Agent is alreadying reporting to $ManagementGroupName Management Group." Write-Verbose -Message "Management Server for $ManagementGroupName is $ManagementServerName" return $true } Write-Verbose -Message "$ManagementGroupName Management Group will be removed from Monitoring Agent." return $false } Else { If ($Ensure -eq "Absent") { Write-Verbose -Message "Monitoring Agent doesn't need Management Group" return $true } Write-Verbose -Message "$ManagementGroupName Management Group is missing from Monitoring Agent." return $false } -} - - - -Export-ModuleMember -Function *-TargetResource - diff --git a/Resources/cSystemCenterManagement/DSCResources/ICG_SCOMAgentMgmtGroup/ICG_SCOMAgentMgmtGroup.schema.mof b/Resources/cSystemCenterManagement/DSCResources/ICG_SCOMAgentMgmtGroup/ICG_SCOMAgentMgmtGroup.schema.mof deleted file mode 100644 index 33e089f..0000000 --- a/Resources/cSystemCenterManagement/DSCResources/ICG_SCOMAgentMgmtGroup/ICG_SCOMAgentMgmtGroup.schema.mof +++ /dev/null @@ -1,12 +0,0 @@ - -[ClassVersion("1.0.0"), FriendlyName("SCOMAgentMG")] -class ICG_SCOMAgentMgmtGroup : OMI_BaseResource -{ - [key] string ManagementGroupName; - - [required] string ManagementServerName; - - [Write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; -}; - - diff --git a/Resources/cSystemCenterManagement/DSCResources/ICG_SCOMBulkMP/ICG_SCOMBulkMP.psm1 b/Resources/cSystemCenterManagement/DSCResources/ICG_SCOMBulkMP/ICG_SCOMBulkMP.psm1 deleted file mode 100644 index 50cf26a..0000000 --- a/Resources/cSystemCenterManagement/DSCResources/ICG_SCOMBulkMP/ICG_SCOMBulkMP.psm1 +++ /dev/null @@ -1,219 +0,0 @@ -####################################################################### -# ICG_SCOMBulkMP DSC Resource -# DSC Resource to bulk import management packs into SCOM 2012 -# 201401129 - Joe Thompson, Infront Consulting Group -####################################################################### - -function Get-TargetResource -{ - [OutputType([hashtable])] - param - ( - [ValidateSet("Present", "Absent")] - [String] $Ensure = "Present", - [parameter(Mandatory)] - [string] $MPSourcePath - ) - - $OMReg = Get-ItemProperty "HKLM:\Software\Microsoft\System Center Operations Manager\12\Setup\Powershell\V2" - - If (!($OMReg)) - { - Throw "Operations Manager PowerShell module not detected!" - } - - $OMPSModule = $OMReg.InstallDirectory + "OperationsManager" - If (!(Get-Module OperationsManager)) { Import-Module $OMPSModule } - - $mpfiles = (Get-Item -Path "$MPSourcePath\*" -Include *.mp*).Name - - If ($mpfiles) - { - $mpcnt = $mpfiles.Count - - $InstallList = @() - $InstalledMPs = Get-SCOMManagementPack |%{$_}|%{$_.name} - foreach ($ManagementPack in $mpfiles) - { - $mpname = [System.IO.Path]::GetFileNameWithoutExtension($ManagementPack) - If ($InstalledMPs -notcontains $mpname) - { - Write-Verbose -Message "$ManagementPack is missing." - $InstallList += $ManagementPack - } - Else - { - Write-Verbose -Message "$ManagementPack is already installed!" - } - } - - $Instcnt = $InstallList.Count - - If ($Instcnt -gt 0) - { - Write-Verbose -Message "All Management Packs are not installed!" - $returnValue = @{ - Ensure = "Absent" - MPSourcePath = $MPSourcePath - } - } - else - { - Write-Verbose -Message "All Management Packs are installed!" - $returnValue = @{ - Ensure = "Present" - MPSourcePath = $MPSourcePath - } - - } - } - Else - { - Throw "Can't find source management pack files for comparison." - } - - $returnValue; -} - -function Set-TargetResource -{ - param - ( - [ValidateSet("Present", "Absent")] - [System.String] $Ensure = "Present", - [parameter(Mandatory)] - [string] $MPSourcePath - ) - - # Make sure we can get to OperationsManager PS Module - - $OMReg = Get-ItemProperty "HKLM:\Software\Microsoft\System Center Operations Manager\12\Setup\Powershell\V2" - - If (!($OMReg)) - { - Throw "Operations Manager PowerShell module not detected!" - } - - $OMPSModule = $OMReg.InstallDirectory + "OperationsManager" - If (!(Get-Module OperationsManager)) { Import-Module $OMPSModule } - - $mpfiles = (Get-Item -Path "$MPSourcePath\*" -Include *.mp*).Name - - If ($mpfiles) - { - $mpcnt = $mpfiles.Count - - $InstallList = @() - $InstalledMPs = Get-SCOMManagementPack |%{$_}|%{$_.name} - foreach ($ManagementPack in $mpfiles) - { - $mpname = [System.IO.Path]::GetFileNameWithoutExtension($ManagementPack) - If ($InstalledMPs -notcontains $mpname) - { - Write-Verbose -Message "Adding $ManagementPack to import queue..." - $InstallList += $ManagementPack - } - Else - { - Write-Verbose -Message "$ManagementPack is already installed!" - } - } - - $Instcnt = $InstallList.Count - - If ($Ensure -eq "Present") - { - If ($Instcnt -gt 0) - { - Write-Verbose -Message "Importing management packs from source folder $MPSourcePath" - Set-Location $MPSourcePath - Import-SCOMManagementPack -Fullname $InstallList -ErrorAction Continue - } - } - Else - { - If ($Instcnt -gt 0) - { - $InstallList | Remove-SCOMManagementPack - - } - } - } - Else - { - Throw "Can't find source management pack files for comparison." - } -} - -function Test-TargetResource -{ - [OutputType([bool])] - param - ( - [ValidateSet("Present", "Absent")] - [String] $Ensure = "Present", - [parameter(Mandatory)] - [string] $MPSourcePath - ) - - $returnValue = $True - - $OMReg = Get-ItemProperty "HKLM:\Software\Microsoft\System Center Operations Manager\12\Setup\Powershell\V2" - - If (!($OMReg)) - { - Throw "Operations Manager role does not exist" - } - - $OMPSModule = $OMReg.InstallDirectory + "OperationsManager" - If (!(Get-Module OperationsManager)) { Import-Module $OMPSModule } - - $mpfiles = (Get-Item -Path "$MPSourcePath\*" -Include *.mp*).Name - - If ($mpfiles) - { - $mpcnt = $mpfiles.Count - - $InstallList = @() - $InstalledMPs = Get-SCOMManagementPack |%{$_}|%{$_.name} - foreach ($ManagementPack in $mpfiles) - { - $mpname = [System.IO.Path]::GetFileNameWithoutExtension($ManagementPack) - If ($InstalledMPs -notcontains $mpname) - { - Write-Verbose -Message "$ManagementPack is missing." - $InstallList += $ManagementPack - } - Else - { - Write-Verbose -Message "$ManagementPack is already installed!" - } - } - - $Instcnt = $InstallList.Count - - If ($Ensure -eq "Present") - { - If ($Instcnt -gt 0) - { - $returnValue = $False - } - } - Else - { - If ($Instcnt -gt 0) - { - $returnValue = $False - - } - } - } - Else - { - Throw "Can't find source management pack files for comparison." - } - - $returnValue; -} - - diff --git a/Resources/cSystemCenterManagement/DSCResources/ICG_SCOMBulkMP/ICG_SCOMBulkMP.schema.mof b/Resources/cSystemCenterManagement/DSCResources/ICG_SCOMBulkMP/ICG_SCOMBulkMP.schema.mof deleted file mode 100644 index a6fde60..0000000 --- a/Resources/cSystemCenterManagement/DSCResources/ICG_SCOMBulkMP/ICG_SCOMBulkMP.schema.mof +++ /dev/null @@ -1,7 +0,0 @@ -[ClassVersion("1.0.0"), FriendlyName("SCOMBulkMP")] -class ICG_SCOMBulkMP : OMI_BaseResource -{ - [key] string MPSourcePath; - [Write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; -}; - diff --git a/Resources/cSystemCenterManagement/DSCResources/ICG_SCOMImportMP/ICG_SCOMImportMP.psm1 b/Resources/cSystemCenterManagement/DSCResources/ICG_SCOMImportMP/ICG_SCOMImportMP.psm1 deleted file mode 100644 index b896ed1..0000000 --- a/Resources/cSystemCenterManagement/DSCResources/ICG_SCOMImportMP/ICG_SCOMImportMP.psm1 +++ /dev/null @@ -1,181 +0,0 @@ -####################################################################### -# ICG_SCOMImportMP DSC Resource -# DSC Resource to import management packs into SCOM 2012 -# 201401127 - Joe Thompson, Infront Consulting Group -####################################################################### - -function Get-TargetResource -{ - param - ( - [ValidateSet("Present", "Absent")] - [String] $Ensure = "Present", - [parameter(Mandatory)] - [String] $MPName, - [parameter(Mandatory)] - [String] $MPSourcePath - ) - - $OMReg = Get-ItemProperty "HKLM:\Software\Microsoft\System Center Operations Manager\12\Setup\Powershell\V2" - - If (!($OMReg)) - { - Throw "Cannot locate Operations Manager PowerShell Module!" - } - Else - { - $OMPSModule = $OMReg.InstallDirectory + "OperationsManager" - If (!(Get-Module OperationsManager)) { Import-Module $OMPSModule } - - $mp = (Get-SCOMManagementPack -Name $MPName -ErrorAction SilentlyContinue) - - if ($mp -ne $null) - { - $returnValue = @{ - Ensure = $Ensure - MPName = $mp.Name - MPSourcePath = $MPSourcePath - } - } - else - { - $returnValue = @{ - Ensure = $Ensure - MPName = $null - MPSourcePath = $null - } - } - } - $returnValue -} - -function Set-TargetResource -{ - param - ( - [ValidateSet("Present", "Absent")] - [System.String] - $Ensure = "Present", - - [parameter(Mandatory)] - [String] $MPName, - - [parameter(Mandatory)] - [String] $MPSourcePath - ) - - # Make sure we can get to OperationsManager PS Module - - $OMReg = Get-ItemProperty "HKLM:\Software\Microsoft\System Center Operations Manager\12\Setup\Powershell\V2" - - If (!($OMReg)) - { - Throw "Cannot locate Operations Manager PowerShell Module!" - } - Else - { - $OMPSModule = $OMReg.InstallDirectory + "OperationsManager" - If (!(Get-Module OperationsManager)) { Import-Module $OMPSModule } - - $mp = (Get-SCOMManagementPack -Name $MPName -ErrorAction SilentlyContinue) - - if ($Ensure -eq 'Present') - { - Write-Verbose "Ensure -eq 'Present'" - if ($mp -eq $null) - { - if (Test-Path $MPSourcePath) - { - Write-Verbose -Message "Importing Management Pack $MPName ..." - Import-SCOMManagementPack $MPSourcePath - } - Else - { - Throw "Unable to import Management Pack from source $MPSourcePath" - } - } - } - elseif($Ensure -eq 'Absent') - { - Write-Verbose "Ensure -eq 'Absent'" - if ($mp -ne $null) - { - Write-Verbose "Management Pack is Present, so removing it: $MPName" - Get-SCOMManagementPack $MPName -ErrorAction SilentlyContinue | Remove-SCOMManagementPack - } - } - } -} - -function Test-TargetResource -{ - param - ( - [ValidateSet("Present", "Absent")] - [String] $Ensure = "Present", - - [parameter(Mandatory)] - [String] $MPName, - - [parameter(Mandatory)] - [String] $MPSourcePath - ) - - $returnValue = $true - - $OMReg = Get-ItemProperty "HKLM:\Software\Microsoft\System Center Operations Manager\12\Setup\Powershell\V2" - - If (!($OMReg)) - { - Throw "Cannot find Operations Manager PowerShell module path!" - } - Else - { - $OMPSModule = $OMReg.InstallDirectory + "OperationsManager" - If (!(Get-Module OperationsManager)) { Import-Module $OMPSModule } - - $mp = (Get-SCOMManagementPack -Name $MPName -ErrorAction SilentlyContinue) - - if ($Ensure -eq 'Present') - { - if ($mp -eq $null) - { - Write-Verbose -Message "Management pack should exist but it is not installed" - $returnValue = $false - } - else - { - Write-Verbose -Message "Management pack is already installed!" - $returnValue = $true - } - } - elseif($Ensure -eq 'Absent') - { - if ($mp -ne $null) - { - Write-Verbose -Message "Management pack is installed, but Ensure value -eq $Ensure" - $returnValue = $false - } - else - { - Write-Verbose -Message "Management pack is not installed which matches Ensure value" - $returnValue = $true - } - } - - if (Test-Path $MPSourcePath) - { - Write-Verbose -Message "Source management pack files exist for comparison!" - #$returnValue = $true - } - Else - { - Write-Verbose -Message "Cannot find source management pack files for comparison at $MPSourcePath !" - #$returnValue = $false - } - } - - $returnValue; -} - - diff --git a/Resources/cSystemCenterManagement/DSCResources/ICG_SCOMImportMP/ICG_SCOMImportMP.schema.mof b/Resources/cSystemCenterManagement/DSCResources/ICG_SCOMImportMP/ICG_SCOMImportMP.schema.mof deleted file mode 100644 index 6f993d3..0000000 --- a/Resources/cSystemCenterManagement/DSCResources/ICG_SCOMImportMP/ICG_SCOMImportMP.schema.mof +++ /dev/null @@ -1,12 +0,0 @@ - -[ClassVersion("1.0.0"), FriendlyName("SCOMImportMP")] -class ICG_SCOMImportMP : OMI_BaseResource -{ - [key] string MPName; - - [required] string MPSourcePath; - - [Write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; -}; - - diff --git a/Resources/cSystemCenterManagement/Examples/SCOMAgentMG.ps1 b/Resources/cSystemCenterManagement/Examples/SCOMAgentMG.ps1 deleted file mode 100644 index b2c535c..0000000 --- a/Resources/cSystemCenterManagement/Examples/SCOMAgentMG.ps1 +++ /dev/null @@ -1,22 +0,0 @@ -Configuration AgentMG { - - Import-DscResource -ModuleName cSystemCenterManagement - - Node SCOMAG01 { - - SCOMAgentMG CheckMG { - Ensure = ?Present? - ManagementGroupName = ?OM_Contoso? - ManagementServerName = ?SCOM01.Contoso.com? - } - - } - - -} - - -AgentMG -OutputPath .\AgentMG -Start-DscConfiguration -Path .\AgentMG -Wait -Force -Verbose -ErrorAction Continue - - diff --git a/Resources/cSystemCenterManagement/Examples/SCOMImportMP.ps1 b/Resources/cSystemCenterManagement/Examples/SCOMImportMP.ps1 deleted file mode 100644 index 9adc45d..0000000 --- a/Resources/cSystemCenterManagement/Examples/SCOMImportMP.ps1 +++ /dev/null @@ -1,72 +0,0 @@ -##### -# Unzip cSystemCenterManagement.zip to C:\Program Files\WindowsPowerShell\Modules folder on server you are running this script from -# Create Share called "DSC", if the share is on another virtual machine besides DC01, change FileShr parameter below. -# Create folder called DSCResources under share folder and copy cSystemCenterManagement.zip to it. -# -# PowerShell Desired State Configuration (DSC) Resources for System Center (Revisited) -# http://www.systemcentercentral.com/powershell-desired-state-configuration-dsc-resources-for-system-center-revisited/ -##### - -$FileShr = "\\DC01\DSC" - -Configuration CopyDSCConfig -{ - param ( - [Parameter(Mandatory)] - [string]$FileShr - ) - - Node SCOM01 - { - Archive cSysCtrZip { - Ensure = "Present" - Path = "$FileShr\DSCResources\cSystemCenterManagement.zip" - Destination = "$Env:ProgramFiles\WindowsPowerShell\Modules" - Force = $True - } - } -} - -CopyDSCConfig -FileShr $FileShr -OutputPath "$Env:Temp\CopyDSCConfig" -Start-DscConfiguration -Path "$Env:Temp\CopyDSCConfig" -Wait -Force -Verbose -ErrorAction Continue - -Configuration SCOMDSCConfiguration -{ - param ( - [Parameter(Mandatory=$true)] - [ValidateNotNullOrEmpty()] - [string]$FileShr - ) - - Import-DscResource -ModuleName cSystemCenterManagement - - Node SCOM01 - { - SCOMImportMP AlertAttMP - { - Ensure = "Present" - MPName = "Microsoft.SystemCenter.AlertAttachment" - MPSourcePath = "\\DC01\DSC\mp\Microsoft.SystemCenter.AlertAttachment.mpb" - } - - Package InstallWinBaseMP - { - Ensure = "Present" - Name = "System Center Management Pack-Windows Server Operating System" - Path = "$FileShr\mp\System%20Center%20Management%20Pack-Windows%20Server%20Operating%20System.msi" - ProductId = "DF6ADE8C-5C88-41BC-87FD-AE3BA00F24E9" - } - - SCOMBulkMP ImportWinOSMp - { - Ensure = "Present" - MPSourcePath = "C:\Program Files (x86)\System Center Management Packs\System Center Management Pack-Windows Server Operating System" - DependsOn = "[Package]InstallWinBaseMp" - } - - } -} - -CopyDSCConfig -FileShr $FileShr -OutputPath "$Env:Temp\SCOMDSCConfiguration" -Start-DscConfiguration -Path "$Env:Temp\SCOMDSCConfiguration" -Wait -Force -Verbose -ErrorAction Continue - diff --git a/Resources/cSystemCenterManagement/cSystemCenterManagement.psd1 b/Resources/cSystemCenterManagement/cSystemCenterManagement.psd1 deleted file mode 100644 index ddb0df8..0000000 --- a/Resources/cSystemCenterManagement/cSystemCenterManagement.psd1 +++ /dev/null @@ -1,98 +0,0 @@ -# -# Module manifest for module 'cSCenterManagement' -# -# Generated by: !installer -# -# Generated on: 1/28/2014 -# - -@{ - -# Script module or binary module file associated with this manifest. -# RootModule = '' - -# Version number of this module. -ModuleVersion = '1.0.1' - -# ID used to uniquely identify this module -GUID = 'd30c5a87-fe29-443a-8a97-f4d96b030c57' - -# Author of this module -Author = '!installer' - -# Company or vendor of this module -CompanyName = 'Unknown' - -# Copyright statement for this module -Copyright = '(c) 2014 !installer. All rights reserved.' - -# Description of the functionality provided by this module -# Description = '' - -# Minimum version of the Windows PowerShell engine required by this module -# PowerShellVersion = '' - -# Name of the Windows PowerShell host required by this module -# PowerShellHostName = '' - -# Minimum version of the Windows PowerShell host required by this module -# PowerShellHostVersion = '' - -# Minimum version of Microsoft .NET Framework required by this module -# DotNetFrameworkVersion = '' - -# Minimum version of the common language runtime (CLR) required by this module -# CLRVersion = '' - -# Processor architecture (None, X86, Amd64) required by this module -# ProcessorArchitecture = '' - -# Modules that must be imported into the global environment prior to importing this module -# RequiredModules = @() - -# Assemblies that must be loaded prior to importing this module -# RequiredAssemblies = @() - -# Script files (.ps1) that are run in the caller's environment prior to importing this module. -# ScriptsToProcess = @() - -# Type files (.ps1xml) to be loaded when importing this module -# TypesToProcess = @() - -# Format files (.ps1xml) to be loaded when importing this module -# FormatsToProcess = @() - -# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess -# NestedModules = @() - -# Functions to export from this module -FunctionsToExport = '*' - -# Cmdlets to export from this module -CmdletsToExport = '*' - -# Variables to export from this module -VariablesToExport = '*' - -# Aliases to export from this module -AliasesToExport = '*' - -# List of all modules packaged with this module -# ModuleList = @() - -# List of all files packaged with this module -# FileList = @() - -# Private data to pass to the module specified in RootModule/ModuleToProcess -# PrivateData = '' - -# HelpInfo URI of this module -# HelpInfoURI = '' - -# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. -# DefaultCommandPrefix = '' - -} - - - diff --git a/Resources/cWebAdministration/DSCResources/PSHOrg_cAppPool/PSHOrg_cAppPool.psd1 b/Resources/cWebAdministration/DSCResources/PSHOrg_cAppPool/PSHOrg_cAppPool.psd1 deleted file mode 100644 index a5cfd2c..0000000 --- a/Resources/cWebAdministration/DSCResources/PSHOrg_cAppPool/PSHOrg_cAppPool.psd1 +++ /dev/null @@ -1,2 +0,0 @@ -@{ # Version number of this module. ModuleVersion = '1.0' # Author of this module Author = Ned Bellavance' # Company or vendor of this module CompanyName = Anexinet' # Copyright statement for this module Copyright = 'NA' # Description of the functionality provided by this module Description = 'Module with DSC Resources for Application Pool Administration' # Minimum version of the Windows PowerShell engine required by this module PowerShellVersion = '4.0' # Minimum version of the common language runtime (CLR) required by this module CLRVersion = '4.0' # Functions to export from this module FunctionsToExport = '*' # Cmdlets to export from this module CmdletsToExport = '*' } - diff --git a/Resources/cWebAdministration/DSCResources/PSHOrg_cAppPool/PSHOrg_cAppPool.psm1 b/Resources/cWebAdministration/DSCResources/PSHOrg_cAppPool/PSHOrg_cAppPool.psm1 deleted file mode 100644 index 32ac300..0000000 --- a/Resources/cWebAdministration/DSCResources/PSHOrg_cAppPool/PSHOrg_cAppPool.psm1 +++ /dev/null @@ -1,414 +0,0 @@ -data LocalizedData -{ - # culture="en-US" - ConvertFrom-StringData @' -SetTargetResourceInstallwhatIfMessage=Trying to create AppPool "{0}". -SetTargetResourceUnInstallwhatIfMessage=Trying to remove AppPool "{0}". -AppPoolNotFoundError=The requested AppPool "{0}" is not found on the target machine. -AppPoolDiscoveryFailureError=Failure to get the requested AppPool "{0}" information from the target machine. -AppPoolCreationFailureError=Failure to successfully create the AppPool "{0}". -AppPoolRemovalFailureError=Failure to successfully remove the AppPool "{0}". -AppPoolUpdateFailureError=Failure to successfully update the properties for AppPool "{0}". -AppPoolCompareFailureError=Failure to successfully compare properties for AppPool "{0}". -AppPoolStateFailureError=Failure to successfully set the state of the AppPool {0}. -'@ -} - -# The Get-TargetResource cmdlet is used to fetch the status of role or AppPool on the target machine. -# It gives the AppPool info of the requested role/feature on the target machine. -function Get-TargetResource -{ - [OutputType([hashtable])] - param - ( - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string]$Name - ) - - $getTargetResourceResult = $null; - - # Check if WebAdministration module is present for IIS cmdlets - if(!(Get-Module -ListAvailable -Name WebAdministration)) - { - Throw "Please ensure that WebAdministration module is installed." - } - - $AppPools = & $env:SystemRoot\system32\inetsrv\appcmd.exe list apppool $Name - - if ($AppPools.count -eq 0) # No AppPool exists with this name. - { - $ensureResult = "Absent"; - } - elseif ($AppPool.count -eq 1) # A single AppPool exists with this name. - { - $ensureResult = "Present" - - [xml] $PoolConfig - $PoolConfig = & $env:SystemRoot\system32\inetsrv\appcmd.exe list apppool $Name /config:* - if($PoolConfig.add.processModel.userName){ - $AppPoolPassword = $PoolConfig.add.processModel.password | ConvertTo-SecureString - $AppPoolCred = new-object -typename System.Management.Automation.PSCredential -argumentlist $PoolConfig.add.processModel.userName,$AppPoolPassword - } - else{ - $AppPoolCred =$null - } - - } - else # Multiple AppPools with the same name exist. This is not supported and is an error - { - $errorId = "AppPoolDiscoveryFailure"; - $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidResult - $errorMessage = $($LocalizedData.AppPoolUpdateFailureError) -f ${Name} - $exception = New-Object System.InvalidOperationException $errorMessage - $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $null - - $PSCmdlet.ThrowTerminatingError($errorRecord); - } - - # Add all Website properties to the hash table - $getTargetResourceResult = @{ - Name = $PoolConfig.add.name; - Ensure = $ensureResult; - autoStart = $PoolConfig.add.autoStart; - managedRuntimeVersion = $PoolConfig.add.managedRuntimeVersion; - managedPipelineMode = $PoolConfig.add.managedPipelineMode; - startMode = $PoolConfig.add.startMode; - identityType = $PoolConfig.add.processModel.identityType; - userName = $PoolConfig.add.processModel.userName; - password = $AppPoolCred - loadUserProfile = $PoolConfig.add.processModel.loadUserProfile; - - } - - return $getTargetResourceResult; -} - - -# The Set-TargetResource cmdlet is used to create, delete or configuure a website on the target machine. -function Set-TargetResource -{ - [CmdletBinding(SupportsShouldProcess=$true)] - param - ( - [ValidateSet("Present", "Absent")] - [string]$Ensure = "Present", - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string]$Name, - - [ValidateSet("true","false")] - [string]$autoStart = "true", - - [ValidateSet("v4.0","v2.0","")] - [string]$managedRuntimeVersion = "v4.0", - - [ValidateSet("Integrated","Classic")] - [string]$managedPipelineMode = "Integrated", - - [ValidateSet("AlwaysRunning","OnDemand")] - [string]$startMode = "OnDemand", - - [ValidateSet("ApplicationPoolIdentity","LocalSystem","LocalService","NetworkService","SpecificUser")] - [string]$identityType = "ApplicationPoolIdentity", - - [string]$userName, - - [System.Management.Automation.PSCredential] - $Password, - - [ValidateSet("true","false")] - [string]$loadUserProfile = "true" - - ) - - $getTargetResourceResult = $null; - - if($Ensure -eq "Present") - { - #Remove Ensure from parameters as it is not needed to create new AppPool - $Result = $psboundparameters.Remove("Ensure"); - - - # Check if WebAdministration module is present for IIS cmdlets - if(!(Get-Module -ListAvailable -Name WebAdministration)) - { - Throw "Please ensure that WebAdministration module is installed." - } - $AppPool = & $env:SystemRoot\system32\inetsrv\appcmd.exe list apppool $Name - - if($AppPool -ne $null) - { - #update parameters as required - - $UpdateNotRequired = $true - - #get configuration of AppPool - #[xml] $PoolConfig - [xml]$PoolConfig = & $env:SystemRoot\system32\inetsrv\appcmd.exe list apppool $Name /config:* - - #Update autoStart if required - if($PoolConfig.add.autoStart -ne $autoStart){ - $UpdateNotRequired = $false - & $env:SystemRoot\system32\inetsrv\appcmd.exe set apppool $Name /autoStart:$autoStart - } - - #update managedRuntimeVersion if required - if($PoolConfig.add.managedRuntimeVersion -ne $managedRuntimeVersion){ - $UpdateNotRequired = $false - & $env:SystemRoot\system32\inetsrv\appcmd.exe set apppool $Name /managedRuntimeVersion:$managedRuntimeVersion - } - #update managedPipelineMode if required - if($PoolConfig.add.managedPipelineMode -ne $managedPipelineMode){ - $UpdateNotRequired = $false - & $env:SystemRoot\system32\inetsrv\appcmd.exe set apppool $Name /managedPipelineMode:$managedPipelineMode - } - #update startMode if required - if($PoolConfig.add.startMode -ne $startMode){ - $UpdateNotRequired = $false - & $env:SystemRoot\system32\inetsrv\appcmd.exe set apppool $Name /startMode:$startMode - } - #update identityType if required - if($PoolConfig.add.processModel.identityType -ne $identityType){ - $UpdateNotRequired = $false - & $env:SystemRoot\system32\inetsrv\appcmd.exe set apppool $Name /processModel.identityType:$identityType - } - #update userName if required - if($identityType -eq "SpecificUser" -and $PoolConfig.add.processModel.userName -ne $userName){ - $UpdateNotRequired = $false - & $env:SystemRoot\system32\inetsrv\appcmd.exe set apppool $Name /processModel.userName:$userName - } - #update password if required - if($identityType -eq "SpecificUser" -and $Password){ - $clearTextPassword = $Password.GetNetworkCredential().Password - if($clearTextPassword -eq $PoolConfig.add.processModel.password){ - $UpdateNotRequired = $false - & $env:SystemRoot\system32\inetsrv\appcmd.exe set apppool $Name /processModel.password:$clearTextPassword - } - - } - #update loadUserProfile if required - if($PoolConfig.add.processModel.loadUserProfile -ne $loadUserProfile){ - $UpdateNotRequired = $false - & $env:SystemRoot\system32\inetsrv\appcmd.exe set apppool $Name /processModel.loadUserProfile:$loadUserProfile - } - - if($UpdateNotRequired) - { - Write-Verbose("AppPool $Name already exists and properties do not need to be udpated."); - } - - - } - else #AppPool doesn't exist so create new one - { - try - { - New-WebAppPool $Name - Wait-Event -Timeout 5 - Stop-WebAppPool $Name - - #Configure settings that have been passed - & $env:SystemRoot\system32\inetsrv\appcmd.exe set apppool $Name /autoStart:$autoStart - - & $env:SystemRoot\system32\inetsrv\appcmd.exe set apppool $Name /managedRuntimeVersion:$managedRuntimeVersion - - & $env:SystemRoot\system32\inetsrv\appcmd.exe set apppool $Name /managedPipelineMode:$managedPipelineMode - - & $env:SystemRoot\system32\inetsrv\appcmd.exe set apppool $Name /startMode:$startMode - - & $env:SystemRoot\system32\inetsrv\appcmd.exe set apppool $Name /processModel.identityType:$identityType - - & $env:SystemRoot\system32\inetsrv\appcmd.exe set apppool $Name /processModel.userName:$userName - - #set password if required - if($identityType -eq "SpecificUser" -and $Password){ - $clearTextPassword = $Password.GetNetworkCredential().Password - & $env:SystemRoot\system32\inetsrv\appcmd.exe set apppool $Name /processModel.password:$clearTextPassword - } - - & $env:SystemRoot\system32\inetsrv\appcmd.exe set apppool $Name /processModel.loadUserProfile:$loadUserProfile - - Write-Verbose("successfully created AppPool $Name") - - #Start site if required - if($autoStart -eq "true") - { - Start-WebAppPool $Name - } - - Write-Verbose("successfully started AppPool $Name") - } - catch - { - $errorId = "AppPoolCreationFailure"; - $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidOperation; - $errorMessage = $($LocalizedData.FeatureCreationFailureError) -f ${Name} ; - $exception = New-Object System.InvalidOperationException $errorMessage ; - $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $null - - $PSCmdlet.ThrowTerminatingError($errorRecord); - } - } - } - else #Ensure is set to "Absent" so remove website - { - try - { - $AppPool = & $env:SystemRoot\system32\inetsrv\appcmd.exe list apppool $Name - if($AppPool -ne $null) - { - Stop-WebAppPool $Name - Remove-WebAppPool $Name - - Write-Verbose("Successfully removed AppPool $Name.") - } - else - { - Write-Verbose("AppPool $Name does not exist.") - } - } - catch - { - $errorId = "AppPoolRemovalFailure"; - $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidOperation; - $errorMessage = $($LocalizedData.WebsiteRemovalFailureError) -f ${Name} ; - $exception = New-Object System.InvalidOperationException $errorMessage ; - $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $null - - $PSCmdlet.ThrowTerminatingError($errorRecord); - } - - } -} - - -# The Test-TargetResource cmdlet is used to validate if the role or feature is in a state as expected in the instance document. -function Test-TargetResource -{ - [OutputType([bool])] - param - ( - [ValidateSet("Present", "Absent")] - [string]$Ensure = "Present", - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string]$Name, - - [ValidateSet("true","false")] - [string]$autoStart = "true", - - [ValidateSet("v4.0","v2.0","")] - [string]$managedRuntimeVersion = "v4.0", - - [ValidateSet("Integrated","Classic")] - [string]$managedPipelineMode = "Integrated", - - [ValidateSet("AlwaysRunning","OnDemand")] - [string]$startMode = "OnDemand", - - [ValidateSet("ApplicationPoolIdentity","LocalSystem","LocalService","NetworkService","SpecificUser")] - [string]$identityType = "ApplicationPoolIdentity", - - [string]$userName, - - [System.Management.Automation.PSCredential] - $Password, - - [ValidateSet("true","false")] - [string]$loadUserProfile = "true" - ) - - $DesiredConfigurationMatch = $true - - # Check if WebAdministration module is present for IIS cmdlets - if(!(Get-Module -ListAvailable -Name WebAdministration)) - { - Throw "Please ensure that WebAdministration module is installed." - } - - $AppPool = & $env:SystemRoot\system32\inetsrv\appcmd.exe list apppool $Name - if($AppPool){ - #get configuration of AppPool - #[xml] $PoolConfig - [xml]$PoolConfig = & $env:SystemRoot\system32\inetsrv\appcmd.exe list apppool $Name /config:* - } - $Stop = $true - - Do - { - #Check Ensure - if(($Ensure -eq "Present" -and $AppPool -eq $null) -or ($Ensure -eq "Absent" -and $AppPool -ne $null)) - { - $DesiredConfigurationMatch = $false - Write-Verbose("The Ensure state for AppPool $Name does not match the desired state."); - break - } - - # Only check properties if $AppPool exists - if ($AppPool -ne $null) - { - #Check autoStart - if($PoolConfig.add.autoStart -ne $autoStart){ - $DesiredConfigurationMatch = $false - Write-Verbose("autoStart of AppPool $Name does not match the desired state."); - break - } - - #Check managedRuntimeVersion - if($PoolConfig.add.managedRuntimeVersion -ne $managedRuntimeVersion){ - $DesiredConfigurationMatch = $false - Write-Verbose("managedRuntimeVersion of AppPool $Name does not match the desired state."); - break - } - #Check managedPipelineMode - if($PoolConfig.add.managedPipelineMode -ne $managedPipelineMode){ - $DesiredConfigurationMatch = $false - Write-Verbose("managedPipelineMode of AppPool $Name does not match the desired state."); - break - } - #Check startMode - if($PoolConfig.add.startMode -ne $startMode){ - $DesiredConfigurationMatch = $false - Write-Verbose("startMode of AppPool $Name does not match the desired state."); - break - } - #Check identityType - if($PoolConfig.add.processModel.identityType -ne $identityType){ - $DesiredConfigurationMatch = $false - Write-Verbose("identityType of AppPool $Name does not match the desired state."); - break - } - #Check userName - if($PoolConfig.add.processModel.userName -ne $userName){ - $DesiredConfigurationMatch = $false - Write-Verbose("userName of AppPool $Name does not match the desired state."); - break - } - #Check password - if($identityType -eq "SpecificUser" -and $Password){ - $clearTextPassword = $Password.GetNetworkCredential().Password - if($clearTextPassword -eq $PoolConfig.add.processModel.password){ - $DesiredConfigurationMatch = $false - Write-Verbose("Password of AppPool $Name does not match the desired state."); - break - } - - } - #Check loadUserProfile - if($PoolConfig.add.processModel.loadUserProfile -ne $loadUserProfile){ - $DesiredConfigurationMatch = $false - Write-Verbose("loadUserProfile of AppPool $Name does not match the desired state."); - break - } - } - - $Stop = $false - } - While($Stop) - - return $DesiredConfigurationMatch -} - diff --git a/Resources/cWebAdministration/DSCResources/PSHOrg_cAppPool/PSHOrg_cAppPool.schema.mof b/Resources/cWebAdministration/DSCResources/PSHOrg_cAppPool/PSHOrg_cAppPool.schema.mof deleted file mode 100644 index b4d1f43..0000000 Binary files a/Resources/cWebAdministration/DSCResources/PSHOrg_cAppPool/PSHOrg_cAppPool.schema.mof and /dev/null differ diff --git a/Resources/cWebAdministration/DSCResources/PSHOrg_cWebsite/PSHOrg_cWebsite.psm1 b/Resources/cWebAdministration/DSCResources/PSHOrg_cWebsite/PSHOrg_cWebsite.psm1 deleted file mode 100644 index 7a7a66d..0000000 --- a/Resources/cWebAdministration/DSCResources/PSHOrg_cWebsite/PSHOrg_cWebsite.psm1 +++ /dev/null @@ -1,733 +0,0 @@ -data LocalizedData -{ - # culture="en-US" - ConvertFrom-StringData @' -SetTargetResourceInstallwhatIfMessage=Trying to create website "{0}". -SetTargetResourceUnInstallwhatIfMessage=Trying to remove website "{0}". -WebsiteNotFoundError=The requested website "{0}" is not found on the target machine. -WebsiteDiscoveryFailureError=Failure to get the requested website "{0}" information from the target machine. -WebsiteCreationFailureError=Failure to successfully create the website "{0}". -WebsiteRemovalFailureError=Failure to successfully remove the website "{0}". -WebsiteUpdateFailureError=Failure to successfully update the properties for website "{0}". -WebsiteBindingUpdateFailureError=Failure to successfully update the bindings for website "{0}". -WebsiteBindingInputInvalidationError=Desired website bindings not valid for website "{0}". -WebsiteCompareFailureError=Failure to successfully compare properties for website "{0}". -WebBindingCertifcateError=Failure to add certificate to web binding. -WebsiteStateFailureError=Failure to successfully set the state of the website {0}. -'@ -} - -# The Get-TargetResource cmdlet is used to fetch the status of role or Website on the target machine. -# It gives the Website info of the requested role/feature on the target machine. -function Get-TargetResource -{ - [OutputType([System.Collections.Hashtable])] - param - ( - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string]$Name, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string]$PhysicalPath - ) - # The LCM requires Get-TargetResource to take all Key AND Required properties as parameters, even though - # the Required properties such as PhysicalPath are really part of Get-TargetResource's output, not its - # input. This is probably an LCM bug. - # We're not actually doing anything with whatever value was passed in to $PhysicalPath here. - - $getTargetResourceResult = $null; - - # Check if WebAdministration module is present for IIS cmdlets - if(!(Get-Module -ListAvailable -Name WebAdministration)) - { - Throw "Please ensure that WebAdministration module is installed." - } - - $Website = Get-Website -Name $Name - - if ($Website.count -eq 0) # No Website exists with this name. - { - $ensureResult = "Absent"; - } - elseif ($Website.count -eq 1) # A single Website exists with this name. - { - $ensureResult = "Present" - - [PSObject[]] $Bindings - $Bindings = (get-itemProperty -path IIS:\Sites\$Name -Name Bindings).collection - - $CimBindings = foreach ($binding in $bindings) - { - $BindingObject = get-WebBindingObject -BindingInfo $binding - New-CimInstance -ClassName PSHOrg_cWebBindingInformation -Namespace root/microsoft/Windows/DesiredStateConfiguration -Property @{Port=[System.UInt16]$BindingObject.Port;Protocol=$BindingObject.Protocol;IPAddress=$BindingObject.IPaddress;HostName=$BindingObject.Hostname;CertificateThumbprint=$BindingObject.CertificateThumbprint;CertificateStoreName=$BindingObject.CertificateStoreName} -ClientOnly - } - } - else # Multiple websites with the same name exist. This is not supported and is an error - { - $errorId = "WebsiteDiscoveryFailure"; - $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidResult - $errorMessage = $($LocalizedData.WebsiteUpdateFailureError) -f ${Name} - $exception = New-Object System.InvalidOperationException $errorMessage - $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $null - - $PSCmdlet.ThrowTerminatingError($errorRecord); - } - - # Add all Website properties to the hash table - $getTargetResourceResult = @{ - Name = $Website.Name; - Ensure = $ensureResult; - PhysicalPath = $Website.physicalPath; - State = $Website.state; - ID = $Website.id; - ApplicationPool = $Website.applicationPool; - BindingInfo = $CimBindings; - } - - return $getTargetResourceResult; -} - - -# The Set-TargetResource cmdlet is used to create, delete or configuure a website on the target machine. -function Set-TargetResource -{ - [CmdletBinding(SupportsShouldProcess=$true)] - param - ( - [ValidateSet("Present", "Absent")] - [string]$Ensure = "Present", - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string]$Name, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string]$PhysicalPath, - - [ValidateSet("Started", "Stopped")] - [string]$State = "Started", - - [string]$ApplicationPool, - - [Microsoft.Management.Infrastructure.CimInstance[]]$BindingInfo - ) - - $getTargetResourceResult = $null; - - if($Ensure -eq "Present") - { - #Remove Ensure from parameters as it is not needed to create new website - $Result = $psboundparameters.Remove("Ensure"); - #Remove State parameter form website. Will start the website after configuration is complete - $Result = $psboundparameters.Remove("State"); - - #Remove bindings from parameters if they exist - #Bindings will be added to site using separate cmdlet - $Result = $psboundparameters.Remove("BindingInfo"); - - # Check if WebAdministration module is present for IIS cmdlets - if(!(Get-Module -ListAvailable -Name WebAdministration)) - { - Throw "Please ensure that WebAdministration module is installed." - } - $website = get-website $Name - - if($website -ne $null) - { - #update parameters as required - - $UpdateNotRequired = $true - - #Update Physical Path if required - if(ValidateWebsitePath -Name $Name -PhysicalPath $PhysicalPath) - { - $UpdateNotRequired = $false - Set-ItemProperty "IIS:\Sites\$Name" -Name physicalPath -Value $PhysicalPath -ErrorAction Stop - - Write-Verbose("Physical path for website $Name has been updated to $PhysicalPath"); - } - - #Update Bindings if required - if ($BindingInfo -ne $null) - { - if(ValidateWebsiteBindings -Name $Name -BindingInfo $BindingInfo) - { - $UpdateNotRequired = $false - #Update Bindings - UpdateBindings -Name $Name -BindingInfo $BindingInfo -ErrorAction Stop - - Write-Verbose("Bindings for website $Name have been updated."); - } - } - - #Update Application Pool if required - if(($website.applicationPool -ne $ApplicationPool) -and ($ApplicationPool -ne "")) - { - $UpdateNotRequired = $false - Set-ItemProperty IIS:\Sites\$Name -Name applicationPool -Value $ApplicationPool -ErrorAction Stop - - Write-Verbose("Application Pool for website $Name has been updated to $ApplicationPool") - } - - #Update State if required - if($website.state -ne $State -and $State -ne "") - { - try - { - $UpdateNotRequired = $false - if($State -eq "Started") - { - - Start-Website -Name $Name - - } - else - { - Stop-Website -Name $Name - } - - Write-Verbose("State for website $Name has been updated to $State"); - - } - catch - { - $errorId = "WebsiteStateFailure"; - $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidOperation; - $errorMessage = $($LocalizedData.WebsiteStateFailureError) -f ${Name} ; - $exception = New-Object System.InvalidOperationException $errorMessage ; - $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $null - - $PSCmdlet.ThrowTerminatingError($errorRecord); - } - } - - if($UpdateNotRequired) - { - Write-Verbose("Website $Name already exists and properties do not need to be udpated."); - } - - - } - else #Website doesn't exist so create new one - { - try - { - $Website = New-Website @psboundparameters - $Result = Stop-Website $Website.name -ErrorAction Stop - - #Clear default bindings if new bindings defined and are different - if($BindingInfo -ne $null) - { - if(ValidateWebsiteBindings -Name $Name -BindingInfo $BindingInfo) - { - UpdateBindings -Name $Name -BindingInfo $BindingInfo - } - } - - Write-Verbose("successfully created website $Name") - - #Start site if required - if($State -eq "Started") - { - #Wait 1 sec for bindings to take effect - #I have found that starting the website results in an error if it happens to quickly - Start-Sleep -s 1 - Start-Website -Name $Name -ErrorAction Stop - } - - Write-Verbose("successfully started website $Name") - } - catch - { - $errorId = "WebsiteCreationFailure"; - $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidOperation; - $errorMessage = $($LocalizedData.FeatureCreationFailureError) -f ${Name} ; - $exception = New-Object System.InvalidOperationException $errorMessage ; - $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $null - - $PSCmdlet.ThrowTerminatingError($errorRecord); - } - } - } - else #Ensure is set to "Absent" so remove website - { - try - { - $website = get-website $Name - if($website -ne $null) - { - Remove-website -name $Name - - Write-Verbose("Successfully removed Website $Name.") - } - else - { - Write-Verbose("Website $Name does not exist.") - } - } - catch - { - $errorId = "WebsiteRemovalFailure"; - $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidOperation; - $errorMessage = $($LocalizedData.WebsiteRemovalFailureError) -f ${Name} ; - $exception = New-Object System.InvalidOperationException $errorMessage ; - $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $null - - $PSCmdlet.ThrowTerminatingError($errorRecord); - } - - } -} - - -# The Test-TargetResource cmdlet is used to validate if the role or feature is in a state as expected in the instance document. -function Test-TargetResource -{ - [OutputType([System.Boolean])] - param - ( - [ValidateSet("Present", "Absent")] - [string]$Ensure = "Present", - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string]$Name, - - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string]$PhysicalPath, - - [ValidateSet("Started", "Stopped")] - [string]$State = "Started", - - [string]$ApplicationPool, - - [Microsoft.Management.Infrastructure.CimInstance[]]$BindingInfo - ) - - $DesiredConfigurationMatch = $true; - - # Check if WebAdministration module is present for IIS cmdlets - if(!(Get-Module -ListAvailable -Name WebAdministration)) - { - Throw "Please ensure that WebAdministration module is installed." - } - - $website = Get-Website -Name $Name - $Stop = $true - - Do - { - #Check Ensure - if(($Ensure -eq "Present" -and $website -eq $null) -or ($Ensure -eq "Absent" -and $website -ne $null)) - { - $DesiredConfigurationMatch = $false - Write-Verbose("The Ensure state for website $Name does not match the desired state."); - break - } - - # Only check properties if $website exists - if ($website -ne $null) - { - #Check Physical Path property - if(ValidateWebsitePath -Name $Name -PhysicalPath $PhysicalPath) - { - $DesiredConfigurationMatch = $false - Write-Verbose("Physical Path of Website $Name does not match the desired state."); - break - } - - #Check State - if($website.state -ne $State -and $State -ne $null) - { - $DesiredConfigurationMatch = $false - Write-Verbose("The state of Website $Name does not match the desired state."); - break - } - - #Check Application Pool property - if(($ApplicationPool -ne "") -and ($website.applicationPool -ne $ApplicationPool)) - { - $DesiredConfigurationMatch = $false - Write-Verbose("Application Pool for Website $Name does not match the desired state."); - break - } - - #Check Binding properties - if($BindingInfo -ne $null) - { - if(ValidateWebsiteBindings -Name $Name -BindingInfo $BindingInfo) - { - $DesiredConfigurationMatch = $false - Write-Verbose("Bindings for website $Name do not mach the desired state."); - break - } - - } - } - - $Stop = $false - } - While($Stop) - - $DesiredConfigurationMatch; -} - -#region HelperFunctions -# ValidateWebsite is a helper function used to validate the results -function ValidateWebsite -{ - param - ( - [object] $Website, - - [string] $Name - ) - - # If a wildCard pattern is not supported by the website provider. - # Hence we restrict user to request only one website information in a single request. - if($Website.Count-gt 1) - { - $errorId = "WebsiteDiscoveryFailure"; - $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidResult - $errorMessage = $($LocalizedData.WebsiteDiscoveryFailureError) -f ${Name} - $exception = New-Object System.InvalidOperationException $errorMessage - $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $null - - $PSCmdlet.ThrowTerminatingError($errorRecord); - } -} - -# Helper function used to validate website path -function ValidateWebsitePath -{ - param - ( - [string] $Name, - - [string] $PhysicalPath - ) - - $PathNeedsUpdating = $false - - if((Get-ItemProperty "IIS:\Sites\$Name" -Name physicalPath) -ne $PhysicalPath) - { - $PathNeedsUpdating = $true - } - - $PathNeedsUpdating - -} - -# Helper function used to validate website bindings -# Returns true if bindings are valid (ie. port, IPAddress & Hostname combinations are unique). - -function ValidateWebsiteBindings -{ - Param - ( - [parameter()] - [string] - $Name, - - [parameter()] - [Microsoft.Management.Infrastructure.CimInstance[]] - $BindingInfo - ) - - - $Valid = $true - - foreach($binding in $BindingInfo) - { - # First ensure that desired binding information is valid ie. No duplicate IPAddres, Port, Host name combinations. - - if (!(EnsurePortIPHostUnique -Port $binding.Port -IPAddress $binding.IPAddress -HostName $Binding.Hostname -BindingInfo $BindingInfo) ) - { - $errorId = "WebsiteBindingInputInvalidation"; - $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidResult - $errorMessage = $($LocalizedData.WebsiteBindingInputInvalidationError) -f ${Name} - $exception = New-Object System.InvalidOperationException $errorMessage - $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $null - - $PSCmdlet.ThrowTerminatingError($errorRecord); - } - } - - return compareWebsiteBindings -Name $Name -BindingInfo $BindingInfo -} - -function EnsurePortIPHostUnique -{ - param - ( - [parameter()] - [System.UInt16] - $Port, - - [parameter()] - [string] - $IPAddress, - - [parameter()] - [string] - $HostName, - - [parameter(Mandatory=$true)] - [ValidateNotNullOrEmpty()] - [Microsoft.Management.Infrastructure.CimInstance[]] - $BindingInfo - ) - - $UniqueInstances = 0 - - foreach ($Binding in $BindingInfo) - { - if($binding.Port -eq $Port -and [string]$Binding.IPAddress -eq $IPAddress -and [string]$Binding.HostName -eq $HostName) - { - $UniqueInstances += 1 - } - } - - if($UniqueInstances -gt 1) - { - return $false - } - else - { - return $true - } -} - -# Helper function used to compare website bindings of actual to desired -# Returns true if bindings need to be updated and false if not. -function compareWebsiteBindings -{ - param - ( - [parameter()] - [string] - $Name, - - [parameter(Mandatory=$true)] - [ValidateNotNullOrEmpty()] - [Microsoft.Management.Infrastructure.CimInstance[]] - $BindingInfo - ) - #Assume bindingsNeedUpdating - $BindingNeedsUpdating = $false - - #check to see if actual settings have been passed in. If not get them from website - if($ActualBindings -eq $null) - { - $ActualBindings = Get-Website $Name | Get-WebBinding - - #Format Binding information: Split BindingInfo into individual Properties (IPAddress:Port:HostName) - $ActualBindingObjects = @() - foreach ($ActualBinding in $ActualBindings) - { - $ActualBindingObjects += get-WebBindingObject -BindingInfo $ActualBinding - } - } - - #Compare Actual Binding info ($FormatActualBindingInfo) to Desired($BindingInfo) - try - { - if($BindingInfo.Count -le $ActualBindingObjects.Count) - { - foreach($Binding in $BindingInfo) - { - $ActualBinding = $ActualBindingObjects | ?{$_.Port -eq $Binding.CimInstanceProperties["Port"].Value} - if ($ActualBinding -ne $null) - { - if([string]$ActualBinding.Protocol -ne [string]$Binding.CimInstanceProperties["Protocol"].Value) - { - $BindingNeedsUpdating = $true - break - } - - if([string]$ActualBinding.IPAddress -ne [string]$Binding.CimInstanceProperties["IPAddress"].Value) - { - # Special case where blank IPAddress is saved as "*" in the binding information. - if([string]$ActualBinding.IPAddress -eq "*" -AND [string]$Binding.CimInstanceProperties["IPAddress"].Value -eq "") - { - #Do nothing - } - else - { - $BindingNeedsUpdating = $true - break - } - } - - if([string]$ActualBinding.HostName -ne [string]$Binding.CimInstanceProperties["HostName"].Value) - { - $BindingNeedsUpdating = $true - break - } - - if([string]$ActualBinding.CertificateThumbprint -ne [string]$Binding.CimInstanceProperties["CertificateThumbprint"].Value) - { - $BindingNeedsUpdating = $true - break - } - - if([string]$ActualBinding.CertificateStoreName -ne [string]$Binding.CimInstanceProperties["CertificateStoreName"].Value) - { - $BindingNeedsUpdating = $true - break - } - } - else - { - { - $BindingNeedsUpdating = $true - break - } - } - } - } - else - { - $BindingNeedsUpdating = $true - } - - $BindingNeedsUpdating - - } - catch - { - $errorId = "WebsiteCompareFailure"; - $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidResult - $errorMessage = $($LocalizedData.WebsiteCompareFailureError) -f ${Name} - $exception = New-Object System.InvalidOperationException $errorMessage - $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $null - - $PSCmdlet.ThrowTerminatingError($errorRecord); - } -} - -function UpdateBindings -{ - param - ( - [parameter(Mandatory=$true)] - [ValidateNotNullOrEmpty()] - [string] - $Name, - - [parameter()] - [Microsoft.Management.Infrastructure.CimInstance[]] - $BindingInfo - ) - - #Need to clear the bindings before we can create new ones - Clear-ItemProperty IIS:\Sites\$Name -Name bindings -ErrorAction Stop - - foreach($binding in $BindingInfo) - { - - $Protocol = $Binding.CimInstanceProperties["Protocol"].Value - $IPAddress = $Binding.CimInstanceProperties["IPAddress"].Value - $Port = $Binding.CimInstanceProperties["Port"].Value - $HostHeader = $Binding.CimInstanceProperties["HostName"].Value - $CertificateThumbprint = $Binding.CimInstanceProperties["CertificateThumbprint"].Value - $CertificateStoreName = $Binding.CimInstanceProperties["CertificateStoreName"].Value - - $bindingParams = @{} - $bindingParams.Add('-Name', $Name) - $bindingParams.Add('-Port', $Port) - - #Set IP Address parameter - if($IPAddress -ne $null) - { - $bindingParams.Add('-IPAddress', $IPAddress) - } - else # Default to any/all IP Addresses - { - $bindingParams.Add('-IPAddress', '*') - } - - #Set protocol parameter - if($Protocol-ne $null) - { - $bindingParams.Add('-Protocol', $Protocol) - } - else #Default to Http - { - $bindingParams.Add('-Protocol', 'http') - } - - #Set Host parameter if it exists - if($HostHeader-ne $null){$bindingParams.Add('-HostHeader', $HostHeader)} - - try - { - New-WebBinding @bindingParams -ErrorAction Stop - } - Catch - { - $errorId = "WebsiteBindingUpdateFailure"; - $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidResult - $errorMessage = $($LocalizedData.WebsiteUpdateFailureError) -f ${Name} - $exception = New-Object System.InvalidOperationException $errorMessage - $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $null - - $PSCmdlet.ThrowTerminatingError($errorRecord); - } - - try - { - if($CertificateThumbprint -ne $null) - { - $NewWebbinding = get-WebBinding -name $Name -Port $Port - $newwebbinding.AddSslCertificate($CertificateThumbprint, $CertificateStoreName) - } - } - catch - { - $errorId = "WebBindingCertifcateError"; - $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidOperation; - $errorMessage = $($LocalizedData.WebBindingCertifcateError) -f ${Name} ; - $exception = New-Object System.InvalidOperationException $errorMessage ; - $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $null - - $PSCmdlet.ThrowTerminatingError($errorRecord); - } - } - -} - -function get-WebBindingObject -{ - Param - ( - $BindingInfo - ) - - #First split properties by ']:'. This will get IPv6 address split from port and host name - $Split = $BindingInfo.BindingInformation.split("[]") - if($Split.count -gt 1) - { - $IPAddress = $Split.item(1) - $Port = $split.item(2).split(":").item(1) - $HostName = $split.item(2).split(":").item(2) - } - else - { - $SplitProps = $BindingInfo.BindingInformation.split(":") - $IPAddress = $SplitProps.item(0) - $Port = $SplitProps.item(1) - $HostName = $SplitProps.item(2) - } - - $WebBindingObject = New-Object PSObject -Property @{Protocol = $BindingInfo.protocol;IPAddress = $IPAddress;Port = $Port;HostName = $HostName;CertificateThumbprint = $BindingInfo.CertificateHash;CertificateStoreName = $BindingInfo.CertificateStoreName} - - return $WebBindingObject -} - -#endregion - diff --git a/Resources/cWebAdministration/DSCResources/PSHOrg_cWebsite/PSHOrg_cWebsite.schema.mof b/Resources/cWebAdministration/DSCResources/PSHOrg_cWebsite/PSHOrg_cWebsite.schema.mof deleted file mode 100644 index aee5eba..0000000 Binary files a/Resources/cWebAdministration/DSCResources/PSHOrg_cWebsite/PSHOrg_cWebsite.schema.mof and /dev/null differ diff --git a/Resources/cWebAdministration/Documentation-cWebAdministration.docx b/Resources/cWebAdministration/Documentation-cWebAdministration.docx deleted file mode 100644 index 1edc73c..0000000 Binary files a/Resources/cWebAdministration/Documentation-cWebAdministration.docx and /dev/null differ diff --git a/Resources/cWebAdministration/Documentation-cWebAdministration.md b/Resources/cWebAdministration/Documentation-cWebAdministration.md deleted file mode 100644 index a540685..0000000 --- a/Resources/cWebAdministration/Documentation-cWebAdministration.md +++ /dev/null @@ -1,429 +0,0 @@ -##xWebAdministration Module – Windows PowerShell Desired State Configuration Resource Kit - -###Introduction -The **xWebAdministration** module is a part of Windows PowerShell Desired State Configuration (DSC) Resource Kit, which is a collection of DSC Resources produced by the PowerShell Team. This module contains the **xWebsite and xIisModule** resource. These DSC Resources allow configuration of IIS Website. - -**All of the resources in the DSC Resource Kit are provided AS IS, and are not supported through any Microsoft standard support program or service. The “x” in xWebAdministration stands for experimental**, which means that these resources will be **fix forward** and monitored by the module owner(s). - -Please leave comments, feature requests, and bug reports in the Q & A tab for this module. - -If you would like to modify **xWebAdministraion** module, feel free. When modifying, please update the module name, resource friendly name, and MOF class name (instructions below). As specified in the license, you may copy or modify this resource as long as they are used on the Windows Platform. - -For more information about Windows PowerShell Desired State Configuration, check out the blog posts on the [PowerShell Blog](http://blogs.msdn.com/b/powershell/) ([this](http://blogs.msdn.com/b/powershell/archive/2013/11/01/configuration-in-a-devops-world-windows-powershell-desired-state-configuration.aspx) is a good starting point). There are also great community resources, such as [PowerShell.org](http://powershell.org/wp/tag/dsc/), or [PowerShell Magazine](http://www.powershellmagazine.com/tag/dsc/). For more information on the DSC Resource Kit, check out [this blog post](http://go.microsoft.com/fwlink/?LinkID=389546). - -###Installation -To install **xWebAdministration** module - -* Unzip the content under $env:ProgramFiles\WindowsPowerShell\Modules folder - -To confirm installation: - -* Run **Get-DSCResource** to see that **xWebsite** is among the DSC Resources listed - -###Requirements -This module requires the latest version of PowerShell (v4.0, which ships in Windows 8.1 or Windows Server 2012R2). It also requires IIS features. To easily use PowerShell 4.0 on older operating systems, [install WMF 4.0](http://www.microsoft.com/en-us/download/details.aspx?id=40855). Please read the installation instructions that are present on both the download page and the release notes for WMF 4.0. - -###Description -The **xWebsiteAdministration** module contains the **xWebsite** DSC Resource. This DSC Resource allows for simple configuration of IIS Websites. Using this resource, you can define your website’s state, application pool, binding info, and other characteristics. When used with the Windows Feature and File Resources (that ships in Windows), this resource allows you to set up a web server entirely through DSC. - -The **xWebsiteAdministration** module contains the **xIisModule** DSC Resource. This DSC Resource allows for registration of modules, such as FastCgiModules, with IIS. Using this resource, you can define your where you module is, the paths and verbs allowed. - -###Details -**xWebsite** resource has following properties: - -* **Name**: The desired name of the website -* **PhysicalPath**: The path of the files that compose the website -* **State**: State of the website – started or stopped -* **Protocol**: Web protocol (currently only “http” is supported) -* **BindingInfo**: Binding information to match the above protocol -* **ApplicationPool**: The website’s application pool -* **Ensure**: Should website be present or absent -* **DefaultPage**: On array of default page(s) for the site. - -###Details -**xIisModule** resource has following properties: - -* **Path**: The path to the module to be registered. -* **Name**: The logical name to register the module as in IIS. -* **RequestPath**: The allowed request paths, such as *.php. -* **Verb**: An array of allowed verbs, such as get and post. -* **SiteName**: The name of the Site to register the module for. If empty, the resource will register the module with all of IIS. - **ModuleType**: The type of the module. Currently, only FastCgiModule is supported. -* **Ensure**: Should module be present or absent - -###Example: Stopping the default website -When configuring a new IIS Server, several references recommend removing or stopping the default website for security purposes. This example sets up your IIS webserver by installing IIS Windows Feature. Following that, it will stop the default website by setting “State = Stopped ”. - - configuration Sample_xWebsite_StopDefault - { - param - ( - # Target nodes to apply the configuration - [string[]]$NodeName = 'localhost' - ) - - # Import the module that defines custom resources - Import-DscResource -Module xWebAdministration - - Node $NodeName - { - # Install the IIS role - WindowsFeature IIS - { - Ensure = "Present" - Name = "Web-Server" - } - - # Stop the default website - xWebsite DefaultSite - { - Ensure = "Present" - Name = "Default Web Site" - State = "Stopped" - PhysicalPath = "C:\inetpub\wwwroot" - DependsOn = "[WindowsFeature]IIS" - } - } - } - -###Example: Create a new website -While setting up IIS and stopping the default website is interesting, it isn’t quite useful yet. After all, typically people use IIS to set up websites of your own. Fortunately, using DSC, adding another website is as simple as using the File and **xWebsite** resources to copy the website content and configure the website with a default page. - - configuration Sample_xWebsite_NewWebsite - { - param - ( - # Target nodes to apply the configuration - [string[]]$NodeName = 'localhost', - - # Name of the website to create - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String]$WebSiteName, - - # Source Path for Website content - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String]$SourcePath, - - # Destination path for Website content - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String]$DestinationPath - ) - - # Import the module that defines custom resources - Import-DscResource -Module xWebAdministration - - Node $NodeName - { - # Install the IIS role - WindowsFeature IIS - { - Ensure = "Present" - Name = "Web-Server" - } - - # Install the ASP .NET 4.5 role - WindowsFeature AspNet45 - { - Ensure = "Present" - Name = "Web-Asp-Net45" - } - - # Stop the default website - xWebsite DefaultSite - { - Ensure = "Present" - Name = "Default Web Site" - State = "Stopped" - PhysicalPath = "C:\inetpub\wwwroot" - DependsOn = "[WindowsFeature]IIS" - } - - # Copy the website content - File WebContent - { - Ensure = "Present" - SourcePath = $SourcePath - DestinationPath = $DestinationPath - Recurse = $true - Type = "Directory" - DependsOn = "[WindowsFeature]AspNet45" - } - - # Create the new Website - xWebsite NewWebsite - { - Ensure = "Present" - Name = $WebSiteName - State = "Started" - PhysicalPath = $DestinationPath - DefaultPage = "Default.aspx" - DependsOn = "[File]WebContent" - } - } - } - -###Example: Removing the default website -In this example, we’ve moved the parameters used to generate the website into a configuration data file – all of the variant portions of the configuration are stored in a separate file. This can be a powerful tool when using DSC to configure a project that will be deployed to multiple environments. For example, users managing larger environments may want to test their configuration on a small number of machines before deploying it across many more machines in their production environment. -Configuration files are made with this in mind. This is an example configuration data file (saved as a .psd1). - - configuration Sample_xWebsite_FromConfigurationData - { - # Import the module that defines custom resources - Import-DscResource -Module xWebAdministration - - # Dynamically find the applicable nodes from configuration data - Node $AllNodes.where{$_.Role -eq "Web"}.NodeName - { - # Install the IIS role - WindowsFeature IIS - { - Ensure = "Present" - Name = "Web-Server" - } - - # Install the ASP .NET 4.5 role - WindowsFeature AspNet45 - { - Ensure = "Present" - Name = "Web-Asp-Net45" - } - - # Stop an existing website (set up in Sample_xWebsite_Default) - xWebsite DefaultSite - { - Ensure = "Present" - Name = "Default Web Site" - State = "Stopped" - PhysicalPath = $Node.DefaultWebSitePath - DependsOn = "[WindowsFeature]IIS" - } - - # Copy the website content - File WebContent - { - Ensure = "Present" - SourcePath = $Node.SourcePath - DestinationPath = $Node.DestinationPath - Recurse = $true - Type = "Directory" - DependsOn = "[WindowsFeature]AspNet45" - } - - # Create a new website - xWebsite BakeryWebSite - { - Ensure = "Present" - Name = $Node.WebsiteName - State = "Started" - PhysicalPath = $Node.DestinationPath - DependsOn = "[File]WebContent" - } - } - } - -Content of configuration data file (e.g. ConfigurationData.psd1) could be: - - # Hashtable to define the environmental data - @{ - # Node specific data - AllNodes = @( - - # All the WebServer has following identical information - @{ - NodeName = "*" - WebsiteName = "FourthCoffee" - SourcePath = "C:\BakeryWebsite\" - DestinationPath = "C:\inetpub\FourthCoffee" - DefaultWebSitePath = "C:\inetpub\wwwroot" - }, - - @{ - NodeName = "WebServer1.fourthcoffee.com" - Role = "Web" - }, - - @{ - NodeName = "WebServer2.fourthcoffee.com" - Role = "Web" - } - ); - } - -Pass the configuration data to configuration as follows: - - Sample_xWebsite_FromConfigurationData -ConfigurationData ConfigurationData.psd1 - -###Example: Registering Php -When configuring an IIS Application that uses PHP, you first need to register the PHP CGI module with IIS. The following xPhp configuration downloads and installs the prerequisites for PHP, downloads PHP, registers the PHP CGI module with IIS and sets the system environment variable that PHP needs to run. - -Note: this sample is intended to be used as a composite resource, so it does not use Configuration Data. Please see the [Composite Configuration Blog](http://blogs.msdn.com/b/powershell/archive/2014/02/25/reusing-existing-configuration-scripts-in-powershell-desired-state-configuration.aspx) on how to use this in configuration in another configuration. - - - - # Composite configuration to install the IIS pre-requisites for php - Configuration IisPreReqs_php - { - param - ( - [Parameter(Mandatory = $true)] - [Validateset("Present","Absent")] - [String] - $Ensure - ) - - foreach ($Feature in @("Web-Server","Web-Mgmt-Tools","web-Default-Doc", ` - "Web-Dir-Browsing","Web-Http-Errors","Web-Static-Content",` - "Web-Http-Logging","web-Stat-Compression","web-Filtering",` - "web-CGI","web-ISAPI-Ext","web-ISAPI-Filter")) - { - WindowsFeature "$Feature$Number" - { - Ensure = $Ensure - Name = $Feature - } - } - } - - # Composite configuration to install PHP on IIS - configuration xPhp - { - param( - [Parameter(Mandatory = $true)] - [switch] $installMySqlExt, - - [Parameter(Mandatory = $true)] - [string] $PackageFolder, - - [Parameter(Mandatory = $true)] - [string] $DownloadUri, - - [Parameter(Mandatory = $true)] - [string] $Vc2012RedistDownloadUri, - - [Parameter(Mandatory = $true)] - [String] $DestinationPath, - - [Parameter(Mandatory = $true)] - [string] $ConfigurationPath - ) - # Make sure the IIS Prerequisites for PHP are present - IisPreReqs_php Iis - { - Ensure = "Present" - - # Removed because this dependency does not work in - # Windows Server 2012 R2 and below - # This should work in WMF v5 and above - # DependsOn = "[File]PackagesFolder" - } - - # Download and install Visual C Redist2012 from chocolatey.org - Package vcRedist - { - Path = $Vc2012RedistDownloadUri - ProductId = "{CF2BEA3C-26EA-32F8-AA9B-331F7E34BA97}" - Name = "Microsoft Visual C++ 2012 x64 Minimum Runtime - 11.0.61030" - Arguments = "/install /passive /norestart" - } - - $phpZip = Join-Path $PackageFolder "php.zip" - - # Make sure the PHP archine is in the package folder - xRemoteFile phpArchive - { - uri = $DownloadURI - DestinationPath = $phpZip - } - - # Make sure the content of the PHP archine are in the PHP path - Archive php - { - Path = $phpZip - Destination = $DestinationPath - } - - if ($installMySqlExt ) - { - # Make sure the MySql extention for PHP is in the main PHP path - File phpMySqlExt - { - SourcePath = "$($DestinationPath)\ext\php_mysql.dll" - DestinationPath = "$($DestinationPath)\php_mysql.dll" - Ensure = "Present" - DependsOn = @("[Archive]PHP") - MatchSource = $true - } - } - - - # Make sure the php.ini is in the Php folder - File PhpIni - { - SourcePath = $ConfigurationPath - DestinationPath = "$($DestinationPath)\php.ini" - DependsOn = @("[Archive]PHP") - MatchSource = $true - } - - - # Make sure the php cgi module is registered with IIS - xIisModule phpHandler - { - Name = "phpFastCgi" - Path = "$($DestinationPath)\php-cgi.exe" - RequestPath = "*.php" - Verb = "*" - Ensure = "Present" - DependsOn = @("[Package]vcRedist","[File]PhpIni") - - # Removed because this dependency does not work in - # Windows Server 2012 R2 and below - # This should work in WMF v5 and above - # "[IisPreReqs_php]Iis" - } - - # Make sure the php binary folder is in the path - Environment PathPhp - { - Name = "Path" - Value = ";$($DestinationPath)" - Ensure = "Present" - Path = $true - DependsOn = "[Archive]PHP" - } - } - - xPhp -PackageFolder "C:\packages" ` - -DownloadUri -DownloadUri "http://windows.php.net/downloads/releases/php-5.5.13-Win32-VC11-x64.zip" ` - -Vc2012RedistDownloadUri "http://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x64.exe" ` - -DestinationPath "C:\php" ` - -ConfigurationPath "C:\MyPhp.ini" ` - -installMySqlExt $false - - -###Renaming Requirements -1. Update the following names by replacing MSFT with your company/community name and replace the “x” with your own prefix (e.g. the resource name should change from MSFT\_xWebsite to Contoso\_myWebsite): - - * **Module name** - * **Resource Name** - * **Resource Friendly Name** - * **MOF class name** - * **Filename for the .schema.mof** -2. Update module and metadata information in the module manifest -3. Update any configuration that use these resources - -###Versions -1.0.0.0 - -* Initial Release with the following resources - * xWebSite - -1.1.0.0 - -* Second release adding and updating the following resources - * xIisModule, added - * xWebSite, updated with new property, DefaultPage - diff --git a/Resources/cWebAdministration/Examples/Sample_cWebsite_ConfigurationData.psd1 b/Resources/cWebAdministration/Examples/Sample_cWebsite_ConfigurationData.psd1 deleted file mode 100644 index fa1bb20..0000000 --- a/Resources/cWebAdministration/Examples/Sample_cWebsite_ConfigurationData.psd1 +++ /dev/null @@ -1,27 +0,0 @@ -# Hashtable to define the environmental data -@{ - # Node specific data - AllNodes = @( - - # All the WebServer has following identical information - @{ - NodeName = "*" - WebsiteName = "FourthCoffee" - SourcePath = "C:\BakeryWebsite\" - DestinationPath = "C:\inetpub\FourthCoffee" - DefaultWebSitePath = "C:\inetpub\wwwroot" - }, - - @{ - NodeName = "WebServer1.fourthcoffee.com" - Role = "Web" - }, - - @{ - NodeName = "WebServer2.fourthcoffee.com" - Role = "Web" - } - ); -} - - diff --git a/Resources/cWebAdministration/Examples/Sample_cWebsite_NewWebsite.ps1 b/Resources/cWebAdministration/Examples/Sample_cWebsite_NewWebsite.ps1 deleted file mode 100644 index 6d0c4ed..0000000 --- a/Resources/cWebAdministration/Examples/Sample_cWebsite_NewWebsite.ps1 +++ /dev/null @@ -1,75 +0,0 @@ -configuration Sample_cWebsite_NewWebsite -{ - param - ( - # Target nodes to apply the configuration - [string[]]$NodeName = 'localhost', - - # Name of the website to create - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String]$WebSiteName, - - # Source Path for Website content - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String]$SourcePath, - - # Destination path for Website content - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [String]$DestinationPath - ) - - # Import the module that defines custom resources - Import-DscResource -Module cWebAdministration - - Node $NodeName - { - # Install the IIS role - WindowsFeature IIS - { - Ensure = "Present" - Name = "Web-Server" - } - - # Install the ASP .NET 4.5 role - WindowsFeature AspNet45 - { - Ensure = "Present" - Name = "Web-Asp-Net45" - } - - # Stop the default website - cWebsite DefaultSite - { - Ensure = "Present" - Name = "Default Web Site" - State = "Stopped" - PhysicalPath = "C:\inetpub\wwwroot" - DependsOn = "[WindowsFeature]IIS" - } - - # Copy the website content - File WebContent - { - Ensure = "Present" - SourcePath = $SourcePath - DestinationPath = $DestinationPath - Recurse = $true - Type = "Directory" - DependsOn = "[WindowsFeature]AspNet45" - } - - # Create the new Website - cWebsite NewWebsite - { - Ensure = "Present" - Name = $WebSiteName - State = "Started" - PhysicalPath = $DestinationPath - DependsOn = "[File]WebContent" - } - } -} - diff --git a/Resources/cWebAdministration/Examples/Sample_cWebsite_NewWebsiteFromConfigurationData.ps1 b/Resources/cWebAdministration/Examples/Sample_cWebsite_NewWebsiteFromConfigurationData.ps1 deleted file mode 100644 index 4a8bcd1..0000000 --- a/Resources/cWebAdministration/Examples/Sample_cWebsite_NewWebsiteFromConfigurationData.ps1 +++ /dev/null @@ -1,55 +0,0 @@ -Configuration Sample_cWebsite_FromConfigurationData -{ - # Import the module that defines custom resources - Import-DscResource -Module cWebAdministration - - # Dynamically find the applicable nodes from configuration data - Node $AllNodes.where{$_.Role -eq "Web"}.NodeName - { - # Install the IIS role - WindowsFeature IIS - { - Ensure = "Present" - Name = "Web-Server" - } - - # Install the ASP .NET 4.5 role - WindowsFeature AspNet45 - { - Ensure = "Present" - Name = "Web-Asp-Net45" - } - - # Stop an existing website (set up in Sample_cWebsite_Default) - cWebsite DefaultSite - { - Ensure = "Present" - Name = "Default Web Site" - State = "Stopped" - PhysicalPath = $Node.DefaultWebSitePath - DependsOn = "[WindowsFeature]IIS" - } - - # Copy the website content - File WebContent - { - Ensure = "Present" - SourcePath = $Node.SourcePath - DestinationPath = $Node.DestinationPath - Recurse = $true - Type = "Directory" - DependsOn = "[WindowsFeature]AspNet45" - } - - # Create a new website - cWebsite BakeryWebSite - { - Ensure = "Present" - Name = $Node.WebsiteName - State = "Started" - PhysicalPath = $Node.DestinationPath - DependsOn = "[File]WebContent" - } - } -} - diff --git a/Resources/cWebAdministration/Examples/Sample_cWebsite_RemoveDefault.ps1 b/Resources/cWebAdministration/Examples/Sample_cWebsite_RemoveDefault.ps1 deleted file mode 100644 index 4afea16..0000000 --- a/Resources/cWebAdministration/Examples/Sample_cWebsite_RemoveDefault.ps1 +++ /dev/null @@ -1,32 +0,0 @@ -configuration Sample_cWebsite_StopDefault -{ - param - ( - # Target nodes to apply the configuration - [string[]]$NodeName = 'localhost' - ) - - # Import the module that defines custom resources - Import-DscResource -Module cWebAdministration - - Node $NodeName - { - # Install the IIS role - WindowsFeature IIS - { - Ensure = "Present" - Name = "Web-Server" - } - - # Stop the default website - cWebsite DefaultSite - { - Ensure = "Present" - Name = "Default Web Site" - State = "Stopped" - PhysicalPath = "C:\inetpub\wwwroot" - DependsOn = "[WindowsFeature]IIS" - } - } -} - diff --git a/Resources/cWebAdministration/cWebAdministration.psd1 b/Resources/cWebAdministration/cWebAdministration.psd1 deleted file mode 100644 index ca55a5a..0000000 --- a/Resources/cWebAdministration/cWebAdministration.psd1 +++ /dev/null @@ -1,32 +0,0 @@ -@{ -# Version number of this module. -ModuleVersion = '1.1.1' - -# ID used to uniquely identify this module -GUID = 'b3239f27-d7d3-4ae6-a5d2-d9a1c97d6ae4' - -# Author of this module -Author = 'Microsoft Corporation' - -# Company or vendor of this module -CompanyName = 'Microsoft Corporation' - -# Copyright statement for this module -Copyright = '(c) 2013 Microsoft Corporation. All rights reserved.' - -# Description of the functionality provided by this module -Description = 'Module with DSC Resources for Web Administration' - -# Minimum version of the Windows PowerShell engine required by this module -PowerShellVersion = '4.0' - -# Minimum version of the common language runtime (CLR) required by this module -CLRVersion = '4.0' - -# Functions to export from this module -FunctionsToExport = '*' - -# Cmdlets to export from this module -CmdletsToExport = '*' -} - diff --git a/Resources/rchaganti/DSCResources/HostsFile/HostsFile.psm1 b/Resources/rchaganti/DSCResources/HostsFile/HostsFile.psm1 deleted file mode 100644 index ac10552..0000000 --- a/Resources/rchaganti/DSCResources/HostsFile/HostsFile.psm1 +++ /dev/null @@ -1,161 +0,0 @@ -# Fallback message strings in en-US -DATA localizedData -{ - # same as culture = "en-US" -ConvertFrom-StringData @' - CheckingHostsFileEntry=Checking if the hosts file entry exists. - HostsFileEntryFound=Found a hosts file entry for {0} and {1}. - HostsFileEntryNotFound=Did not find a hosts file entry for {0} and {1}. - HostsFileShouldNotExist=Hosts file entry exists while it should not. - HostsFileEntryShouldExist=Hosts file entry does not exist while it should. - CreatingHostsFileEntry=Creating a hosts file entry with {0} and {1}. - RemovingHostsFileEntry=Removing a hosts file entry with {0} and {1}. - HostsFileEntryAdded=Created the hosts file entry for {0} and {1}. - HostsFileEntryRemoved=Removed the hosts file entry for {0} and {1}. - AnErrorOccurred=An error occurred while creating hosts file entry: {1}. - InnerException=Nested error trying to create hosts file entry: {1}. -'@ -} -if (Test-Path $PSScriptRoot\en-us) -{ - Import-LocalizedData LocalizedData -filename HostsFileProvider.psd1 -} - -function Get-TargetResource -{ - [OutputType([Hashtable])] - param ( - [parameter(Mandatory = $true)] - [string] - $hostName, - [parameter(Mandatory = $true)] - [string] - $ipAddress, - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - - $Configuration = @{ - HostName = $hostName - IPAddress = $IPAddress - } - - Write-Verbose $localizedData.CheckingHostsFileEntry - try { - if ((Get-Content "${env:windir}\system32\drivers\etc\hosts") -match "^[^#]*$ipAddress\s+$hostName") { - Write-Verbose ($localizedData.HostsFileEntryFound -f $hostName, $ipAddress) - $Configuration.Add('Ensure','Present') - } else { - Write-Verbose ($localizedData.HostsFileEntryNotFound -f $hostName, $ipAddress) - $Configuration.Add('Ensure','Absent') - } - return $Configuration - } - - catch { - $exception = $_ - Write-Verbose ($LocalizedData.AnErrorOccurred -f $name, $exception.message) - while ($exception.InnerException -ne $null) - { - $exception = $exception.InnerException - Write-Verbose ($LocalizedData.InnerException -f $name, $exception.message) - } - } -} - -function Set-TargetResource -{ - param ( - [parameter(Mandatory = $true)] - [string] - $hostName, - [parameter(Mandatory = $true)] - [string] - $ipAddress, - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - - $hostEntry = "`r`n${ipAddress}`t${hostName}" - - try { - - if ($Ensure -eq 'Present') - { - Write-Verbose ($localizedData.CreatingHostsFileEntry -f $hostName, $ipAddress) - Add-Content -Path "${env:windir}\system32\drivers\etc\hosts" -Value $hostEntry -Force -Encoding ASCII - Write-Verbose ($localizedData.HostsFileEntryAdded -f $hostName, $ipAddress) - } - else - { - Write-Verbose ($localizedData.RemovingHostsFileEntry -f $hostName, $ipAddress) - ((Get-Content "${env:windir}\system32\drivers\etc\hosts") -notmatch "^\s*$") -notmatch "^[^#]*$ipAddress\s+$hostName" | Set-Content "${env:windir}\system32\drivers\etc\hosts" - Write-Verbose ($localizedData.HostsFileEntryRemoved -f $hostName, $ipAddress) - } - } - catch { - $exception = $_ - Write-Verbose ($LocalizedData.AnErrorOccurred -f $name, $exception.message) - while ($exception.InnerException -ne $null) - { - $exception = $exception.InnerException - Write-Verbose ($LocalizedData.InnerException -f $name, $exception.message) - } - } - -} - -function Test-TargetResource -{ - [OutputType([boolean])] - param ( - [parameter(Mandatory = $true)] - [string] - $hostName, - [parameter(Mandatory = $true)] - [string] - $ipAddress, - [parameter()] - [ValidateSet('Present','Absent')] - [string] - $Ensure = 'Present' - ) - - try { - Write-Verbose $localizedData.CheckingHostsFileEntry - $entryExist = ((Get-Content "${env:windir}\system32\drivers\etc\hosts") -match "^[^#]*$ipAddress\s+$hostName") - - if ($Ensure -eq "Present") { - if ($entryExist) { - Write-Verbose ($localizedData.HostsFileEntryFound -f $hostName, $ipAddress) - return $true - } else { - Write-Verbose ($localizedData.HostsFileEntryShouldExist -f $hostName, $ipAddress) - return $false - } - } else { - if ($entryExist) { - Write-Verbose $localizedData.HostsFileShouldNotExist - return $false - } else { - Write-Verbose $localizedData.HostsFileEntryNotFound - return $true - } - } - } - catch { - $exception = $_ - Write-Verbose ($LocalizedData.AnErrorOccurred -f $name, $exception.message) - while ($exception.InnerException -ne $null) - { - $exception = $exception.InnerException - Write-Verbose ($LocalizedData.InnerException -f $name, $exception.message) - } - } -} - - diff --git a/Resources/rchaganti/DSCResources/HostsFile/HostsFile.schema.mof b/Resources/rchaganti/DSCResources/HostsFile/HostsFile.schema.mof deleted file mode 100644 index f6e3e5a..0000000 --- a/Resources/rchaganti/DSCResources/HostsFile/HostsFile.schema.mof +++ /dev/null @@ -1,8 +0,0 @@ -[ClassVersion("1.1.0"), FriendlyName("HostsFile")] -class HostsFile : OMI_BaseResource -{ - [Key] string hostName; - [Key] string ipAddress; - [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; -}; - diff --git a/Resources/rchaganti/DSCResources/HostsFile/HostsFileExample.ps1 b/Resources/rchaganti/DSCResources/HostsFile/HostsFileExample.ps1 deleted file mode 100644 index 210b78b..0000000 --- a/Resources/rchaganti/DSCResources/HostsFile/HostsFileExample.ps1 +++ /dev/null @@ -1,35 +0,0 @@ -Configuration HostsFileExample { - Node "SRV2-WS2012R2" { - HostsFile HostsFileDemo { - hostName = "testhost100" - ipAddress = "10.10.10.100" - Ensure = "Present" - } - } - - Node "SRV3-WS2012R2" { - HostsFile HostsFileDemo { - hostName = "testhost102" - ipAddress = "10.10.10.102" - Ensure = "Absent" - } - } - - Node "SRV1-WS2012R2" { - HostsFile TestHost120 { - hostName = "testhost120" - ipAddress = "10.10.10.120" - Ensure = "Absent" - } - - HostsFile TestHost130 { - hostName = "testhost130" - ipAddress = "10.10.10.130" - Ensure = "Present" - } - - } -} - -HostsFileExample - diff --git a/Resources/rchaganti/DSCResources/HostsFile/en-US/HostsFileProvider.psd1 b/Resources/rchaganti/DSCResources/HostsFile/en-US/HostsFileProvider.psd1 deleted file mode 100644 index 5e7d65f..0000000 --- a/Resources/rchaganti/DSCResources/HostsFile/en-US/HostsFileProvider.psd1 +++ /dev/null @@ -1,15 +0,0 @@ -ConvertFrom-StringData @' - CheckingHostsFileEntry=Checking if the hosts file entry exists. - HostsFileEntryFound=Found a hosts file entry for {0} and {1}. - HostsFileEntryNotFound=Did not find a hosts file entry for {0} and {1}. - HostsFileShouldNotExist=Hosts file entry exists while it should not. - HostsFileEntryShouldExist=Hosts file entry does not exist while it should. - CreatingHostsFileEntry=Creating a hosts file entry with {0} and {1}. - RemovingHostsFileEntry=Removing a hosts file entry with {0} and {1}. - HostsFileEntryAdded=Created the hosts file entry for {0} and {1}. - HostsFileEntryRemoved=Removed the hosts file entry for {0} and {1}. - AnErrorOccurred=An error occurred while creating hosts file entry: {1}. - InnerException=Nested error trying to create hosts file entry: {1}. -'@ - - diff --git a/Resources/rchaganti/DSCResources/HostsFile/en-US/about_HostsFile_Resource.txt b/Resources/rchaganti/DSCResources/HostsFile/en-US/about_HostsFile_Resource.txt deleted file mode 100644 index ad76353..0000000 --- a/Resources/rchaganti/DSCResources/HostsFile/en-US/about_HostsFile_Resource.txt +++ /dev/null @@ -1,20 +0,0 @@ -Syntax - -HostsFile [string] #ResourceName -{ - HostName = [string] - - IPAddress = [string] - - [ Ensure = [string] { Absent | Present } ] -} - -Properties - -HostName - Name of the server or computer - -IPAddress - IPv4 or IPv6 address of the server or computer - -Ensure - Set this property to "Present" add the hosts file entry. Using "Absent" will remove the hosts entry, if it exists. - - diff --git a/Resources/rchaganti/rchaganti.psd1 b/Resources/rchaganti/rchaganti.psd1 deleted file mode 100644 index 7816276..0000000 --- a/Resources/rchaganti/rchaganti.psd1 +++ /dev/null @@ -1,98 +0,0 @@ -# -# Module manifest for module 'rchaganti' -# -# Generated by: Ravikanth -# -# Generated on: 1/23/2014 -# - -@{ - -# Script module or binary module file associated with this manifest. -# RootModule = '' - -# Version number of this module. -ModuleVersion = '1.1.3' - -# ID used to uniquely identify this module -GUID = '9162bb16-237d-401c-a551-3330bdc36616' - -# Author of this module -Author = 'Ravikanth' - -# Company or vendor of this module -CompanyName = 'PowerShell Magazine' - -# Copyright statement for this module -Copyright = '(c) 2013 PowerShellMagazine.com. All rights reserved.' - -# Description of the functionality provided by this module -Description = 'Manage Hosts file on local and remote nodes. This module allows getting and modifying (add/delete) host file entries.' - -# Minimum version of the Windows PowerShell engine required by this module -# PowerShellVersion = '' - -# Name of the Windows PowerShell host required by this module -# PowerShellHostName = '' - -# Minimum version of the Windows PowerShell host required by this module -# PowerShellHostVersion = '' - -# Minimum version of Microsoft .NET Framework required by this module -# DotNetFrameworkVersion = '' - -# Minimum version of the common language runtime (CLR) required by this module -# CLRVersion = '' - -# Processor architecture (None, X86, Amd64) required by this module -# ProcessorArchitecture = '' - -# Modules that must be imported into the global environment prior to importing this module -# RequiredModules = @() - -# Assemblies that must be loaded prior to importing this module -# RequiredAssemblies = @() - -# Script files (.ps1) that are run in the caller's environment prior to importing this module. -# ScriptsToProcess = @() - -# Type files (.ps1xml) to be loaded when importing this module -# TypesToProcess = @() - -# Format files (.ps1xml) to be loaded when importing this module -# FormatsToProcess = @() - -# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess -# NestedModules = @() - -# Functions to export from this module -FunctionsToExport = '*' - -# Cmdlets to export from this module -CmdletsToExport = '*' - -# Variables to export from this module -VariablesToExport = '*' - -# Aliases to export from this module -AliasesToExport = '*' - -# List of all modules packaged with this module -# ModuleList = @() - -# List of all files packaged with this module -# FileList = @() - -# Private data to pass to the module specified in RootModule/ModuleToProcess -# PrivateData = '' - -# HelpInfo URI of this module -# HelpInfoURI = '' - -# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. -# DefaultCommandPrefix = '' - -} - - -