2014-09-26 01:01:01 +00:00
#!powershell
# This file is part of Ansible
2017-11-16 00:04:03 +00:00
# Copyright (c) 2017 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# Requires -Module Ansible.ModuleUtils.Legacy
# Requires -Module Ansible.ModuleUtils.FileUtil
2017-12-12 04:07:56 +00:00
# Requires -Module Ansible.ModuleUtils.LinkUtil
2014-09-26 01:01:01 +00:00
2017-12-12 04:07:56 +00:00
function DateTo-Timestamp($start_date , $end_date ) {
if ( $start_date -and $end_date ) {
2017-02-24 06:58:51 +00:00
return ( New-TimeSpan -Start $start_date -End $end_date ) . TotalSeconds
2016-04-20 19:26:27 +00:00
}
2015-06-05 13:35:26 +00:00
}
2017-02-24 06:58:51 +00:00
$params = Parse-Args $args -supports_check_mode $true
2014-09-26 01:01:01 +00:00
2017-02-24 06:58:51 +00:00
$path = Get-AnsibleParam -obj $params -name " path " -type " path " -failifempty $true -aliases " dest " , " name "
2017-11-27 23:58:55 +00:00
$get_md5 = Get-AnsibleParam -obj $params -name " get_md5 " -type " bool " -default $false
2017-02-24 06:58:51 +00:00
$get_checksum = Get-AnsibleParam -obj $params -name " get_checksum " -type " bool " -default $true
$checksum_algorithm = Get-AnsibleParam -obj $params -name " checksum_algorithm " -type " str " -default " sha1 " -validateset " md5 " , " sha1 " , " sha256 " , " sha384 " , " sha512 "
$result = @ {
2014-09-26 01:01:01 +00:00
changed = $false
2017-08-04 03:55:58 +00:00
stat = @ {
exists = $false
}
2017-04-03 18:38:34 +00:00
}
2014-09-26 01:01:01 +00:00
2017-11-27 23:58:55 +00:00
# get_md5 will be an undocumented option in 2.9 to be removed at a later
# date if possible (3.0+)
if ( Get-Member -inputobject $params -name " get_md5 " ) {
Add-DepreactionWarning -obj $result -message " get_md5 has been deprecated along with the md5 return value, use get_checksum=True and checksum_algorithm=md5 instead " -version 2.9
2017-02-24 06:58:51 +00:00
}
2018-01-17 04:16:34 +00:00
$info = Get-AnsibleItem -Path $path -ErrorAction SilentlyContinue
2017-12-12 04:07:56 +00:00
If ( $info -ne $null ) {
2017-02-24 06:58:51 +00:00
$epoch_date = Get-Date -Date " 01/01/1970 "
2017-01-27 22:51:12 +00:00
$attributes = @ ( )
foreach ( $attribute in ( $info . Attributes -split ',' ) ) {
2017-04-03 18:38:34 +00:00
$attributes + = $attribute . Trim ( )
2017-01-27 22:51:12 +00:00
}
2017-12-12 04:07:56 +00:00
# default values that are always set, specific values are set below this
# but are kept commented for easier readability
$stat = @ {
exists = $true
attributes = $info . Attributes . ToString ( )
isarchive = ( $attributes -contains " Archive " )
isdir = $false
ishidden = ( $attributes -contains " Hidden " )
isjunction = $false
islnk = $false
isreadonly = ( $attributes -contains " ReadOnly " )
isreg = $false
isshared = $false
nlink = 1 # Number of links to the file (hard links), overriden below if islnk
# lnk_target = islnk or isjunction Target of the symlink. Note that relative paths remain relative
# lnk_source = islnk os isjunction Target of the symlink normalized for the remote filesystem
hlnk_targets = @ ( )
creationtime = ( DateTo-Timestamp -start_date $epoch_date -end_date $info . CreationTime )
lastaccesstime = ( DateTo-Timestamp -start_date $epoch_date -end_date $info . LastAccessTime )
lastwritetime = ( DateTo-Timestamp -start_date $epoch_date -end_date $info . LastWriteTime )
# size = a file and directory - calculated below
path = $info . FullName
filename = $info . Name
# extension = a file
# owner = set outsite this dict in case it fails
# sharename = a directory and isshared is True
# checksum = a file and get_checksum: True
# md5 = a file and get_md5: True
2017-02-24 06:58:51 +00:00
}
2017-12-12 04:07:56 +00:00
$stat . owner = $info . GetAccessControl ( ) . Owner
# values that are set according to the type of file
2018-01-17 04:16:34 +00:00
if ( $info . Attributes . HasFlag ( [ System.IO.FileAttributes ] :: Directory ) ) {
2017-12-12 04:07:56 +00:00
$stat . isdir = $true
$share_info = Get-WmiObject -Class Win32_Share -Filter " Path=' $( $stat . path -replace '\\' , '\\' ) ' "
if ( $share_info -ne $null ) {
$stat . isshared = $true
$stat . sharename = $share_info . Name
2017-01-27 22:51:12 +00:00
}
2018-01-17 04:16:34 +00:00
try {
$size = 0
foreach ( $file in $info . EnumerateFiles ( " * " , [ System.IO.SearchOption ] :: AllDirectories ) ) {
$size + = $file . Length
}
$stat . size = $size
} catch {
2017-12-12 04:07:56 +00:00
$stat . size = 0
2017-01-27 22:51:12 +00:00
}
2017-12-12 04:07:56 +00:00
} else {
$stat . extension = $info . Extension
$stat . isreg = $true
$stat . size = $info . Length
2017-01-27 22:51:12 +00:00
2017-12-12 04:07:56 +00:00
if ( $get_md5 ) {
2017-08-07 02:04:42 +00:00
try {
2017-12-12 04:07:56 +00:00
$stat . md5 = Get-FileChecksum -path $path -algorithm " md5 "
2017-08-07 02:04:42 +00:00
} catch {
2017-11-27 23:58:55 +00:00
Fail-Json -obj $result -message " failed to get MD5 hash of file, remove get_md5 to ignore this error: $( $_ . Exception . Message ) "
2017-08-07 02:04:42 +00:00
}
2017-01-27 22:51:12 +00:00
}
2017-12-12 04:07:56 +00:00
if ( $get_checksum ) {
2017-08-07 02:04:42 +00:00
try {
2017-12-12 04:07:56 +00:00
$stat . checksum = Get-FileChecksum -path $path -algorithm $checksum_algorithm
2017-08-07 02:04:42 +00:00
} catch {
Fail-Json -obj $result -message " failed to get hash of file, set get_checksum to False to ignore this error: $( $_ . Exception . Message ) "
}
2017-01-27 22:51:12 +00:00
}
2014-09-26 01:01:01 +00:00
}
2017-12-12 04:07:56 +00:00
# Get symbolic link, junction point, hard link info
Load-LinkUtils
try {
$link_info = Get-Link -link_path $info . FullName
} catch {
Add-Warning -obj $result -message " Failed to check/get link info for file: $( $_ . Exception . Message ) "
}
if ( $link_info -ne $null ) {
switch ( $link_info . Type ) {
" SymbolicLink " {
$stat . islnk = $true
$stat . isreg = $false
$stat . lnk_target = $link_info . TargetPath
$stat . lnk_source = $link_info . AbsolutePath
break
}
" JunctionPoint " {
$stat . isjunction = $true
$stat . isreg = $false
$stat . lnk_target = $link_info . TargetPath
$stat . lnk_source = $link_info . AbsolutePath
break
}
" HardLink " {
$stat . lnk_type = " hard "
$stat . nlink = $link_info . HardTargets . Count
# remove current path from the targets
$hlnk_targets = $link_info . HardTargets | Where-Object { $_ -ne $stat . path }
$stat . hlnk_targets = @ ( $hlnk_targets )
break
}
}
}
$result . stat = $stat
2014-09-26 01:01:01 +00:00
}
2017-04-03 18:38:34 +00:00
Exit-Json $result