使用Ansible在Windows Guest虚拟机上映射网络驱动器 [英] Mapping a Network Drive on a Windows Guest using Ansible

查看:169
本文介绍了使用Ansible在Windows Guest虚拟机上映射网络驱动器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Ansible在Windows guest虚拟机上自动化一些任务,并且遇到映射网络驱动器的一些问题.

我要做的是映射驱动器,对其进行一些操作(在这里的示例中,我只是尝试列出文件),然后取消映射.

当我运行Ansible时,输出表明共享驱动器已成功映射,但是列出文件并取消映射都导致错误,指出该驱动器不存在. ("名称为'K'的驱动器不存在.")

运行Ansible后登录Windows来宾时,驱动器已映射.

如果我在登录访客时运行Ansible,则只有在我注销并再次登录后,驱动器才可见.我用于安装驱动器的脚本还在调试时在客户机上创建了一个文件,即使我登录后该文件也确实会显示.我无需注销并再次登录即可使其可见.因此,似乎只有网络驱动器映射需要注销和登录才能生效.

我还尝试了"net use"来映射驱动器,结果是相同的.

我的Ansible剧本看起来像这样. (我省去了一些敏感的部分.)

  tasks:
      - name: Mount share
        script: scripts/mount.ps1 {{ share }}
      - name: Test
        script: scripts/test.ps1
        register: test
      - name: Test stdout
        debug: msg="{{ test.stdout }}"
      - name: Test stderr
        debug: msg="{{ test.stderr }}"
      - name: Umount share
        script: scripts/umount.ps1

mount.ps1.

param([string]$share)
$share | Out-File c:\ansible-test\debug.txt
New-PSDrive -Name "K" -PSProvider FileSystem -Root "$share" -Persist

test.ps1

Get-ChildItem K:\

umount.ps1

Remove-PSDrive "K"

解决方案

不幸的是,这是Ansible与Windows进行通信的方式.我遇到过类似的问题,其中命令和软件包的安装无法按预期进行.

当Ansible通过WinRM与Windows框通信时,它将启动一个批处理连接,而不是一个完整的会话.映射驱动器是需要一个完整会话的那些任务之一,但是Ansible运行的每个任务都会创建它自己的批处理连接,因此当您断开驱动器的映射而对其进行映射时,您会失去该映射,因为也没有实际用户注册它

这里唯一的解决方法是创建一个.ps1来映射驱动器,然后使用Invoke-Command.

这是我的工作范围:

- name: map drive and run a task
  script: files/mapdrive.ps1 -network_password "{{ network_password }" -command_to_run "{ Copy-Item Y:\file_to_copy.txt C:\Some\Were }"

我的ps1看起来像这样:

param(
  $network_password,
  $command_to_run
)
$PWord = ConvertTo-SecureString $network_password -AsPlainText -Force
$myCreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "domain\user",$PWord
New-PSDrive -Name "Y" -PSProvider "FileSystem" -Root "\\remoteserver\share" -Credential $myCreds
Invoke-Command -ScriptBlock $command_to_run

显然,Ansible的未来发行版将采用一种成为"形式,这将允许这些持久性会话使这类任务变得容易得多,但这可能要等上几年,并且至少要发行2或3个发行版./p>

I'm trying to automate some tasks on Windows guests using Ansible, and I'm running into some issues mapping a network drive.

What I'm trying to do is map the drive, do something to it (in my example here, I just try to list the files), and then unmap it.

When I run Ansible, the output suggests that the shared drive was mapped successfully, but listing the files and unmapping both result in errors that state that the drive doesn't exist. ("A drive with the name 'K' does not exist.")

When I login to the Windows guest after running Ansible, the drive is mapped.

If I run Ansible while I am logged in the guest, the drive only becomes visible after I logout and log back in again. The script I use to mount the drive also creates a file on the guest for debugging purposes, and the file does appear even when I'm logged in. I don't need to logout and back in again for it to become visible. So it seems only the network drive mapping requires a logout and login to take effect.

I also tried "net use" to map the drive, and the results were the same.

My Ansible playbook looks like this. (I have left out some sensitive parts.)

  tasks:
      - name: Mount share
        script: scripts/mount.ps1 {{ share }}
      - name: Test
        script: scripts/test.ps1
        register: test
      - name: Test stdout
        debug: msg="{{ test.stdout }}"
      - name: Test stderr
        debug: msg="{{ test.stderr }}"
      - name: Umount share
        script: scripts/umount.ps1

mount.ps1.

param([string]$share)
$share | Out-File c:\ansible-test\debug.txt
New-PSDrive -Name "K" -PSProvider FileSystem -Root "$share" -Persist

test.ps1

Get-ChildItem K:\

umount.ps1

Remove-PSDrive "K"

解决方案

Unfortunately this is down the way Ansible communicates with windows. I've had similar issues where commands and package installation didn't work as expected.

When Ansible communicates over WinRM to the windows box it initiates a batch connection, not a full session. Mapping drives is one of those tasks that requires a full session, but each task that Ansible runs creates it's own batch connection so when you map a drive as soon as it disconnects, you loose that mapping because there is no actual user to register it too.

The only work around you have here is to create a .ps1 to map the drive then use Invoke-Command.

Here is my work around :

- name: map drive and run a task
  script: files/mapdrive.ps1 -network_password "{{ network_password }" -command_to_run "{ Copy-Item Y:\file_to_copy.txt C:\Some\Were }"

and my ps1 looks like this :

param(
  $network_password,
  $command_to_run
)
$PWord = ConvertTo-SecureString $network_password -AsPlainText -Force
$myCreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "domain\user",$PWord
New-PSDrive -Name "Y" -PSProvider "FileSystem" -Root "\\remoteserver\share" -Credential $myCreds
Invoke-Command -ScriptBlock $command_to_run

Apparently future releases of Ansible will employ a form of "become" which will allow these persistent sessions making this type of task a lot easier, but that could be a couple of years away and at least 2 or 3 releases ahead.

这篇关于使用Ansible在Windows Guest虚拟机上映射网络驱动器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