Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
23c1314
xScheduledTask heavily updated with the nearly full feature set of th…
nyanhp Mar 16, 2017
cdde689
-At takes DateTime, not timespan
nyanhp Mar 16, 2017
505716a
Adapted tests to new properties
nyanhp Mar 16, 2017
3e6d7b9
Added test methods from DSC HQRM xSharePoint to ease testing of 50+ p…
nyanhp Mar 17, 2017
096ed53
Updated tests to comply with new resource architecture
nyanhp Mar 17, 2017
dfebe0e
Setting repetition is now possible for all valid trigger types.
nyanhp Mar 20, 2017
58122bb
Added quick check when a scheduled task is Absent and should be absen…
nyanhp Mar 20, 2017
c1a636e
Wrong comparison for repetitioninterval
nyanhp Mar 20, 2017
1663d77
Parameter test method updated with uint32, uint16 and boolean
nyanhp Mar 21, 2017
bf518e0
parameter test method updated with boolean
nyanhp Mar 21, 2017
f6e196d
Get-TargetResource now return RestartInterval and the correct values …
nyanhp Mar 21, 2017
2ef8364
Parameters Disable and RandomDelay are now properly handled
nyanhp Mar 21, 2017
6fa176b
Set-TargetResource now removes the existing scheduled task that would…
nyanhp Mar 21, 2017
05ae37f
Integration tests updated to cover all new properties
nyanhp Mar 21, 2017
34b8da6
Integration tests updated to use all new test configurations
nyanhp Mar 21, 2017
41d6501
Unit tests updated to cover new properties
nyanhp Mar 21, 2017
65c3cc8
Finishing touches
nyanhp Mar 21, 2017
280e5c7
Methods Test-DscParameterState adapted from @raandree 's version (as …
nyanhp Mar 21, 2017
3f4094a
Added a couple of Write-Verbose statements
nyanhp Mar 21, 2017
1941c0a
Moved Test-DscParameterState to module CommonresourceHelper
nyanhp Mar 21, 2017
601df90
Samples added
nyanhp Mar 21, 2017
c05508a
Formatting
nyanhp Mar 21, 2017
0bcb06a
Updated README. Ultimately fixes #34 and #41
nyanhp Mar 21, 2017
2693b51
Spaces added to readme
nyanhp Mar 21, 2017
473641a
Readme unreleased section updated
nyanhp Mar 21, 2017
edecdf4
Sample in readme updated
nyanhp Mar 21, 2017
7763efb
Added newline to test configuration data
nyanhp Mar 21, 2017
108a010
Integration tests: variable scope fixed to satisfy AppVeyor tests
nyanhp Mar 21, 2017
be5f31b
Made unit and integration tests verbose
nyanhp Mar 21, 2017
ab9e005
Probabyl fixed issue where AppVeyor tests would fail due to the prope…
nyanhp Mar 21, 2017
f032ed7
Trying to set repetition any way I can
nyanhp Mar 21, 2017
2b45412
Exception inserted for PowerShell v4 (Task is created first, repetiti…
nyanhp Mar 21, 2017
5cb89e0
Additional info for write-verbose
nyanhp Mar 21, 2017
57725e2
Exception handling added which emulates PS v4 behavior
nyanhp Mar 21, 2017
d17e8f1
Fixed failing unit test for resource xComputer...
nyanhp Mar 21, 2017
cbe281e
Merge https://github.com/PowerShell/xComputerManagement into feature/…
May 6, 2017
1eca3fb
Remedied first code review issues
nyanhp May 6, 2017
2365c7c
Added new functions to throw exceptions
nyanhp May 7, 2017
dffb78b
Used new functions to throw exceptions
nyanhp May 7, 2017
872ffab
Comment added, quotes fixed
nyanhp May 7, 2017
4a2cee6
Styling issues fixed
nyanhp May 22, 2017
0763bd0
Added cleanup task for integration test
nyanhp May 23, 2017
afaf764
fixed double quotes in unit tests
nyanhp May 24, 2017
ea4499e
Building contexts with foreach loop
nyanhp May 24, 2017
ab10800
Tasks properly named
nyanhp May 24, 2017
5f2e46b
Resolved merge conflict
nyanhp Jun 18, 2017
84fd712
Additional info in README
nyanhp Jul 10, 2017
0cf6bc1
Merge pull request #69 from nyanhp/feature/ScheduledTaskOptions
PlagueHO Jul 11, 2017
09d3709
Releasing version 2.0.0.0
kwirkykat Jul 12, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
380 changes: 379 additions & 1 deletion DSCResources/CommonResourceHelper.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,384 @@ function Get-LocalizedData
return $localizedData
}

