diff --git a/system/setup b/system/setup
index cc3a5855f1e..3194500cb2e 100644
--- a/system/setup
+++ b/system/setup
@@ -54,6 +54,9 @@ notes:
install I(facter) and I(ohai) means you can avoid Ruby-dependencies on your
remote systems. (See also M(facter) and M(ohai).)
- The filter option filters only the first level subkey below ansible_facts.
+ - If the target host is Windows, you will not currently have the ability to use
+ C(fact_path) or C(filter) as this is provided by a simpler implementation of the module.
+ Different facts are returned for Windows hosts.
author: Michael DeHaan
'''
diff --git a/windows/setup.ps1 b/windows/setup.ps1
new file mode 100644
index 00000000000..adec2d9ae0d
--- /dev/null
+++ b/windows/setup.ps1
@@ -0,0 +1,45 @@
+#!powershell
+# 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 .
+
+# WANT_JSON
+# POWERSHELL_COMMON
+
+# $params is not currently used in this module
+# $params = Parse-Args $args;
+
+$result = New-Object psobject @{
+ ansible_facts = New-Object psobject
+ changed = $false
+};
+
+$osversion = [Environment]::OSVersion
+$memory = Get-WmiObject win32_Pysicalmemory
+$netcfg = Get-WmiObject win32_NetworkAdapterConfiguration
+
+Set-Attr $result.ansible_facts "ansible_hostname" $env:COMPUTERNAME;
+Set-Attr $result.ansible_facts "ansible_fqdn" "$([System.Net.Dns]::GetHostByName((hostname)).HostName)"
+Set-Attr $result.ansible_facts "ansible_system" $osversion.Platform.ToString()
+Set-Attr $result.ansible_facts "ansible_os_family" "Windows"
+Set-Attr $result.ansible_facts "ansible_distribution" $osversion.VersionString
+Set-Attr $result.ansible_facts "ansible_distribution_version" $osversion.Version.ToString()
+
+Set-Attr $result.ansible_facts "ansible_totalmem" $memory.Capacity.ToString()
+
+$ips = @()
+Foreach ($ip in $netcfg.IPAddress) { If ($ip) { $ips += $ip } }
+Set-Attr $result.ansible_facts "ansible_ip_addresses" $ips
+
+Exit-Json $result;
diff --git a/windows/slurp.ps1 b/windows/slurp.ps1
new file mode 100644
index 00000000000..edf1da7635f
--- /dev/null
+++ b/windows/slurp.ps1
@@ -0,0 +1,46 @@
+#!powershell
+# 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 .
+
+# WANT_JSON
+# POWERSHELL_COMMON
+
+$params = Parse-Args $args;
+
+$src = Get-Attr $params "src" (Get-Attr $params "path" $FALSE);
+If (-not $src)
+{
+ Fail-Json (New-Object psobject) "missing required argument: src";
+}
+
+If (Test-Path -PathType Leaf $src)
+{
+ $bytes = [System.IO.File]::ReadAllBytes($src);
+ $content = [System.Convert]::ToBase64String($bytes);
+ $result = New-Object psobject @{
+ changed = $false
+ encoding = "base64"
+ content = $content
+ };
+ Exit-Json $result;
+}
+ElseIf (Test-Path -PathType Container $src)
+{
+ Fail-Json (New-Object psobject) ("is a directory: " + $src);
+}
+Else
+{
+ Fail-Json (New-Object psobject) ("file not found: " + $src);
+}
diff --git a/windows/win_feature b/windows/win_feature
new file mode 100644
index 00000000000..0151ee32261
--- /dev/null
+++ b/windows/win_feature
@@ -0,0 +1,77 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# (c) 2014, Paul Durivage , and others
+#
+# 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 .
+
+# this is a windows documentation stub. actual code lives in the .ps1
+# file of the same name
+
+DOCUMENTATION = '''
+---
+module: win_feature
+version_added: "1.7"
+short_description: Fetches a file from a given URL
+description:
+ - Fetches a file from a URL and saves to locally
+options:
+ name:
+ description:
+ - Names of roles or features to install as a single feature or a comma-separated list of features
+ required: true
+ default: null
+ aliases: []
+ state:
+ description:
+ - State of the features or roles on the system
+ required: false
+ choices:
+ - present
+ - absent
+ default: present
+ aliases: []
+ restart:
+ description:
+ - Restarts the computer automatically when installation is complete, if restarting is required by the roles or features installed.
+ choices:
+ - yes
+ - no
+ default: null
+ aliases: []
+author: Paul Durivage
+'''
+
+EXAMPLES = '''
+# This installs IIS.
+# The names of features available for install can be run by running the following Powershell Command:
+# PS C:\Users\Administrator> Import-Module ServerManager; Get-WindowsFeature
+$ ansible -i hosts -m win_feature -a "name=Web-Server" all
+$ ansible -i hosts -m win_feature -a "name=Web-Server,Web-Common-Http" all
+
+
+# Playbook example
+---
+- name: Install IIS
+ hosts: all
+ gather_facts: false
+ tasks:
+ - name: Install IIS
+ win_feature:
+ name: "Web-Server"
+ state: absent
+ restart: yes
+'''
diff --git a/windows/win_feature.ps1 b/windows/win_feature.ps1
new file mode 100644
index 00000000000..698d78dfcad
--- /dev/null
+++ b/windows/win_feature.ps1
@@ -0,0 +1,100 @@
+#!powershell
+# This file is part of Ansible.
+#
+# Copyright 2014, Paul Durivage
+#
+# 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 .
+
+# WANT_JSON
+# POWERSHELL_COMMON
+
+Import-Module Servermanager;
+
+$params = Parse-Args $args;
+
+$result = New-Object psobject @{
+ changed = $false
+}
+
+If ($params.name) {
+ $name = $params.name
+}
+Else {
+ Fail-Json $result "mising required argument: name"
+}
+
+If ($params.state) {
+ $state = $params.state.ToString().ToLower()
+ If (($state -ne 'present') -and ($state -ne 'absent')) {
+ Fail-Json $result "state is '$state'; must be 'present' or 'absent'"
+ }
+}
+Elseif (!$params.state) {
+ $state = "present"
+}
+
+If ($params.restart) {
+ $restart = $params.restart | ConvertTo-Bool
+}
+
+If ($state -eq "present") {
+ try {
+ if ($restart) {
+ $featureresult = Add-WindowsFeature -Name $name -Restart
+ }
+ else {
+ $featureresult = Add-WindowsFeature -Name $name
+ }
+ }
+ catch {
+ Fail-Json $result $_.Exception.Message
+ }
+}
+Elseif ($state -eq "absent") {
+ try {
+ if ($restart) {
+ $featureresult = Remove-WindowsFeature -Name $name -Restart
+ }
+ else {
+ $featureresult = Remove-WindowsFeature -Name $name
+ }
+ }
+ catch {
+ Fail-Json $result $_.Exception.Message
+ }
+}
+
+# Loop through results and create a hash containing details about
+# each role/feature that is installed/removed
+$installed_features = @()
+ForEach ($item in $featureresult.FeatureResult) {
+ $installed_features += New-Object psobject @{
+ id = $item.id.ToString()
+ display_name = $item.DisplayName
+ message = $item.Message.ToString()
+ restart_needed = $item.RestartNeeded.ToString()
+ skip_reason = $item.SkipReason.ToString()
+ success = $item.Success.ToString()
+ }
+}
+Set-Attr $result "feature_result" $installed_features
+Set-Attr $result "feature_success" $featureresult.Success.ToString()
+Set-Attr $result "feature_exitcode" $featureresult.ExitCode.ToString()
+Set-Attr $result "feature_restart_needed" $featureresult.RestartNeeded.ToString()
+
+If ($result.feature_result.Length -gt 0) {
+ $result.changed = $true
+}
+
+Exit-Json $result;
diff --git a/windows/win_get_url b/windows/win_get_url
new file mode 100644
index 00000000000..10910cf605e
--- /dev/null
+++ b/windows/win_get_url
@@ -0,0 +1,57 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# (c) 2014, Paul Durivage , and others
+#
+# 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 .
+
+# this is a windows documentation stub. actual code lives in the .ps1
+# file of the same name
+
+DOCUMENTATION = '''
+---
+module: win_get_url
+version_added: "1.7"
+short_description: Fetches a file from a given URL
+description:
+ - Fetches a file from a URL and saves to locally
+options:
+ url:
+ description:
+ - The full URL of a file to download
+ required: true
+ default: null
+ aliases: []
+ dest:
+ description:
+ - The absolute path of the location to save the file at the URL. Be sure to include a filename and extension as appropriate.
+ required: false
+ default: yes
+ aliases: []
+author: Paul Durivage
+'''
+
+EXAMPLES = '''
+# Downloading a JPEG and saving it to a file with the ansible command.
+# Note the "dest" is quoted rather instead of escaping the backslashes
+$ ansible -i hosts -c winrm -m win_get_url -a "url=http://www.example.com/earthrise.jpg dest='C:\Users\Administrator\earthrise.jpg'" all
+
+# Playbook example
+- name: Download earthrise.jpg to 'C:\Users\RandomUser\earthrise.jpg'
+ win_get_url:
+ url: 'http://www.example.com/earthrise.jpg'
+ dest: 'C:\Users\RandomUser\earthrise.jpg'
+'''
diff --git a/windows/win_get_url.ps1 b/windows/win_get_url.ps1
new file mode 100644
index 00000000000..b555cc7a52c
--- /dev/null
+++ b/windows/win_get_url.ps1
@@ -0,0 +1,56 @@
+#!powershell
+# This file is part of Ansible.
+#
+# Copyright 2014, Paul Durivage
+#
+# 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 .
+
+# WANT_JSON
+# POWERSHELL_COMMON
+
+$params = Parse-Args $args;
+
+$result = New-Object psobject @{
+ win_get_url = New-Object psobject
+ changed = $false
+}
+
+If ($params.url) {
+ $url = $params.url
+}
+Else {
+ Fail-Json $result "mising required argument: url"
+}
+
+If ($params.dest) {
+ $dest = $params.dest
+}
+Else {
+ Fail-Json $result "missing required argument: dest"
+}
+
+$client = New-Object System.Net.WebClient
+
+Try {
+ $client.DownloadFile($url, $dest)
+ $result.changed = $true
+}
+Catch {
+ Fail-Json $result "Error downloading $url to $dest"
+}
+
+Set-Attr $result.win_get_url "url" $url
+Set-Attr $result.win_get_url "dest" $dest
+
+Exit-Json $result;
diff --git a/windows/win_msi b/windows/win_msi
new file mode 100644
index 00000000000..9eb6f1bafa5
--- /dev/null
+++ b/windows/win_msi
@@ -0,0 +1,58 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# (c) 2014, Matt Martz , and others
+#
+# 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 .
+
+# this is a windows documentation stub. actual code lives in the .ps1
+# file of the same name
+
+DOCUMENTATION = '''
+---
+module: win_msi
+version_added: "1.7"
+short_description: Installs and uninstalls Windows MSI files
+description:
+ - Installs or uninstalls a Windows MSI file that is already located on the
+ target server
+options:
+ path:
+ description:
+ - File system path to the MSI file to install
+ required: true
+ state:
+ description:
+ - Whether the MSI file should be installed or uninstalled
+ choices:
+ - present
+ - absent
+ default: present
+ creates:
+ description:
+ - Path to a file created by installing the MSI to prevent from
+ attempting to reinstall the package on every run
+author: Matt Martz
+'''
+
+EXAMPLES = '''
+# Install an MSI file
+- win_msi: path=C:\\\\7z920-x64.msi
+
+# Uninstall an MSI file
+- win_msi: path=C:\\\\7z920-x64.msi state=absent
+'''
+
diff --git a/windows/win_msi.ps1 b/windows/win_msi.ps1
new file mode 100644
index 00000000000..1c2bc8a3019
--- /dev/null
+++ b/windows/win_msi.ps1
@@ -0,0 +1,63 @@
+#!powershell
+# (c) 2014, Matt Martz , and others
+#
+# 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 .
+
+# WANT_JSON
+# POWERSHELL_COMMON
+
+$params = Parse-Args $args;
+
+$result = New-Object psobject;
+Set-Attr $result "changed" $false;
+
+If (-not $params.path.GetType)
+{
+ Fail-Json $result "missing required arguments: path"
+}
+
+$extra_args = ""
+If ($params.extra_args.GetType)
+{
+ $extra_args = $params.extra_args;
+}
+
+If ($params.creates.GetType -and $params.state.GetType -and $params.state -ne "absent")
+{
+ If (Test-File $creates)
+ {
+ Exit-Json $result;
+ }
+}
+
+$logfile = [IO.Path]::GetTempFileName();
+if ($params.state.GetType -and $params.state -eq "absent")
+{
+ msiexec.exe /x $params.path /qb /l $logfile $extra_args;
+}
+Else
+{
+ msiexec.exe /i $params.path /qb /l $logfile $extra_args;
+}
+
+Set-Attr $result "changed" $true;
+
+$logcontents = Get-Content $logfile;
+Remove-Item $logfile;
+
+Set-Attr $result "log" $logcontents;
+
+Exit-Json $result;
diff --git a/windows/win_ping b/windows/win_ping
new file mode 100644
index 00000000000..de32877d615
--- /dev/null
+++ b/windows/win_ping
@@ -0,0 +1,48 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# (c) 2012, Michael DeHaan , and others
+#
+# 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 .
+
+# this is a windows documentation stub. actual code lives in the .ps1
+# file of the same name
+
+DOCUMENTATION = '''
+---
+module: win_ping
+version_added: "1.7"
+short_description: A windows version of the classic ping module.
+description:
+ - Checks management connectivity of a windows host
+options:
+ data:
+ description:
+ - Alternate data to return instead of 'pong'
+ required: false
+ default: 'pong'
+ aliases: []
+author: Chris Church
+'''
+
+EXAMPLES = '''
+# Test connectivity to a windows host
+ansible winserver -m win_ping
+
+# Example from an Ansible Playbook
+- action: win_ping
+'''
+
diff --git a/windows/win_ping.ps1 b/windows/win_ping.ps1
new file mode 100644
index 00000000000..98f1415e290
--- /dev/null
+++ b/windows/win_ping.ps1
@@ -0,0 +1,29 @@
+#!powershell
+# 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 .
+
+# WANT_JSON
+# POWERSHELL_COMMON
+
+$params = Parse-Args $args;
+
+$data = Get-Attr $params "data" "pong";
+
+$result = New-Object psobject @{
+ changed = $false
+ ping = $data
+};
+
+Exit-Json $result;
diff --git a/windows/win_stat b/windows/win_stat
new file mode 100644
index 00000000000..c98cd55f599
--- /dev/null
+++ b/windows/win_stat
@@ -0,0 +1,52 @@
+#!/usr/bin/python
+# 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 .
+
+# this is a windows documentation stub, actual code lives in the .ps1
+# file of the same name
+
+DOCUMENTATION = '''
+---
+module: win_stat
+version_added: "1.7"
+short_description: returns information about a Windows file
+description:
+ - Returns information about a Windows file
+options:
+ path:
+ description:
+ - The full path of the file/object to get the facts of; both forward and
+ back slashes are accepted.
+ required: true
+ default: null
+ aliases: []
+ get_md5:
+ description:
+ - Whether to return the md5 sum of the file
+ required: false
+ default: yes
+ aliases: []
+author: Chris Church
+'''
+
+EXAMPLES = '''
+# Obtain information about a file
+
+- win_stat: path=C:\\foo.ini
+ register: file_info
+
+- debug: var=file_info
+'''
+
diff --git a/windows/win_stat.ps1 b/windows/win_stat.ps1
new file mode 100644
index 00000000000..f60bc577ec7
--- /dev/null
+++ b/windows/win_stat.ps1
@@ -0,0 +1,60 @@
+#!powershell
+# 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 .
+
+# WANT_JSON
+# POWERSHELL_COMMON
+
+$params = Parse-Args $args;
+
+$path = Get-Attr $params "path" $FALSE;
+If ($path -eq $FALSE)
+{
+ Fail-Json (New-Object psobject) "missing required argument: path";
+}
+
+$get_md5 = Get-Attr $params "get_md5" $TRUE | ConvertTo-Bool;
+
+$result = New-Object psobject @{
+ stat = New-Object psobject
+ changed = $false
+};
+
+If (Test-Path $path)
+{
+ Set-Attr $result.stat "exists" $TRUE;
+ $info = Get-Item $path;
+ If ($info.Directory) # Only files have the .Directory attribute.
+ {
+ Set-Attr $result.stat "isdir" $FALSE;
+ Set-Attr $result.stat "size" $info.Length;
+ }
+ Else
+ {
+ Set-Attr $result.stat "isdir" $TRUE;
+ }
+}
+Else
+{
+ Set-Attr $result.stat "exists" $FALSE;
+}
+
+If ($get_md5 -and $result.stat.exists -and -not $result.stat.isdir)
+{
+ $path_md5 = (Get-FileHash -Path $path -Algorithm MD5).Hash.ToLower();
+ Set-Attr $result.stat "md5" $path_md5;
+}
+
+Exit-Json $result;
diff --git a/windows/win_user b/windows/win_user
new file mode 100644
index 00000000000..e2da6a1ddb8
--- /dev/null
+++ b/windows/win_user
@@ -0,0 +1,71 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# (c) 2014, Matt Martz , and others
+#
+# 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 .
+
+# this is a windows documentation stub. actual code lives in the .ps1
+# file of the same name
+
+DOCUMENTATION = '''
+---
+module: win_user
+version_added: "1.7"
+short_description: Manages local Windows user accounts
+description:
+ - Manages local Windows user accounts
+options:
+ name:
+ description:
+ - Username of the user to manage
+ required: true
+ default: null
+ aliases: []
+ password:
+ description:
+ - Password for the user (plain text)
+ required: true
+ default: null
+ aliases: []
+ state:
+ description:
+ - Whether to create or delete a user
+ required: false
+ choices:
+ - present
+ - absent
+ default: present
+ aliases: []
+author: Paul Durivage
+'''
+
+EXAMPLES = '''
+# Ad-hoc example
+$ ansible -i hosts -m win_user -a "name=bob password=Password12345" all
+$ ansible -i hosts -m win_user -a "name=bob password=Password12345 state=absent" all
+
+# Playbook example
+---
+- name: Add a user
+ hosts: all
+ gather_facts: false
+ tasks:
+ - name: Add User
+ win_user:
+ name: ansible
+ password: "@ns1bl3"
+'''
diff --git a/windows/win_user.ps1 b/windows/win_user.ps1
new file mode 100644
index 00000000000..306d7a0db2f
--- /dev/null
+++ b/windows/win_user.ps1
@@ -0,0 +1,116 @@
+#!powershell
+# This file is part of Ansible
+#
+# Copyright 2014, Paul Durivage
+#
+# 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 .
+
+# WANT_JSON
+# POWERSHELL_COMMON
+
+########
+$adsi = [ADSI]"WinNT://$env:COMPUTERNAME"
+
+function Get-User($user) {
+ $adsi.Children | where {$_.SchemaClassName -eq 'user' -and $_.Name -eq $user }
+ return
+}
+
+function Create-User([string]$user, [string]$passwd) {
+ $adsiuser = $adsi.Create("User", $user)
+ $adsiuser.SetPassword($passwd)
+ $adsiuser.SetInfo()
+ $adsiuser
+ return
+}
+
+function Update-Password($user, [string]$passwd) {
+ $user.SetPassword($passwd)
+ $user.SetInfo()
+}
+
+function Delete-User($user) {
+ $adsi.delete("user", $user.Name.Value)
+}
+########
+
+$params = Parse-Args $args;
+
+$result = New-Object psobject @{
+ changed = $false
+};
+
+If (-not $params.name.GetType)
+{
+ Fail-Json $result "missing required arguments: name"
+}
+
+If ($params.state) {
+ $state = $params.state.ToString().ToLower()
+ If (($state -ne 'present') -and ($state -ne 'absent')) {
+ Fail-Json $result "state is '$state'; must be 'present' or 'absent'"
+ }
+}
+Elseif (!$params.state) {
+ $state = "present"
+}
+
+If ((-not $params.password.GetType) -and ($state -eq 'present'))
+{
+ Fail-Json $result "missing required arguments: password"
+}
+
+$username = Get-Attr $params "name"
+$password = Get-Attr $params "password"
+
+$user_obj = Get-User $username
+
+if ($state -eq 'present') {
+ # Add or update user
+ try {
+ if ($user_obj.GetType) {
+ Update-Password $user_obj $password
+ }
+ else {
+ Create-User $username $password
+ }
+ $result.changed = $true
+ $user_obj = Get-User $username
+ }
+ catch {
+ Fail-Json $result $_.Exception.Message
+ }
+}
+else {
+ # Remove user
+ try {
+ if ($user_obj.GetType) {
+ Delete-User $user_obj
+ $result.changed = $true
+ }
+ else {
+ Set-Attr $result "msg" "User '$username' was not found"
+ }
+ }
+ catch {
+ Fail-Json $result $_.Exception.Message
+ }
+}
+
+# Set-Attr $result "user" $user_obj
+Set-Attr $result "user_name" $user_obj.Name
+Set-Attr $result "user_fullname" $user_obj.FullName
+Set-Attr $result "user_path" $user_obj.Path
+
+Exit-Json $result;