#!powershell # 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 #Requires -Module Ansible.ModuleUtils.LinkUtil function DateTo-Timestamp($start_date, $end_date) { if ($start_date -and $end_date) { return (New-TimeSpan -Start $start_date -End $end_date).TotalSeconds } } $params = Parse-Args $args -supports_check_mode $true $path = Get-AnsibleParam -obj $params -name "path" -type "path" -failifempty $true -aliases "dest","name" $get_md5 = Get-AnsibleParam -obj $params -name "get_md5" -type "bool" -default $false $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 = @{ changed = $false stat = @{ exists = $false } } # 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 } $info = Get-AnsibleItem -Path $path -ErrorAction SilentlyContinue If ($info -ne $null) { $epoch_date = Get-Date -Date "01/01/1970" $attributes = @() foreach ($attribute in ($info.Attributes -split ',')) { $attributes += $attribute.Trim() } # 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 } $stat.owner = $info.GetAccessControl().Owner # values that are set according to the type of file if ($info.Attributes.HasFlag([System.IO.FileAttributes]::Directory)) { $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 } try { $size = 0 foreach ($file in $info.EnumerateFiles("*", [System.IO.SearchOption]::AllDirectories)) { $size += $file.Length } $stat.size = $size } catch { $stat.size = 0 } } else { $stat.extension = $info.Extension $stat.isreg = $true $stat.size = $info.Length if ($get_md5) { try { $stat.md5 = Get-FileChecksum -path $path -algorithm "md5" } catch { Fail-Json -obj $result -message "failed to get MD5 hash of file, remove get_md5 to ignore this error: $($_.Exception.Message)" } } if ($get_checksum) { try { $stat.checksum = Get-FileChecksum -path $path -algorithm $checksum_algorithm } catch { Fail-Json -obj $result -message "failed to get hash of file, set get_checksum to False to ignore this error: $($_.Exception.Message)" } } } # 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 } Exit-Json $result