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
2015-08-22 22:19:43 +00:00
2015-07-24 16:39:54 +00:00
# Ansible v2 will insert the module arguments below as a string containing
# JSON; assign them to an environment variable and redefine $args so existing
# modules will continue to work.
$complex_args = @ '
2016-04-05 18:06:17 +00:00
< < INCLUDE_ANSIBLE_MODULE_JSON_ARGS > >
2015-07-24 16:39:54 +00:00
' @
Set-Content env : MODULE_COMPLEX_ARGS -Value $complex_args
$args = @ ( 'env:MODULE_COMPLEX_ARGS' )
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 )
{
$obj = New-Object psobject
}
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 )
{
$obj = New-Object psobject
}
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
# powershell object 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
{
2014-06-19 17:16:43 +00:00
# If we weren't given 2 args, and the only arg was a string, create a new
# psobject and use the arg as the failure message
If ( $message -eq $null -and $obj . GetType ( ) . Name -eq " String " )
{
$message = $obj
$obj = New-Object psobject
}
# If the first args is undefined or not an object, make it an object
2015-08-22 22:19:43 +00:00
ElseIf ( -not $obj -or -not $obj . GetType -or $obj . GetType ( ) . Name -ne " PSCustomObject " )
2014-06-19 17:16:43 +00:00
{
$obj = New-Object psobject
}
2014-06-18 16:48:50 +00:00
Set-Attr $obj " msg " $message
Set-Attr $obj " failed " $true
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-01-16 18:51:56 +00:00
Function Expand-Environment($value )
{
[ System.Environment ] :: ExpandEnvironmentVariables ( $value )
}
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-16 18:51:56 +00:00
Function Get-AnsibleParam($obj , $name , $default = $null , $resultobj , $failifempty = $false , $emptyattributefailmessage , $ValidateSet , $ValidateSetErrorMessage , $type = $null )
2014-08-29 08:39:42 +00:00
{
2015-08-22 22:19:43 +00:00
# Check if the provided Member $name exists in $obj and return it or the default.
Try
2014-08-29 08:39:42 +00:00
{
2015-08-22 22:19:43 +00:00
If ( -not $obj . $name . GetType )
{
throw
}
2015-09-30 19:02:12 +00:00
if ( $ValidateSet )
{
if ( $ValidateSet -contains ( $obj . $name ) )
{
2017-01-16 18:51:56 +00:00
$value = $obj . $name
2015-09-30 19:02:12 +00:00
}
Else
{
if ( $ValidateSetErrorMessage -eq $null )
{
#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
}
}
Else
{
2017-01-16 18:51:56 +00:00
$value = $obj . $name
2015-09-30 19:02:12 +00:00
}
2014-08-29 08:39:42 +00:00
}
2015-08-22 22:19:43 +00:00
Catch
2014-08-29 08:39:42 +00:00
{
2015-08-22 22:19:43 +00:00
If ( $failifempty -eq $false )
{
2017-01-16 18:51:56 +00:00
$value = $default
2015-08-22 22:19:43 +00:00
}
Else
{
If ( ! $emptyattributefailmessage )
{
$emptyattributefailmessage = " Missing required argument: $name "
}
Fail-Json -obj $resultobj -message $emptyattributefailmessage
}
2014-08-29 08:39:42 +00:00
}
2017-01-16 18:51:56 +00:00
# Expand environment variables on path-type (Beware: turns $null into "")
If ( $value -ne $null -and $type -eq " path " ) {
$value = Expand-Environment ( $value )
}
$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
}
2015-09-30 19:02:12 +00:00
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
if ( ( $obj . GetType ( ) . Name -eq " Boolean " -and $obj ) -or $boolean_strings -contains $obj_string . ToLower ( ) )
{
$true
}
Else
{
$false
}
return
}
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 )
{
$parameters = New-Object psobject
If ( $arguments . Length -gt 0 )
{
$parameters = Get-Content $arguments [ 0 ] | ConvertFrom-Json
}
$check_mode = Get-Attr $parameters " _ansible_check_mode " $false | ConvertTo-Bool
If ( $check_mode -and -not $supports_check_mode )
{
$obj = New-Object psobject
Set-Attr $obj " skipped " $true
Set-Attr $obj " changed " $false
Set-Attr $obj " msg " " remote module does not support check mode "
Exit-Json $obj
}
$parameters
}
2015-07-14 11:28:32 +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:
2015-07-14 11:28:32 +00:00
Function Get-FileChecksum($path )
2014-11-24 18:03:32 +00:00
{
$hash = " "
If ( Test-Path -PathType Leaf $path )
{
2015-07-14 11:28:32 +00:00
$sp = new-object -TypeName System . Security . Cryptography . SHA1CryptoServiceProvider ;
2016-03-01 00:30:55 +00:00
$fp = [ System.IO.File ] :: Open ( $path , [ System.IO.Filemode ] :: Open , [ System.IO.FileAccess ] :: Read , [ System.IO.FileShare ] :: ReadWrite ) ;
2015-06-01 20:53:49 +00:00
$hash = [ System.BitConverter ] :: ToString ( $sp . ComputeHash ( $fp ) ) . Replace ( " - " , " " ) . ToLower ( ) ;
2014-11-24 18:03:32 +00:00
$fp . Dispose ( ) ;
}
ElseIf ( Test-Path -PathType Container $path )
{
$hash = " 3 " ;
}
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
}
else
{
return $False
}
}