Skip to content

Instantly share code, notes, and snippets.

@trondhindenes
Created May 23, 2016 21:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save trondhindenes/eb5bcc9a4dd8615807c31c495a95e6ba to your computer and use it in GitHub Desktop.
Save trondhindenes/eb5bcc9a4dd8615807c31c495a95e6ba to your computer and use it in GitHub Desktop.
#!powershell
# <COPYRIGHT>
# <CODEGENMETA>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
# WANT_JSON
# POWERSHELL_COMMON
$params = Parse-Args $args
$result = New-Object psobject
Set-Attr $result "changed" $false
#ATTRIBUTE:DestinationPath;MANDATORY:True;DEFAULTVALUE:;DESCRIPTION:;CHOICES:
$DestinationPath = Get-Attr -obj $params -name DestinationPath -failifempty $True -resultobj $result
#ATTRIBUTE:Attributes;MANDATORY:False;DEFAULTVALUE:;DESCRIPTION:;CHOICES:Archive,Hidden,ReadOnly,System
$Attributes = Get-Attr -obj $params -name Attributes -failifempty $False -resultobj $result
#ATTRIBUTE:Checksum;MANDATORY:False;DEFAULTVALUE:;DESCRIPTION:;CHOICES:CreatedDate,ModifiedDate,SHA-1,SHA-256,SHA-512
$Checksum = Get-Attr -obj $params -name Checksum -failifempty $False -resultobj $result
#ATTRIBUTE:Contents;MANDATORY:False;DEFAULTVALUE:;DESCRIPTION:;CHOICES:
$Contents = Get-Attr -obj $params -name Contents -failifempty $False -resultobj $result
#ATTRIBUTE:Credential_username;MANDATORY:False;DEFAULTVALUE:;DESCRIPTION:;CHOICES:
$Credential_username = Get-Attr -obj $params -name Credential_username -failifempty $False -resultobj $result
#ATTRIBUTE:Credential_password;MANDATORY:False;DEFAULTVALUE:;DESCRIPTION:;CHOICES:
$Credential_password = Get-Attr -obj $params -name Credential_password -failifempty $False -resultobj $result
#ATTRIBUTE:Ensure;MANDATORY:False;DEFAULTVALUE:;DESCRIPTION:;CHOICES:Absent,Present
$Ensure = Get-Attr -obj $params -name Ensure -failifempty $False -resultobj $result
#ATTRIBUTE:Force;MANDATORY:False;DEFAULTVALUE:;DESCRIPTION:;CHOICES:
$Force = Get-Attr -obj $params -name Force -failifempty $False -resultobj $result
#ATTRIBUTE:MatchSource;MANDATORY:False;DEFAULTVALUE:;DESCRIPTION:;CHOICES:
$MatchSource = Get-Attr -obj $params -name MatchSource -failifempty $False -resultobj $result
#ATTRIBUTE:PsDscRunAsCredential_username;MANDATORY:False;DEFAULTVALUE:;DESCRIPTION:;CHOICES:
$PsDscRunAsCredential_username = Get-Attr -obj $params -name PsDscRunAsCredential_username -failifempty $False -resultobj $result
#ATTRIBUTE:PsDscRunAsCredential_password;MANDATORY:False;DEFAULTVALUE:;DESCRIPTION:;CHOICES:
$PsDscRunAsCredential_password = Get-Attr -obj $params -name PsDscRunAsCredential_password -failifempty $False -resultobj $result
#ATTRIBUTE:Recurse;MANDATORY:False;DEFAULTVALUE:;DESCRIPTION:;CHOICES:
$Recurse = Get-Attr -obj $params -name Recurse -failifempty $False -resultobj $result
#ATTRIBUTE:SourcePath;MANDATORY:False;DEFAULTVALUE:;DESCRIPTION:;CHOICES:
$SourcePath = Get-Attr -obj $params -name SourcePath -failifempty $False -resultobj $result
#ATTRIBUTE:Type;MANDATORY:False;DEFAULTVALUE:;DESCRIPTION:;CHOICES:Directory,File
$Type = Get-Attr -obj $params -name Type -failifempty $False -resultobj $result
#ATTRIBUTE:AutoInstallModule;MANDATORY:False;DEFAULTVALUE:false;DESCRIPTION:If true, the required dsc resource/module will be auto-installed using the Powershell package manager;CHOICES:true,false
$AutoInstallModule = Get-Attr -obj $params -name AutoInstallModule -failifempty $False -resultobj $result -default false
#ATTRIBUTE:AutoConfigureLcm;MANDATORY:False;DEFAULTVALUE:false;DESCRIPTION:If true, LCM will be auto-configured for directly invoking DSC resources (which is a one-time requirement for Ansible DSC modules);CHOICES:true,false
$AutoConfigureLcm = Get-Attr -obj $params -name AutoConfigureLcm -failifempty $False -resultobj $result -default false
If ($Attributes)
{
If (('Archive','Hidden','ReadOnly','System') -contains $Attributes ) {
}
Else
{
Fail-Json $result "Option Attributes has invalid value $Attributes. Valid values are 'Archive','Hidden','ReadOnly','System'"
}
}
If ($Checksum)
{
If (('CreatedDate','ModifiedDate','SHA-1','SHA-256','SHA-512') -contains $Checksum ) {
}
Else
{
Fail-Json $result "Option Checksum has invalid value $Checksum. Valid values are 'CreatedDate','ModifiedDate','SHA-1','SHA-256','SHA-512'"
}
}
If ($Ensure)
{
If (('Absent','Present') -contains $Ensure ) {
}
Else
{
Fail-Json $result "Option Ensure has invalid value $Ensure. Valid values are 'Absent','Present'"
}
}
If ($Type)
{
If (('Directory','File') -contains $Type ) {
}
Else
{
Fail-Json $result "Option Type has invalid value $Type. Valid values are 'Directory','File'"
}
}
If ($AutoInstallModule)
{
If (('true','false') -contains $AutoInstallModule ) {
}
Else
{
Fail-Json $result "Option AutoInstallModule has invalid value $AutoInstallModule. Valid values are 'true','false'"
}
}
If ($AutoConfigureLcm)
{
If (('true','false') -contains $AutoConfigureLcm ) {
}
Else
{
Fail-Json $result "Option AutoConfigureLcm has invalid value $AutoConfigureLcm. Valid values are 'true','false'"
}
}
if ($Credential_username)
{
$Credential_securepassword = $Credential_password | ConvertTo-SecureString -asPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential($Credential_username,$Credential_securepassword)
}
if ($PsDscRunAsCredential_username)
{
$PsDscRunAsCredential_securepassword = $PsDscRunAsCredential_password | ConvertTo-SecureString -asPlainText -Force
$PsDscRunAsCredential = New-Object System.Management.Automation.PSCredential($PsDscRunAsCredential_username,$PsDscRunAsCredential_securepassword)
}
$DscResourceName = "file"
#This code comes from powershell2_dscresourceverify.ps1 in the DSC-->Ansible codegen tool
#Verify powershell version
if (($psversiontable.psversion.major -ge 5) -and ($psversiontable.psversion.build -ge 10018))
{
#Do nothing
}
Else
{
Fail-Json $result "Local powershell version is not at the reuired version (found version $($Psversiontable.psversion.tostring()) )"
}
if ($AutoInstallModule)
{
$AutoInstallModule = $AutoInstallModule | convertto-bool
}
$ResourceExists = Get-DscResource $dscresourcename -ErrorAction SilentlyContinue
if (!$ResourceExists)
{
#Download the module containing the resource if that's allowed
if ($AutoInstallModule | convertto-bool)
{
#USe find-package to auto-install the nuget binaries
Find-Package something -ForceBootstrap -ErrorAction SilentlyContinue | out-null
$res = Find-dscresource $dscresourcename
install-module $res.modulename -force
Set-Attr $result "AutoInstalledModule" $res.modulename
}
$ResourceExists = Get-DscResource $dscresourcename -ErrorAction SilentlyContinue
}
if (!$ResourceExists)
{
Fail-Json $result "Unable to locate DSC module $dscmodulename and/or DSC resource $dscresourcename"
}
#Check that LCM is in the right status
$Lcm = Get-DscLocalConfigurationManager
if (($lcm.RefreshMode) -eq "Disabled")
{
#All good
}
Else
{
if (($autoconfigureLcm | convertto-bool) -eq $true)
{
$refreshmode = "Disabled"
#Reconfigure LCM
[DscLocalConfigurationManager()]
Configuration Meta {
Settings {
RefreshMode = $RefreshMode
}
}
try
{
& meta
Set-DscLocalConfigurationManager -Path .\Meta -ErrorAction Stop -ErrorVariable lcmerror
}
Catch
{
Fail-json $result "Error reconfiguring LCM"
}
}
Else
{
Fail-json $result "DSC Local Configuration Manager is not set to disabled. Set the module option AutoConfigureLcm to Disabled in order to auto-configure LCM"
}
}
$Attributes = $params | get-member | where {$_.MemberTYpe -eq "noteproperty"} | select -ExpandProperty Name
$Attributes = $attributes | where {$_ -ne "autoinstallmodule"}
$Attributes = $attributes | where {$_ -ne "AutoConfigureLcm"}
if (!($Attributes))
{
Fail-Json -obj $result -message "No attributes specified"
}
#Always return the name
set-attr -obj $result -name "resource_name" -value $dscresourcename
set-attr -obj $result -name "Attributes" -value $Attributes
$Attrib = @{}
<#
$params.Keys | foreach-object {
$Attrib.Add($_,$params.Item($_))
set-attr -obj $result -name $_ -value $params.Item($_)
}
#>
$Keys = $params.psobject.Properties | where {$_.MemberTYpe -eq "Noteproperty"} | where {$_.Name -ne "resource_name"} |where {$_.Name -ne "autoinstallmodule"} |where {$_.Name -ne "autoconfigurelcm"}|where {$_.Name -notlike "_ansible*"} | select -ExpandProperty Name
foreach ($key in $keys)
{
$Attrib.add($key, ($params.$key))
set-attr -obj $result -name $key -value ($params.$key)
}
$Config = @{
Name = ($dscresourcename)
Property = @{
}
}
$Resource = Get-DscResource -Name $dscresourcename -ErrorAction SilentlyContinue
if (!$Resource)
{
Fail-Json -obj $result -message "Resource $dscresourcename not found"
}
#Convert params to correct datatype and inject
#Convert params to correct datatype and inject
$attrib.Keys | foreach-object {
$Key = $_.replace("item_name", "name")
$prop = $resource.Properties | where {$_.Name -eq $key}
if (!$prop)
{
#If its a credential specified as "credential", Ansible will support credential_username and credential_password. Need to check for that
$prop = $resource.Properties | where {$_.Name -eq $key.Replace("_username","")}
if ($prop)
{
#We need to construct a cred object. At this point keyvalue is the username, so grab the password
$PropUserNameValue = $attrib.Item($_)
$PropPassword = $key.Replace("_username","_password")
$PropPasswordValue = $attrib.$PropPassword
$cred = New-Object System.Management.Automation.PSCredential ($PropUserNameValue, ($PropPasswordValue | ConvertTo-SecureString -AsPlainText -Force))
[System.Management.Automation.PSCredential]$KeyValue = $cred
$config.Property.Add($key.Replace("_username",""),$KeyValue)
}
ElseIf ($key.Contains("_password"))
{
#Do nothing. We suck in the password in the handler for _username, so we can just skip it.
}
Else
{
Fail-Json -obj $result -message "Property $key in resource $dscresourcename is not a valid property"
}
}
ElseIf ($prop.PropertyType -eq "[string]")
{
[String]$KeyValue = $attrib.Item($_)
$config.Property.Add($key,$KeyValue)
}
ElseIf ($prop.PropertyType -eq "[string[]]")
{
#KeyValue is an array of strings
[String]$TempKeyValue = $attrib.Item($_)
[String[]]$KeyValue = $TempKeyValue.Split(",").Trim()
$config.Property.Add($key,$KeyValue)
}
ElseIf ($prop.PropertyType -eq "[UInt32[]]")
{
#KeyValue is an array of integers
[String]$TempKeyValue = $attrib.Item($_)
[UInt32[]]$KeyValue = $attrib.Item($_.split(",").Trim())
$config.Property.Add($key,$KeyValue)
}
ElseIf ($prop.PropertyType -eq "[bool]")
{
if ($attrib.Item($_) -like "true")
{
[bool]$KeyValue = $true
}
ElseIf ($attrib.Item($_) -like "false")
{
[bool]$KeyValue = $false
}
$config.Property.Add($key,$KeyValue)
}
ElseIf ($prop.PropertyType -eq "[int]")
{
[int]$KeyValue = $attrib.Item($_)
$config.Property.Add($key,$KeyValue)
}
ElseIf ($prop.PropertyType -eq "[CimInstance[]]")
{
#KeyValue is an array of CimInstance
[CimInstance[]]$KeyVal = @()
[String]$TempKeyValue = $attrib.Item($_)
#Need to split on the string }, because some property values have commas in them
[String[]]$KeyValueStr = $TempKeyValue -split("},")
#Go through each string of properties and create a hash of them
foreach($str in $KeyValueStr)
{
[string[]]$properties = $str.Split("{")[1].Replace("}","").Trim().Split([environment]::NewLine).Trim()
$prph = @{}
foreach($p in $properties)
{
$pArr = $p -split "="
#if the value can be an int we must convert it to an int
if([bool]($pArr[1] -as [int] -is [int]))
{
$prph.Add($pArr[0].Trim(),$pArr[1].Trim() -as [int])
}
else
{
$prph.Add($pArr[0].Trim(),$pArr[1].Trim())
}
}
#create the new CimInstance
$cim = New-CimInstance -ClassName $str.Split("{")[0].Trim() -Property $prph -ClientOnly
#add the new CimInstance to the array
$KeyVal += $cim
}
$config.Property.Add($key,$KeyVal)
}
}
try
{
#Invoke WMF5 production preview differently than feb preview
$TargetVersion = [version]::new("5.0.10514.6")
if ($PSVersionTable.PSVersion.CompareTo($TargetVersion) -ge 0)
{
#Current hosts version is production prevoew or higher. Use modulename when invoking.
$Params = @{"Modulename"=$resource.Modulename}
}
else
{
$Params = @{}
}
$TestResult = Invoke-DscResource @Config -Method Test @params -ErrorVariable TestError -ErrorAction SilentlyContinue
if ($TestError)
{
throw ($TestError[0].Exception.Message)
}
ElseIf (($testResult.InDesiredState) -ne $true)
{
Invoke-DscResource -Method Set @Config @params -ErrorVariable SetError -ErrorAction SilentlyContinue
Set-Attr $result "changed" $true
if ($SetError)
{
throw ($SetError[0].Exception.Message)
}
}
}
Catch
{
Fail-Json -obj $result -message $_[0].Exception.Message
}
#set-attr -obj $result -name "property" -value $property
Exit-Json -obj $result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment