Skip to content

Instantly share code, notes, and snippets.

@linuxsimba
Last active January 11, 2021 09:02
Show Gist options
  • Save linuxsimba/58b4c03531ef6efcbe860455c1218a79 to your computer and use it in GitHub Desktop.
Save linuxsimba/58b4c03531ef6efcbe860455c1218a79 to your computer and use it in GitHub Desktop.
Ansible Windows Powershell Module Example
#!powershell
#
# Copyright 2016, Stanley Karunditu <[email protected]>
#
# 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/>.
# Not quite sure what these do..but I see it in all powershell examples, so just leave it here.
# WANT_JSON
# POWERSHELL_COMMON
# Ansible Windows PowerShell Template
# Example function called at the end of this script
# This function checks AD group membership before adding a new user to a group
# If the user already exists, then update the "msg" field in the Ansible JSON string
# to say why it failed.
function GroupMembership ($member, $groupname) {
# Check if the $member is a user or group
# If not fail.
$membertype = 'user'
# Check if the member exists
$memberisuser = get-aduser -filter {(name -eq $member)}
if ($memberisuser -eq $null) {
$membertype = 'group'
$memberisgroup = get-adgroup -filter {(name -eq $member)}
if ( $memberisgroup -eq $null ) {
Fail-Json $result "member $member is not a user or group"
}
}
# Check if Group to add the member to exists. If it does
# not exist then fail.
$foundgroup = get-adgroup -filter {(name -eq $groupname)}
if ($foundgroup) {
$groupname = $foundgroup.name
} else {
Fail-Json $result "Group $groupname.name does not exist. Cannot proceed with group membership"
}
$gmembers = Get-AdGroupMember -Identity "$groupname" | Select -ExpandProperty Name
Set-Attr $result "group-members" $gmembers
if ($state -eq 'present') {
# If the state is present and the member is in the group
# no change. otherwise add the member to the group and
# change the $result.changed var.
if ($gmembers -contains $member) {
$result.msg = "Member $member already exist in Group $groupname"
} else {
Add-ADGroupMember "$groupname" "$member"
$result.msg = "$membertype $member added to group $groupname"
$result.changed = $true
}
} else {
if ($gmembers -contains $member){
Remove-ADGroupMember "$groupname" "$member" -confirm:$false
$result.changed = $true
$result.msg = "Removed $member from Group $groupname"
} else {
$result.msg = "Member $member is already deleted from Group $groupname"
}
}
}
# Parse the Keywords from the ansible module call
# Example: if the module command looks like this
# ----
# ansible -m mywinmodule command -a "groups=['g1','g2']" windowshost
# ----
# Then Parse-Args $args attributes like this
# groups: ['g1',g2']
$params = Parse-Args $args;
# Create a new object. Call it result. This will store the information you want to print
# out in the json result string when the module exits. By default its a good idea to add
# the "changed" and "msg" attributes.
# When "changed" == "false" it means that no action was taken to change the system. It is also
# a good idea to update the "msg" attribute and mention why no change occurred.
$result = New-Object psobject;
Set-Attr $result "changed" $false;
Set-Attr $result "msg" "";
# Extract each attribute into a variable. During this stage you can perform various checks.
# 1. Like checking if the attribute is empty. If it is, then exit the module with a failure
$groupname = Get-Attr $params "group" -failifempty $true
# 2. Check if the attribute is of a certain type like Array or String. If not then fail.
$members = Get-Attr $params "members" -failifempty $true
if ($members -is [System.String]) {
[string[]]$members = $members.Split(",")
} elseif ($members -isnot [System.Collections.IList]) {
Fail-Json $result "members must be a string or array"
}
# 3. Set default state of an attribute. In this case the "state" attribute is set to "present" if not set.
$state = Get-Attr $params "state" "present"
$state = $state.ToString().ToLower()
If (($state -ne "present") -and ($state -ne "absent")) {
Fail-Json $result "state is '$state'; must be 'present' or 'absent'"
}
# Think about performing some idempotence tests. In this case it checks to see if Active directory is running.
try {
$domain = get-addomain
} catch {
$errormsg = $_.Exception.Message
Fail-Json $result "AD Domain not active: $errormsg"
}
# If something needs to change, go ahead and attempt to execute the change
# In this case it executes a PowerShell function that adds a member to a group
$members = $members | ForEach { ([string]$_).Trim() } | Where { $_ }
foreach ($member in $members) {
GroupMembership -member $member -groupname $groupname
}
# Finally always return the $result attribute. This will have the "changed", "msg" and any other attribute
# you want to add to the JSON output string
Exit-Json $result;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment