check if a (file or directory) symbolic links exists on a windows file system with the help of win_file

1,085 views
Skip to first unread message

ishan jain

unread,
Mar 16, 2016, 5:56:05 AM3/16/16
to Ansible Project
I am trying to gather custom facts for a windows 2012 R2 server while avoiding to write powershell scripts. win_stat is something that can apparently be very useful to me but i am getting confused about its exact behavior.
I have a file structure like this:

E:\
E:\link1
E:\folder\link2
E:\folder\link2\some_dir\link3.jar

Link1 and 2 are directory symbolic links and link3 is a file symbolic link and is currently active in a java process. I am trying to check if these links exists or not via this kink of script:

---
- hosts: windows
  tasks:
    - name: check symbolic links
      win_stat: path=E:\link1
      register: result
      ignore_errors: yes
      
    - debug: msg="{{result}}"

I expect to check something like result.stats.attributes == ReparsePoint to see if this indeed is a symlink. But i am getting some varied results when i execute the script for the above folder structure which are listed below. I will try to mark my questions with a number.

1) First question, is this a good solution to check for directory n file symbolic link or is there a better one ?

2) Problem with the reporting of directory symbolic link

win_stat: path=E:\link1 
or 
win_stat: path=E:\link1\  
or
win_stat: path="E:\link1"

These statements, when the symlink is at the root level of a drive, gives me an error that this link does not exist while it is there:

 "msg": {
        "changed": false,
        "stat": {
            "exists": false
        }
    }

When i change it to:

win_stat: path="E:\\test"

It works perfectly fine with output:

 "msg": {
        "changed": false,
        "stat": {
            "attributes": "Directory, ReparsePoint",
            "creationtime": 1458045768.6789002,
            "exists": true,
            "extension": "",
            "isdir": true,
            "lastaccesstime": 1458045768.6789002,
            "lastwritetime": 1458045768.6789002,
            "owner": "BUILTIN\\Administrators"
        }
    }


While the similar statements for the directory symlink inside a folder

win_stat: path=E:\folder\link2
or
win_stat: path="E:\folder\link2"
or
win_stat: path="E:\\folder\\link2"
or
win_stat: path=E:\\folder\\link2
or
win_stat: path=E:\folder\\link2 (notice only one \\)

They all seems to be working fine. So what exactly is the syntax here so that it will work at all levels ?

3) Problems with file symbolic links that are in use 

For the statements:

win_stat: path=E:\folder\link2\some_dir\link3.jar

I get the following error because the file is actively in use:

"msg": {
        "changed": false,
        "exception": "At C:\\Users\\Ishan\\AppData\\Local\\Temp\\ansible-tmp-1458122016.24-112690440585191\\win_stat.ps1:231 char:9\r\n+         $fp = [System.IO.File]::Open($path, [System.IO.Filemode]::Open, [System. ...\r\n+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
        "failed": true,
        "msg": "Exception calling \"Open\" with \"3\" argument(s): \"The process cannot access the file 'E:\\folder\\link2\\some_dir\\link3.jar' because it is being used by another process.\""
    }


How can i make sure that the file link in use can at least be read so that i can know more about it ?

ishan jain

unread,
Mar 16, 2016, 6:01:39 AM3/16/16
to Ansible Project
4) I have a file symbolic link E:\folder\link.exe pointing to an exe file and this link is not actively in use by a process. So when i use

 win_stat: path="E:\folder\link.exe"

i get an answer that it does not exist.

 "msg": {
        "changed": false,
        "stat": {
            "exists": false
        }
    }


But when i use:

 win_stat: path="E:\\folder\\link.exe"

I get a proper result.
Probably related to the above questions, but what is the proper syntax to specify a path here ?

J Hawkesworth

unread,
Mar 17, 2016, 6:07:15 AM3/17/16
to Ansible Project
I don't have any experience of using symlinks on windows, but my advice for construction windows paths (assuming you are using ansible 2.0 or later) is...

1/ If you need to double quote your path names, then always use double backslash for the path separator

So 
win_stat: "path=E:\\folder\\link.exe"

2/ I would also advise using the 'yaml style' way of supplying module parameters, rather than using the key=value style, if only because 'yaml style' makes you put 1 parameter per line, which often means you don't need to use any quotes at all for hard-coded windows paths:

So like this (yaml style parameter)
win_stat:
   path: E:\folder\link.exe

Hope this helps,

Jon

ishan jain

unread,
Mar 17, 2016, 6:14:32 AM3/17/16
to Ansible Project
Thanks for the answer. I figured i should always quote and use double slashes to be on safe side.
I am still stuck with problem number 3. can you help me with that  ?
Reply all
Reply to author
Forward
0 new messages