diff --git a/lib/ansible/modules/windows/win_copy.ps1 b/lib/ansible/modules/windows/win_copy.ps1
new file mode 100644
index 00000000000..9ffdab85f03
--- /dev/null
+++ b/lib/ansible/modules/windows/win_copy.ps1
@@ -0,0 +1,84 @@
+#!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" $FALSE;
+If ($src -eq $FALSE)
+{
+ Fail-Json (New-Object psobject) "missing required argument: src";
+}
+
+$dest= Get-Attr $params "dest" $FALSE;
+If ($dest -eq $FALSE)
+{
+ Fail-Json (New-Object psobject) "missing required argument: dest";
+}
+
+# seems to be supplied by the calling environment, but
+# probably shouldn't be a test for it existing in the params.
+# TODO investigate.
+$original_basename = Get-Attr $params "original_basename" $FALSE;
+If ($original_basename -eq $FALSE)
+{
+ Fail-Json (New-Object psobject) "missing required argument: original_basename ";
+}
+
+$result = New-Object psobject @{
+ changed = $FALSE
+};
+
+# if $dest is a dir, append $original_basename so the file gets copied with its intended name.
+if (Test-Path $dest -PathType Container)
+{
+ $dest = Join-Path $dest $original_basename;
+}
+
+If (Test-Path $dest)
+{
+ $dest_checksum = Get-FileChecksum ($dest);
+ $src_checksum = Get-FileChecksum ($src);
+
+ If (! $src_checksum.CompareTo($dest_checksum))
+ {
+ # New-Item -Force creates subdirs for recursive copies
+ New-Item -Force $dest -Type file;
+ Copy-Item -Path $src -Destination $dest -Force;
+ }
+ $dest_checksum = Get-FileChecksum ($dest);
+ If ( $src_checksum.CompareTo($dest_checksum))
+ {
+ $result.changed = $TRUE;
+ }
+ Else
+ {
+ Fail-Json (New-Object psobject) "Failed to place file";
+ }
+}
+Else
+{
+ New-Item -Force $dest -Type file;
+ Copy-Item -Path $src -Destination $dest;
+ $result.changed = $TRUE;
+}
+
+$dest_checksum = Get-FileChecksum($dest);
+$result.checksum = $dest_checksum;
+
+Exit-Json $result;
diff --git a/lib/ansible/modules/windows/win_copy.py b/lib/ansible/modules/windows/win_copy.py
new file mode 100644
index 00000000000..7d0b49e5985
--- /dev/null
+++ b/lib/ansible/modules/windows/win_copy.py
@@ -0,0 +1,60 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# (c) 2012, Michael DeHaan
+#
+# 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 .
+
+import os
+import time
+
+DOCUMENTATION = '''
+---
+module: win_copy
+version_added: "1.8"
+short_description: Copies files to remote locations on windows hosts.
+description:
+ - The M(win_copy) module copies a file on the local box to remote windows locations.
+options:
+ src:
+ description:
+ - Local path to a file to copy to the remote server; can be absolute or relative.
+ If path is a directory, it is copied recursively. In this case, if path ends
+ with "/", only inside contents of that directory are copied to destination.
+ Otherwise, if it does not end with "/", the directory itself with all contents
+ is copied. This behavior is similar to Rsync.
+ required: false
+ default: null
+ aliases: []
+ dest:
+ description:
+ - Remote absolute path where the file should be copied to. If src is a directory,
+ this must be a directory too. Use \\ for path separators.
+ required: true
+ default: null
+author: Michael DeHaan
+notes:
+ - The "win_copy" module recursively copy facility does not scale to lots (>hundreds) of files.
+ Instead, you may find it better to create files locally, perhaps using win_template, and
+ then use win_get_url to put them in the correct location.
+'''
+
+EXAMPLES = '''
+# Example from Ansible Playbooks
+- win_copy: src=/srv/myfiles/foo.conf dest=c:\\TEMP\\foo.conf
+
+'''
+
diff --git a/lib/ansible/modules/windows/win_file.ps1 b/lib/ansible/modules/windows/win_file.ps1
new file mode 100644
index 00000000000..62ac81fc1ee
--- /dev/null
+++ b/lib/ansible/modules/windows/win_file.ps1
@@ -0,0 +1,105 @@
+#!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
+$path = Get-Attr $params "path" $FALSE;
+If ($path -eq $FALSE)
+{
+ $path = Get-Attr $params "dest" $FALSE;
+ If ($path -eq $FALSE)
+ {
+ $path = Get-Attr $params "name" $FALSE;
+ If ($path -eq $FALSE)
+ {
+ Fail-Json (New-Object psobject) "missing required argument: path";
+ }
+ }
+}
+
+# JH Following advice from Chris Church, only allow the following states
+# in the windows version for now:
+# state - file, directory, touch, absent
+# (originally was: state - file, link, directory, hard, touch, absent)
+
+$state = Get-Attr $params "state" "file";
+
+#$recurse = Get-Attr $params "recurse" "no";
+
+# force - yes, no
+# $force = Get-Attr $params "force" "no";
+
+# result
+$result = New-Object psobject @{
+ changed = $FALSE
+};
+
+If ( $state -eq "touch" )
+{
+ If(Test-Path $path)
+ {
+ (Get-ChildItem $path).LastWriteTime = Get-Date
+ }
+ Else
+ {
+ echo $null > $file
+ }
+ $result.changed = $TRUE;
+}
+
+If (Test-Path $path)
+{
+ $fileinfo = Get-Item $path;
+ If ( $state -eq "absent" )
+ {
+ Remove-Item -Recurse -Force $fileinfo;
+ $result.changed = $TRUE;
+ }
+ Else
+ {
+ # Only files have the .Directory attribute.
+ If ( $state -eq "directory" -and $fileinfo.Directory )
+ {
+ Fail-Json (New-Object psobject) "path is not a directory";
+ }
+
+ # Only files have the .Directory attribute.
+ If ( $state -eq "file" -and -not $fileinfo.Directory )
+ {
+ Fail-Json (New-Object psobject) "path is not a file";
+ }
+
+ }
+}
+Else
+{
+ If ( $state -eq "directory" )
+ {
+ New-Item -ItemType directory -Path $path
+ $result.changed = $TRUE;
+ }
+
+ If ( $state -eq "file" )
+ {
+ Fail-Json (New-Object psobject) "path will not be created";
+ }
+}
+
+Exit-Json $result;
diff --git a/lib/ansible/modules/windows/win_file.py b/lib/ansible/modules/windows/win_file.py
new file mode 100644
index 00000000000..6a218216617
--- /dev/null
+++ b/lib/ansible/modules/windows/win_file.py
@@ -0,0 +1,73 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# (c) 2012, Michael DeHaan
+#
+# 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 .
+
+
+DOCUMENTATION = '''
+---
+module: win_file
+version_added: "1.8"
+short_description: Creates, touches or removes files or directories.
+extends_documentation_fragment: files
+description:
+ - Creates (empty) files, updates file modification stamps of existing files,
+ and can create or remove directories.
+ Unlike M(file), does not modify ownership, permissions or manipulate links.
+notes:
+ - See also M(win_copy), M(win_template), M(copy), M(template), M(assemble)
+requirements: [ ]
+author: Michael DeHaan
+options:
+ path:
+ description:
+ - 'path to the file being managed. Aliases: I(dest), I(name)'
+ required: true
+ default: []
+ aliases: ['dest', 'name']
+ state:
+ description:
+ - If C(directory), all immediate subdirectories will be created if they
+ do not exist.
+ If C(file), the file will NOT be created if it does not exist, see the M(copy)
+ or M(template) module if you want that behavior. If C(absent),
+ directories will be recursively deleted, and files will be removed.
+ If C(touch), an empty file will be created if the c(path) does not
+ exist, while an existing file or directory will receive updated file access and
+ modification times (similar to the way `touch` works from the command line).
+ required: false
+ default: file
+ choices: [ file, directory, touch, absent ]
+'''
+
+EXAMPLES = '''
+# create a file
+- win_file: path=C:\\temp\\foo.conf
+
+# touch a file (creates if not present, updates modification time if present)
+- win_file: path=C:\\temp\\foo.conf state=touch
+
+# remove a file, if present
+- win_file: path=C:\\temp\\foo.conf state=absent
+
+# create directory structure
+- win_file: path=C:\\temp\\folder\\subfolder state=directory
+
+# remove directory structure
+- win_file: path=C:\\temp state=absent
+'''
diff --git a/lib/ansible/modules/windows/win_stat.ps1 b/lib/ansible/modules/windows/win_stat.ps1
index 4e4c55b2aa3..10101a62b30 100644
--- a/lib/ansible/modules/windows/win_stat.ps1
+++ b/lib/ansible/modules/windows/win_stat.ps1
@@ -53,11 +53,9 @@ Else
If ($get_md5 -and $result.stat.exists -and -not $result.stat.isdir)
{
- $sp = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider;
- $fp = [System.IO.File]::Open($path, [System.IO.Filemode]::Open, [System.IO.FileAccess]::Read);
- $hash = [System.BitConverter]::ToString($sp.ComputeHash($fp)).Replace("-", "").ToLower();
- $fp.Dispose();
+ $hash = Get-FileChecksum($path);
Set-Attr $result.stat "md5" $hash;
+ Set-Attr $result.stat "checksum" $hash;
}
Exit-Json $result;
diff --git a/lib/ansible/modules/windows/win_template.py b/lib/ansible/modules/windows/win_template.py
new file mode 100644
index 00000000000..402702f93b2
--- /dev/null
+++ b/lib/ansible/modules/windows/win_template.py
@@ -0,0 +1,52 @@
+# this is a virtual module that is entirely implemented server side
+
+DOCUMENTATION = '''
+---
+module: win_template
+version_added: 1.8
+short_description: Templates a file out to a remote server.
+description:
+ - Templates are processed by the Jinja2 templating language
+ (U(http://jinja.pocoo.org/docs/)) - documentation on the template
+ formatting can be found in the Template Designer Documentation
+ (U(http://jinja.pocoo.org/docs/templates/)).
+ - "Six additional variables can be used in templates: C(ansible_managed)
+ (configurable via the C(defaults) section of C(ansible.cfg)) contains a string
+ which can be used to describe the template name, host, modification time of the
+ template file and the owner uid, C(template_host) contains the node name of
+ the template's machine, C(template_uid) the owner, C(template_path) the
+ absolute path of the template, C(template_fullpath) is the absolute path of the
+ template, and C(template_run_date) is the date that the template was rendered. Note that including
+ a string that uses a date in the template will result in the template being marked 'changed'
+ each time."
+options:
+ src:
+ description:
+ - Path of a Jinja2 formatted template on the local server. This can be a relative or absolute path.
+ required: true
+ default: null
+ aliases: []
+ dest:
+ description:
+ - Location to render the template to on the remote machine.
+ required: true
+ default: null
+ backup:
+ description:
+ - Create a backup file including the timestamp information so you can get
+ the original file back if you somehow clobbered it incorrectly.
+ required: false
+ choices: [ "yes", "no" ]
+ default: "no"
+notes:
+ - "templates are loaded with C(trim_blocks=True)."
+requirements: []
+author: Michael DeHaan
+'''
+
+EXAMPLES = '''
+# Example
+- win_template: src=/mytemplates/foo.j2 dest=C:\\temp\\file.conf
+
+
+'''