<#
.SYNOPSIS
Removes common parameters from a hashtable
.DESCRIPTION
This function serves the purpose of removing common parameters and option common parameters from a parameter hashtable
.PARAMETER Hashtable
The parameter hashtable that should be pruned
#>
function Remove-CommonParameter
{
[OutputType([hashtable])]
[cmdletbinding()]
param
(
[Parameter(Mandatory = $true)]
[hashtable]
$Hashtable
)

$inputClone = $Hashtable.Clone()
$commonParameters = [System.Management.Automation.PSCmdlet]::CommonParameters
$commonParameters += [System.Management.Automation.PSCmdlet]::OptionalCommonParameters

$Hashtable.Keys | Where-Object { $_ -in $commonParameters } | ForEach-Object {
$inputClone.Remove($_)
}

return $inputClone
}

<#
.SYNOPSIS
Tests the status of DSC resource parameters
.DESCRIPTION
This function tests the parameter status of DSC resource parameters against the current values present on the system
.PARAMETER CurrentValues
A hashtable with the current values on the system, obtained by e.g. Get-TargetResource
.PARAMETER DesiredValues
The hashtable of desired values
.PARAMETER ValuesToCheck
The values to check if not all values should be checked
.PARAMETER TurnOffTypeChecking
Indicates that the type of the parameter should not be checked
#>
function Test-DscParameterState
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[hashtable]
$CurrentValues,

[Parameter(Mandatory = $true)]
[object]
$DesiredValues,

[string[]]
$ValuesToCheck,

[switch]
$TurnOffTypeChecking
)

$returnValue = $true

$types = 'System.Management.Automation.PSBoundParametersDictionary', 'System.Collections.Hashtable', 'Microsoft.Management.Infrastructure.CimInstance'

if ($DesiredValues.GetType().FullName -notin $types)
{
throw ("Property 'DesiredValues' in Test-DscParameterState must be either a Hashtable or CimInstance. Type detected was $($DesiredValues.GetType().FullName)")
}

if ($DesiredValues -is [Microsoft.Management.Infrastructure.CimInstance] -and -not $ValuesToCheck)
{
throw ("If 'DesiredValues' is a CimInstance then property 'ValuesToCheck' must contain a value")
}

$desiredValuesClean = Remove-CommonParameter -Hashtable $DesiredValues

if (-not $ValuesToCheck)
{
$keyList = $desiredValuesClean.Keys
}
else
{
$keyList = $ValuesToCheck
}

