--- - name: "Установка Mango Talker для другого пользователя через планировщик" hosts: localhost gather_facts: false vars: target_hosts: "{{ target_ips.split(',') | map('trim') | list }}" ansible_connection: winrm ansible_winrm_server_cert_validation: ignore ansible_winrm_transport: ntlm ansible_port: 5985 source_file: "\\\\fs\\alls\\mango-talker-setup.exe" local_dir: "C:\\distr" local_file: "C:\\distr\\mango-talker-setup.exe" install_args: "--silent" target_user_name: "{{ target_user | default('aturenkov') }}" target_user_password: "{{ target_password }}" app_check_path: "C:\\Users\\{{ target_user_name }}\\AppData\\Roaming\\Mango Telecom\\M.TALKER\\application\\mango-talker.exe" tasks: - name: "Создать динамический инвентарь" add_host: name: "{{ item }}" groups: target_group ansible_connection: winrm ansible_winrm_server_cert_validation: ignore ansible_winrm_transport: ntlm ansible_port: 5985 ansible_user: "{{ ansible_user }}" ansible_password: "{{ ansible_password }}" loop: "{{ target_hosts }}" when: target_hosts | length > 0 - name: "Проверить, что есть хосты" fail: msg: "❌ Не указаны IP-адреса для установки" when: target_hosts | length == 0 - name: "Показать информацию" debug: msg: - "Установка будет выполнена на: {{ target_hosts }}" - "Установка от имени: {{ ansible_user.split('@')[0] }}" - "Установка ДЛЯ пользователя: {{ target_user_name }}" - name: "Выполнить установку" hosts: target_group gather_facts: true vars: source_file: "\\\\fs\\alls\\mango-talker-setup.exe" local_dir: "C:\\distr" local_file: "C:\\distr\\mango-talker-setup.exe" install_args: "--silent" target_user_name: "{{ target_user | default('aturenkov') }}" target_user_password: "{{ target_password }}" app_check_path: "C:\\Users\\{{ target_user_name }}\\AppData\\Roaming\\Mango Telecom\\M.TALKER\\application\\mango-talker.exe" tasks: - name: "1. Проверить доступность" ansible.windows.win_ping: - name: "2. Создать папку C:\\distr" ansible.windows.win_file: path: "{{ local_dir }}" state: directory - name: "3. Скопировать файл" ansible.windows.win_shell: | $source = "{{ source_file }}" $dest = "{{ local_file }}" $username = "{{ ansible_user }}" $password = "{{ ansible_password }}" $secpass = ConvertTo-SecureString $password -AsPlainText -Force $cred = New-Object System.Management.Automation.PSCredential($username, $secpass) $drive = New-PSDrive -Name "TempDrive" -PSProvider FileSystem -Root (Split-Path $source) -Credential $cred Copy-Item -Path $source -Destination $dest -Force Remove-PSDrive -Name "TempDrive" register: copy_result ignore_errors: true - name: "4. Проверить файл" ansible.windows.win_stat: path: "{{ local_file }}" register: local_stat - name: "5. Остановить, если файл не скопирован" fail: msg: "❌ Не удалось скопировать файл" when: not local_stat.stat.exists - name: "6. Запустить установку через планировщик задач" ansible.windows.win_shell: | $domain = "{{ ansible_user.split('@')[1] }}" $user = "{{ target_user_name }}" $password = "{{ target_user_password }}" $taskName = "MangoTalkerInstall_$(Get-Date -Format 'yyyyMMddHHmmss')" # Создаём действие $action = New-ScheduledTaskAction -Execute "{{ local_file }}" -Argument "{{ install_args }}" -WorkingDirectory "{{ local_dir }}" # Создаём триггер (однократно) $trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).AddMinutes(1) # Создаём principal с паролем $principal = New-ScheduledTaskPrincipal -UserId "$domain\\$user" -LogonType Password -RunLevel Highest # Создаём настройки $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable # Регистрируем задачу Register-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger -Principal $principal -Settings $settings -Password $password -Force # Ждём 5 секунд и запускаем задачу Start-Sleep -Seconds 5 Start-ScheduledTask -TaskName $taskName # Ждём завершения (максимум 5 минут) $timeout = 300 $elapsed = 0 $exitCode = $null do { $task = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue if ($task) { $taskInfo = $task | Get-ScheduledTaskInfo if ($taskInfo.LastTaskResult -ne $null -and $taskInfo.LastTaskResult -ne 0) { $exitCode = $taskInfo.LastTaskResult break } # Проверяем, завершилась ли задача $taskState = (Get-ScheduledTask -TaskName $taskName).State if ($taskState -eq "Ready") { $exitCode = $taskInfo.LastTaskResult break } } Start-Sleep -Seconds 5 $elapsed += 5 } while ($elapsed -lt $timeout) # Если таймаут if ($exitCode -eq $null) { $exitCode = 0 } # Удаляем задачу Unregister-ScheduledTask -TaskName $taskName -Confirm:$false Write-Host "Exit code: $exitCode" exit $exitCode register: install_result failed_when: install_result.rc not in [0, 3010] changed_when: install_result.rc == 0 - name: "7. Подождать завершения" ansible.windows.win_shell: | Start-Sleep -Seconds 10 when: install_result.rc == 0 - name: "8. Проверить установку для пользователя {{ target_user_name }}" ansible.windows.win_stat: path: "{{ app_check_path }}" register: app_check - name: "9. Поиск установки у всех пользователей" ansible.windows.win_shell: | Get-ChildItem -Path "C:\\Users" -Directory -ErrorAction SilentlyContinue | ForEach-Object { $path = Join-Path $_.FullName "AppData\\Roaming\\Mango Telecom\\M.TALKER\\application\\mango-talker.exe" if (Test-Path $path) { Write-Host $_.Name } } register: found_users ignore_errors: true when: not app_check.stat.exists - name: "10. Результат" debug: msg: - "==========================================" - "✅ Хост: {{ inventory_hostname }}" - "👤 Установка от: {{ ansible_user.split('@')[0] }}" - "👤 Установка для: {{ target_user_name }}" - "📊 Код возврата: {{ install_result.rc }}" - "📁 Приложение установлено для {{ target_user_name }}: {{ app_check.stat.exists | default(false) }}" - "📁 Найдено у других: {{ found_users.stdout_lines | default('Нет') }}" - "==========================================" - name: "11. Удалить установщик" ansible.windows.win_shell: | Start-Sleep -Seconds 5 Remove-Item "{{ local_file }}" -Force -ErrorAction SilentlyContinue when: install_result.rc == 0 ignore_errors: true - name: "12. Перезагрузить, если требуется" ansible.windows.win_reboot: reboot_timeout: 600 post_reboot_delay: 30 when: - install_result is defined - install_result.rc == 3010