2014-06-17 17:30:34 +00:00
# This particular file snippet, and this file snippet only, is BSD licensed.
# Modules you write using this snippet, which is embedded dynamically by Ansible
# still belong to the author of the module, and may assign their own license
# to the complete work.
#
# Copyright (c), Michael DeHaan <michael.dehaan@gmail.com>, 2014, and others
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
2015-10-07 05:24:37 +00:00
Set-StrictMode -Version 2.0
2017-02-17 08:09:56 +00:00
$ErrorActionPreference = " Stop "
2015-07-24 16:39:54 +00:00
2014-06-17 23:20:33 +00:00
# Helper function to set an "attribute" on a psobject instance in powershell.
# This is a convenience to make adding Members to the object easier and
# slightly more pythonic
2014-06-19 16:32:48 +00:00
# Example: Set-Attr $result "changed" $true
2014-06-17 23:20:33 +00:00
Function Set-Attr($obj , $name , $value )
{
2014-06-19 17:16:43 +00:00
# If the provided $obj is undefined, define one to be nice
If ( -not $obj . GetType )
{
2017-02-24 07:08:19 +00:00
$obj = @ { }
2014-06-19 17:16:43 +00:00
}
2015-08-22 22:19:43 +00:00
Try
{
$obj . $name = $value
}
Catch
{
$obj | Add-Member -Force -MemberType NoteProperty -Name $name -Value $value
}
2014-06-17 23:20:33 +00:00
}
2014-06-17 17:30:34 +00:00
2014-06-18 16:48:50 +00:00
# Helper function to convert a powershell object to JSON to echo it, exiting
# the script
2014-06-19 16:32:48 +00:00
# Example: Exit-Json $result
2014-06-18 16:48:50 +00:00
Function Exit-Json($obj )
{
2014-06-19 17:16:43 +00:00
# If the provided $obj is undefined, define one to be nice
If ( -not $obj . GetType )
{
2017-02-24 07:08:19 +00:00
$obj = @ { }
2014-06-19 17:16:43 +00:00
}
2015-05-29 13:50:08 +00:00
echo $obj | ConvertTo-Json -Compress -Depth 99
2014-06-18 16:48:50 +00:00
Exit
}
# Helper function to add the "msg" property and "failed" property, convert the
2017-02-24 07:08:19 +00:00
# powershell Hashtable to JSON and echo it, exiting the script
2014-06-19 16:32:48 +00:00
# Example: Fail-Json $result "This is the failure message"
2014-06-19 17:16:43 +00:00
Function Fail-Json($obj , $message = $null )
2014-06-18 16:48:50 +00:00
{
2017-02-24 07:08:19 +00:00
if ( $obj -is [ hashtable ] -or $obj -is [ psobject ] ) {
# Nothing to do
} elseif ( $obj -is [ string ] -and $message -eq $null ) {
# If we weren't given 2 args, and the only arg was a string,
# create a new Hashtable and use the arg as the failure message
2014-06-19 17:16:43 +00:00
$message = $obj
2017-02-24 07:08:19 +00:00
$obj = @ { }
} else {
# If the first argument is undefined or a different type,
# make it a Hashtable
$obj = @ { }
2014-06-19 17:16:43 +00:00
}
2017-02-24 07:08:19 +00:00
# Still using Set-Attr for PSObject compatibility
2014-06-18 16:48:50 +00:00
Set-Attr $obj " msg " $message
Set-Attr $obj " failed " $true
2017-02-24 07:08:19 +00:00
2015-05-29 13:50:08 +00:00
echo $obj | ConvertTo-Json -Compress -Depth 99
2014-06-18 21:10:10 +00:00
Exit 1
2014-06-18 16:48:50 +00:00
}
2014-06-19 15:36:53 +00:00
2017-02-09 18:41:57 +00:00
# Helper function to add warnings, even if the warnings attribute was
# not already set up. This is a convenience for the module developer
# so he does not have to check for the attribute prior to adding.
Function Add-Warning($obj , $message )
{
if ( Get-Member -InputObject $obj -Name " warnings " ) {
2017-02-24 07:08:19 +00:00
if ( $obj . warnings -is [ array ] ) {
2017-02-09 18:41:57 +00:00
$obj . warnings + = $message
} else {
throw " warnings attribute is not an array "
}
} else {
$obj . warnings = , @ ( $message )
}
}
# Helper function to add deprecations, even if the deprecations attribute was
# not already set up. This is a convenience for the module developer
# so he does not have to check for the attribute prior to adding.
Function Add-DeprecationWarning($obj , $message , $version = $null )
{
if ( Get-Member -InputObject $obj -Name " deprecations " ) {
2017-02-24 07:08:19 +00:00
if ( $obj . deprecations -is [ array ] ) {
2017-02-09 18:41:57 +00:00
$obj . deprecations + = @ {
msg = $message
version = $version
}
} else {
throw " deprecations attribute is not a list "
}
} else {
$obj . deprecations = , @ (
@ {
msg = $message
version = $version
}
)
}
}
2017-02-24 06:41:03 +00:00
# Helper function to expand environment variables in values. By default
# it turns any type to a string, but we ensure $null remains $null.
2017-01-16 18:51:56 +00:00
Function Expand-Environment($value )
{
2017-02-24 06:41:03 +00:00
if ( $value -ne $null ) {
[ System.Environment ] :: ExpandEnvironmentVariables ( $value )
} else {
$value
}
2017-01-16 18:51:56 +00:00
}
2014-08-29 08:39:42 +00:00
# Helper function to get an "attribute" from a psobject instance in powershell.
# This is a convenience to make getting Members from an object easier and
# slightly more pythonic
2015-09-30 19:02:12 +00:00
# Example: $attr = Get-AnsibleParam $response "code" -default "1"
#Get-AnsibleParam also supports Parameter validation to save you from coding that manually:
#Example: Get-AnsibleParam -obj $params -name "State" -default "Present" -ValidateSet "Present","Absent" -resultobj $resultobj -failifempty $true
2014-08-29 08:39:42 +00:00
#Note that if you use the failifempty option, you do need to specify resultobject as well.
2017-01-24 13:58:40 +00:00
Function Get-AnsibleParam($obj , $name , $default = $null , $resultobj = @ { } , $failifempty = $false , $emptyattributefailmessage , $ValidateSet , $ValidateSetErrorMessage , $type = $null , $aliases = @ ( ) )
2014-08-29 08:39:42 +00:00
{
2017-01-24 13:58:40 +00:00
# Check if the provided Member $name or aliases exist in $obj and return it or the default.
try {
$found = $null
# First try to find preferred parameter $name
$aliases = @ ( $name ) + $aliases
# Iterate over aliases to find acceptable Member $name
foreach ( $alias in $aliases ) {
2017-02-17 08:09:56 +00:00
if ( $obj . ContainsKey ( $alias ) ) {
2017-01-24 13:58:40 +00:00
$found = $alias
break
}
}
if ( $found -eq $null ) {
2015-08-22 22:19:43 +00:00
throw
}
2017-01-24 13:58:40 +00:00
$name = $found
2015-09-30 19:02:12 +00:00
2017-01-24 13:58:40 +00:00
if ( $ValidateSet ) {
if ( $ValidateSet -contains ( $obj . $name ) ) {
2017-01-16 18:51:56 +00:00
$value = $obj . $name
2017-01-24 13:58:40 +00:00
} else {
if ( $ValidateSetErrorMessage -eq $null ) {
2015-09-30 19:02:12 +00:00
#Auto-generated error should be sufficient in most use cases
$ValidateSetErrorMessage = " Argument $name needs to be one of $( $ValidateSet -join " , " ) but was $( $obj . $name ) . "
}
Fail-Json -obj $resultobj -message $ValidateSetErrorMessage
}
2017-01-24 13:58:40 +00:00
} else {
2017-01-16 18:51:56 +00:00
$value = $obj . $name
2015-09-30 19:02:12 +00:00
}
2017-01-24 13:58:40 +00:00
} catch {
if ( $failifempty -eq $false ) {
2017-01-16 18:51:56 +00:00
$value = $default
2017-01-24 13:58:40 +00:00
} else {
if ( ! $emptyattributefailmessage ) {
2015-08-22 22:19:43 +00:00
$emptyattributefailmessage = " Missing required argument: $name "
}
Fail-Json -obj $resultobj -message $emptyattributefailmessage
}
2017-01-24 13:58:40 +00:00
2014-08-29 08:39:42 +00:00
}
2017-01-16 18:51:56 +00:00
2017-02-24 06:41:03 +00:00
# If $value -eq $null, the parameter was unspecified
2017-01-24 13:58:40 +00:00
if ( $value -ne $null -and $type -eq " path " ) {
2017-02-24 06:41:03 +00:00
# Expand environment variables on path-type
2017-01-16 18:51:56 +00:00
$value = Expand-Environment ( $value )
2017-02-24 06:41:03 +00:00
} elseif ( $value -ne $null -and $type -eq " str " ) {
# Convert str types to real Powershell strings
$value = $value . ToString ( )
} elseif ( $value -ne $null -and $type -eq " bool " ) {
2017-01-24 13:48:58 +00:00
# Convert boolean types to real Powershell booleans
$value = $value | ConvertTo-Bool
2017-02-24 06:41:03 +00:00
} elseif ( $value -ne $null -and $type -eq " int " ) {
# Convert int types to real Powershell integers
$value = $value -as [ int ]
} elseif ( $value -ne $null -and $type -eq " float " ) {
# Convert float types to real Powershell floats
$value = $value -as [ float ]
2017-01-16 18:51:56 +00:00
}
2017-01-27 22:46:21 +00:00
return $value
2014-08-29 08:39:42 +00:00
}
2016-09-30 16:46:06 +00:00
#Alias Get-attr-->Get-AnsibleParam for backwards compat. Only add when needed to ease debugging of scripts
If ( ! ( Get-Alias -Name " Get-attr " -ErrorAction SilentlyContinue ) )
{
New-Alias -Name Get-attr -Value Get-AnsibleParam
}
2014-06-19 15:36:53 +00:00
# Helper filter/pipeline function to convert a value to boolean following current
# Ansible practices
2014-06-19 16:32:48 +00:00
# Example: $is_true = "true" | ConvertTo-Bool
2014-06-19 15:36:53 +00:00
Function ConvertTo-Bool
{
param (
[ parameter ( valuefrompipeline = $true ) ]
$obj
)
$boolean_strings = " yes " , " on " , " 1 " , " true " , 1
$obj_string = [ string ] $obj
2017-02-24 07:08:19 +00:00
if ( ( $obj -is [ boolean ] -and $obj ) -or $boolean_strings -contains $obj_string . ToLower ( ) ) {
2017-01-27 22:46:21 +00:00
return $true
2017-02-24 07:08:19 +00:00
} else {
2017-01-27 22:46:21 +00:00
return $false
2014-06-19 15:36:53 +00:00
}
}
2014-08-29 08:39:42 +00:00
2015-07-30 19:54:32 +00:00
# Helper function to parse Ansible JSON arguments from a "file" passed as
# the single argument to the module.
# Example: $params = Parse-Args $args
Function Parse-Args($arguments , $supports_check_mode = $false )
{
2017-01-27 22:46:21 +00:00
$params = New-Object psobject
2015-07-30 19:54:32 +00:00
If ( $arguments . Length -gt 0 )
{
2017-01-27 22:46:21 +00:00
$params = Get-Content $arguments [ 0 ] | ConvertFrom-Json
2015-07-30 19:54:32 +00:00
}
2017-02-17 08:09:56 +00:00
Else {
$params = $complex_args
}
2017-01-27 22:46:21 +00:00
$check_mode = Get-AnsibleParam -obj $params -name " _ansible_check_mode " -type " bool " -default $false
2015-07-30 19:54:32 +00:00
If ( $check_mode -and -not $supports_check_mode )
{
2017-01-27 22:46:21 +00:00
Exit-Json @ {
skipped = $true
changed = $false
msg = " remote module does not support check mode "
}
2015-07-30 19:54:32 +00:00
}
2017-01-27 22:46:21 +00:00
return $params
2015-07-30 19:54:32 +00:00
}
2017-01-24 13:58:40 +00:00
# Helper function to calculate a hash of a file in a way which powershell 3
2014-11-24 18:03:32 +00:00
# and above can handle:
2017-01-27 22:51:12 +00:00
Function Get-FileChecksum($path , $algorithm = 'sha1' )
2014-11-24 18:03:32 +00:00
{
2017-02-24 06:41:03 +00:00
If ( Test-Path -Path $path -PathType Leaf )
2014-11-24 18:03:32 +00:00
{
2017-01-27 22:51:12 +00:00
switch ( $algorithm )
{
'md5' { $sp = New-Object -TypeName System . Security . Cryptography . MD5CryptoServiceProvider }
'sha1' { $sp = New-Object -TypeName System . Security . Cryptography . SHA1CryptoServiceProvider }
'sha256' { $sp = New-Object -TypeName System . Security . Cryptography . SHA256CryptoServiceProvider }
'sha384' { $sp = New-Object -TypeName System . Security . Cryptography . SHA384CryptoServiceProvider }
'sha512' { $sp = New-Object -TypeName System . Security . Cryptography . SHA512CryptoServiceProvider }
2017-02-24 06:41:03 +00:00
default { Fail-Json @ { } " Unsupported hash algorithm supplied ' $algorithm ' " }
2017-01-27 22:51:12 +00:00
}
If ( $PSVersionTable . PSVersion . Major -ge 4 ) {
$raw_hash = Get-FileHash $path -Algorithm $algorithm
$hash = $raw_hash . Hash . ToLower ( )
} Else {
$fp = [ System.IO.File ] :: Open ( $path , [ System.IO.Filemode ] :: Open , [ System.IO.FileAccess ] :: Read , [ System.IO.FileShare ] :: ReadWrite ) ;
$hash = [ System.BitConverter ] :: ToString ( $sp . ComputeHash ( $fp ) ) . Replace ( " - " , " " ) . ToLower ( ) ;
$fp . Dispose ( ) ;
}
2014-11-24 18:03:32 +00:00
}
2017-02-24 06:41:03 +00:00
ElseIf ( Test-Path -Path $path -PathType Container )
2014-11-24 18:03:32 +00:00
{
2017-01-27 22:46:21 +00:00
$hash = " 3 " ;
2014-11-24 18:03:32 +00:00
}
Else
{
$hash = " 1 " ;
}
return $hash
}
2016-06-06 21:18:51 +00:00
Function Get-PendingRebootStatus
{
# Check if reboot is required, if so notify CA. The MSFT_ServerManagerTasks provider is missing on client SKUs
#Function returns true if computer has a pending reboot
$featureData = invoke-wmimethod -EA Ignore -Name GetServerFeature -namespace root \ microsoft \ windows \ servermanager -Class MSFT_ServerManagerTasks
$regData = Get-ItemProperty " HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager " " PendingFileRenameOperations " -EA Ignore
2016-11-06 16:01:49 +00:00
$CBSRebootStatus = Get-ChildItem " HKLM:\\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing " -ErrorAction SilentlyContinue | where { $_ . PSChildName -eq " RebootPending " }
if ( ( $featureData -and $featureData . RequiresReboot ) -or $regData -or $CBSRebootStatus )
2016-06-06 21:18:51 +00:00
{
return $True
}
2017-01-24 13:58:40 +00:00
else
2016-06-06 21:18:51 +00:00
{
return $False
}
2017-02-17 08:09:56 +00:00
}
# this line must stay at the bottom to ensure all defined module parts are exported
2017-02-24 07:08:19 +00:00
Export-ModuleMember -Alias * -Function * -Cmdlet *