foreach ($key in $keyList)
{
if ($null -ne $desiredValuesClean.$key)
{
$desiredType = $desiredValuesClean.$key.GetType()
}
else
{
$desiredType = [psobject]@{
Name = 'Unknown'
}
}

if ($null -ne $CurrentValues.$key)
{
$currentType = $CurrentValues.$key.GetType()
}
else
{
$currentType = [psobject]@{
Name = 'Unknown'
}
}

if ($currentType.Name -ne 'Unknown' -and $desiredType.Name -eq 'PSCredential')
{
# This is a credential object. Compare only the user name
if ($currentType.Name -eq 'PSCredential' -and $CurrentValues.$key.UserName -eq $desiredValuesClean.$key.UserName)
{
Write-Verbose -Message ('MATCH: PSCredential username match. Current state is {0} and desired state is {1}' -f $CurrentValues.$key.UserName, $desiredValuesClean.$key.UserName)
continue
}
else
{
Write-Verbose -Message ('NOTMATCH: PSCredential username mismatch. Current state is {0} and desired state is {1}' -f $CurrentValues.$key.UserName, $desiredValuesClean.$key.UserName)
$returnValue = $false
}

# Assume the string is our username when the matching desired value is actually a credential
if ($currentType.Name -eq 'string' -and $CurrentValues.$key -eq $desiredValuesClean.$key.UserName)
{
Write-Verbose -Message ('MATCH: PSCredential username match. Current state is {0} and desired state is {1}' -f $CurrentValues.$key, $desiredValuesClean.$key.UserName)
continue
}
else
{
Write-Verbose -Message ('NOTMATCH: PSCredential username mismatch. Current state is {0} and desired state is {1}' -f $CurrentValues.$key, $desiredValuesClean.$key.UserName)
$returnValue = $false
}
}

if (-not $TurnOffTypeChecking)
{
if (($desiredType.Name -ne 'Unknown' -and $currentType.Name -ne 'Unknown') -and
$desiredType.FullName -ne $currentType.FullName)
{
Write-Verbose -Message "NOTMATCH: Type mismatch for property '$key' Current state type is '$($currentType.Name)' and desired type is '$($desiredType.Name)'"
continue
}
}

if ($CurrentValues.$key -eq $desiredValuesClean.$key -and -not $desiredType.IsArray)
{
Write-Verbose -Message "MATCH: Value (type $($desiredType.Name)) for property '$key' does match. Current state is '$($CurrentValues.$key)' and desired state is '$($desiredValuesClean.$key)'"
continue
}

if ($desiredValuesClean.GetType().Name -in 'HashTable', 'PSBoundParametersDictionary')
{
$checkDesiredValue = $desiredValuesClean.ContainsKey($key)
}
else
{
$checkDesiredValue = Test-DSCObjectHasProperty -Object $desiredValuesClean -PropertyName $key
}

if (-not $checkDesiredValue)
{
Write-Verbose -Message "MATCH: Value (type $($desiredType.Name)) for property '$key' does match. Current state is '$($CurrentValues.$key)' and desired state is '$($desiredValuesClean.$key)'"
continue
}

if ($desiredType.IsArray)
{
Write-Verbose -Message "Comparing values in property '$key'"
if (-not $CurrentValues.ContainsKey($key) -or -not $CurrentValues.$key)
{
Write-Verbose -Message "NOTMATCH: Value (type $($desiredType.Name)) for property '$key' does not match. Current state is '$($CurrentValues.$key)' and desired state is '$($desiredValuesClean.$key)'"
$returnValue = $false
continue
}
elseif ($CurrentValues.$key.Count -ne $DesiredValues.$key.Count)
{
Write-Verbose -Message "NOTMATCH: Value (type $($desiredType.Name)) for property '$key' does have a different count. Current state count is '$($CurrentValues.$key.Count)' and desired state count is '$($desiredValuesClean.$key.Count)'"
$returnValue = $false
continue
}
else
{
$desiredArrayValues = $DesiredValues.$key
$currentArrayValues = $CurrentValues.$key

for ($i = 0; $i -lt $desiredArrayValues.Count; $i++)
{
if ($null -ne $desiredArrayValues[$i])
{
$desiredType = $desiredArrayValues[$i].GetType()
}
else
{
$desiredType = [psobject]@{
Name = 'Unknown'
}
}

if ($null -ne $currentArrayValues[$i])
{
$currentType = $currentArrayValues[$i].GetType()
}
else
{
$currentType = [psobject]@{
Name = 'Unknown'
}
}

if (-not $TurnOffTypeChecking)
{
if (($desiredType.Name -ne 'Unknown' -and $currentType.Name -ne 'Unknown') -and
$desiredType.FullName -ne $currentType.FullName)
{
Write-Verbose -Message "`tNOTMATCH: Type mismatch for property '$key' Current state type of element [$i] is '$($currentType.Name)' and desired type is '$($desiredType.Name)'"
$returnValue = $false
continue
}
}

if ($desiredArrayValues[$i] -ne $currentArrayValues[$i])
{
Write-Verbose -Message "`tNOTMATCH: Value [$i] (type $($desiredType.Name)) for property '$key' does match. Current state is '$($currentArrayValues[$i])' and desired state is '$($desiredArrayValues[$i])'"
$returnValue = $false
continue
}
else
{
Write-Verbose -Message "`tMATCH: Value [$i] (type $($desiredType.Name)) for property '$key' does match. Current state is '$($currentArrayValues[$i])' and desired state is '$($desiredArrayValues[$i])'"
continue
}
}

}
}
else
{
if ($desiredValuesClean.$key -ne $CurrentValues.$key)
{
Write-Verbose -Message "NOTMATCH: Value (type $($desiredType.Name)) for property '$key' does not match. Current state is '$($CurrentValues.$key)' and desired state is '$($desiredValuesClean.$key)'"
$returnValue = $false
}

}
}

