Ansible의 Windows 모듈 중에 win_package에서는 특정 URL에서 msi 파일이나 exe 파일을 다운받아서 설치하는 과정까지 한 번에 해주는 기능을 제공한다.
아래와 같이 작성하면 일반적으로 문제가 없을 거라고 생각했다.
...
- name: win_package test
win_package:
path: MSI파일을 받을 URL 입력
arguments:
- /quiet
...
실행해보면 아래와 같은 Fatal 에러가 발생한다.
fatal: [x.x.x.x]: FAILED! => {"changed": false, "msg": "product_id is required when the path is not an MSI or the path is an MSI but not local", "reboot_required": false, "restart_required": false}
MSI파일이 로컬 내에 위치해 있지 않은 경우 product_id를 넣으라는 의미인데..
Windows를 잘 모르는 내 입장에서 product_id를 어떻게 찾아야 할 지 막막해서 구글링을 해본 결과 다음과 같은 링크를 찾게 됨.
powershell을 이용해서 msi 파일의 정보를 뽑아내는데, 그 중에 ProductCode (ansible에서 이야기하는 product_id)를 뽑아낼 수 있다는 내용이다.
https://www.scconfigmgr.com/2014/08/22/how-to-get-msi-file-information-with-powershell/
혹시 위 링크의 정보가 사라질 수 있으므로, Powershell 스크립트와 실행법에 대해 이 글에 복붙을 해보기로 한다.
param(
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[System.IO.FileInfo]$Path,
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[ValidateSet("ProductCode", "ProductVersion", "ProductName", "Manufacturer", "ProductLanguage", "FullVersion")]
[string]$Property
)
Process {
try {
# Read property from MSI database
$WindowsInstaller = New-Object -ComObject WindowsInstaller.Installer
$MSIDatabase = $WindowsInstaller.GetType().InvokeMember("OpenDatabase", "InvokeMethod", $null, $WindowsInstaller, @($Path.FullName, 0))
$Query = "SELECT Value FROM Property WHERE Property = '$($Property)'"
$View = $MSIDatabase.GetType().InvokeMember("OpenView", "InvokeMethod", $null, $MSIDatabase, ($Query))
$View.GetType().InvokeMember("Execute", "InvokeMethod", $null, $View, $null)
$Record = $View.GetType().InvokeMember("Fetch", "InvokeMethod", $null, $View, $null)
$Value = $Record.GetType().InvokeMember("StringData", "GetProperty", $null, $Record, 1)
# Commit database and close view
$MSIDatabase.GetType().InvokeMember("Commit", "InvokeMethod", $null, $MSIDatabase, $null)
$View.GetType().InvokeMember("Close", "InvokeMethod", $null, $View, $null)
$MSIDatabase = $null
$View = $null
# Return the value
return $Value
}
catch {
Write-Warning -Message $_.Exception.Message ; break
}
}
End {
# Run garbage collection and release ComObject
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($WindowsInstaller) | Out-Null
[System.GC]::Collect()
}
실행법은 파워쉘을 연 후에 다음과 같은 커맨드를 입력하면 된다.
.\파일명.ps1 -Path "MSI파일의 경로" -Property ProductCode
위의 powershell 스크립트를 이용해서 win_package 모듈 사용 시 아래와 같이 product_id를 추가해주면 에러가 사라지게 된다.
...
- name: win_package test
win_package:
path: MSI파일을 받을 URL 입력
product_id: Powershell 스크립트를 이용해 얻은 product_id (single quote를 붙여주자.)
arguments:
- /quiet
...
'개발 > Ansible' 카테고리의 다른 글
[Ansible] win_command 이용 시 escape 처리 (0) | 2019.05.22 |
---|---|
[Ansible] Internal Error: this connection module does not support running commands via sudo 해결 (0) | 2019.05.21 |
[Ansible] playbook 작성 시 ansible_facts 활용 (0) | 2019.05.21 |
[Ansible] Windows 환경에서의 Inventory 구성 (0) | 2019.04.12 |
[Ansible] retry 파일 비활성화 (0) | 2019.02.27 |