Write-Verbose -Message "Result is '$returnValue'"
return $returnValue
}

<#
.SYNOPSIS
Tests of an object has a property
.PARAMETER Object
The object to test
.PARAMETER PropertyName
The property name
#>
function Test-DSCObjectHasProperty
{
[CmdletBinding()]
[OutputType([bool])]
param
(
[Parameter(Mandatory = $true)]
[object]
$Object,

[Parameter(Mandatory = $true)]
[string]
$PropertyName
)

if ($Object.PSObject.Properties.Name -contains $PropertyName)
{
return [bool] $Object.$PropertyName
}

return $false
}

<#
.SYNOPSIS
Creates and throws an invalid argument exception

.PARAMETER Message
The message explaining why this error is being thrown

.PARAMETER ArgumentName
The name of the invalid argument that is causing this error to be thrown
#>
function New-InvalidArgumentException
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$Message,

[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]
$ArgumentName
)

$argumentException = New-Object -TypeName 'ArgumentException' `
-ArgumentList @($Message, $ArgumentName)
$newObjectParams = @{
TypeName = 'System.Management.Automation.ErrorRecord'
ArgumentList = @($argumentException, $ArgumentName, 'InvalidArgument', $null)
}
$errorRecord = New-Object @newObjectParams

throw $errorRecord
}

<#
.SYNOPSIS
Creates and throws an invalid operation exception

.PARAMETER Message
The message explaining why this error is being thrown

.PARAMETER ErrorRecord
The error record containing the exception that is causing this terminating error
#>
function New-InvalidOperationException
{
[CmdletBinding()]
param
(
[ValidateNotNullOrEmpty()]
[String]
$Message,

[ValidateNotNull()]
[System.Management.Automation.ErrorRecord]
$ErrorRecord
)

if ($null -eq $Message)
{
$invalidOperationException = New-Object -TypeName 'InvalidOperationException'
}
elseif ($null -eq $ErrorRecord)
{
$invalidOperationException = New-Object -TypeName 'InvalidOperationException' `
-ArgumentList @($Message)
}
else
{
$invalidOperationException = New-Object -TypeName 'InvalidOperationException' `
-ArgumentList @($Message, $ErrorRecord.Exception)
}

$newObjectParams = @{
TypeName = 'System.Management.Automation.ErrorRecord'
ArgumentList = @( $invalidOperationException.ToString(), 'MachineStateIncorrect',
'InvalidOperation', $null )
}

$errorRecordToThrow = New-Object @newObjectParams
throw $errorRecordToThrow
}

Export-ModuleMember -Function @(
'Get-LocalizedData'
)
'Remove-CommonParameter'
'Test-DscParameterState'
'Test-DSCObjectHasProperty'
'New-InvalidOperationException'
'New-InvalidArgumentException'
)
Loading