Menu

3 Apr 2026

πŸ” WAS Service Restart Using WinRM over HTTPS (5986) on Azure DevOps

WAS Service Restart Using WinRM over HTTPS (5986) on Azure DevOps

This section explains the prerequisites, end‑to‑end pipeline flow, and a real‑world production use case for restarting Windows services securely using Azure DevOps and WinRM over HTTPS (5986).


πŸ“š Table of Contents


πŸ“Œ Prerequisites

πŸ”· Azure DevOps

  • Azure DevOps project and pipeline created
  • Manual trigger enabled for UAT / PROD
  • Pipeline parameters (START / STOP / RESTART)
  • Secrets stored in Variable Groups

πŸͺŸ Windows DevOps Agent

  • Self‑hosted Windows agent installed
  • Agent pool access configured
  • Outbound connectivity to target servers
  • PowerShellOnTargetMachines available

πŸ–₯️ Target Windows Server

  • WinRM enabled and running , Refrence link ( Secure WinRM Configuration Guide )
  • WinRM configured over HTTPS (5986)
  • CA SSL certificate installed
  • 5986 allowed in Firewall / NSG
  • Service credentials available

⬆️ Back to Top


πŸ”„ Pipeline Flow: Service Restart Using WinRM over Secure Port (5986)

┌──────────────────────────────────────────────┐
│           Azure DevOps Pipeline              │
│          (Manual Trigger)                    │
└──────────────────────────────────────────────┘
                    │
                    ▼
┌──────────────────────────────────────────────┐
│      Parameter Selection (OPERATION)         │
│  ─ START_WAS                                 │
│  ─ STOP_WAS                                  │
│  ─ RESTART_WAS                               │
└──────────────────────────────────────────────┘
                    │
                    ▼
┌──────────────────────────────────────────────┐
│   Azure DevOps Windows Agent                 │
│   Pool: AppOps-Win-AgentPool                 │
│   Secrets: WinRM-Secrets (secure)            │
└──────────────────────────────────────────────┘
                    │
                    ▼
┌──────────────────────────────────────────────┐
│      Secure WinRM Session Initiated          │
│  ─ Protocol   : HTTPS                        │
│  ─ Port       : 5986                         │
│  ─ Auth       : Negotiate                    │
│  ─ SSL Cert   : CA Enterprise Certificate    │
└──────────────────────────────────────────────┘
                    │
                    ▼
┌──────────────────────────────────────────────┐
│        Target Windows Server                 │
│        WebSphere Application Server          │
└──────────────────────────────────────────────┘
                    │
                    ▼
┌──────────────────────────────────────────────┐
│   PowerShellOnTargetMachines@                │
│   Remote Session via WinRM                   │
└──────────────────────────────────────────────┘
                    │
                    ▼
┌──────────────────────────────────────────────┐
│        Operation Execution Logic             │
└──────────────────────────────────────────────┘
        │                 │                 │
        ▼                 ▼                 ▼
┌───────────────┐ ┌────────────────┐ ┌──────────────────────┐
│  START_WAS    │ │   STOP_WAS     │ │    RESTART_WAS       │
│ Start Service │ │ Stop Service   │ │ Stop → Cleanup       │
│ Validate Run  │ │ Validate Stop  │ │ Start → Validate     │
└───────────────┘ └────────────────┘ └──────────────────────┘
                    │
                    ▼
┌──────────────────────────────────────────────┐
│   Logs Printed to Azure DevOps Console       │
│  ─ Pre/Post Service Status                   │
│  ─ Cleanup Verification                      │
│  ─ Immediate Failure on Error                │
└──────────────────────────────────────────────┘
                    │
                    ▼
┌──────────────────────────────────────────────┐
│            Pipeline Result                   │
│   SUCCESS → Safe Completion                  │
│   FAILURE → Clear Error Output               │
└──────────────────────────────────────────────┘

⬆️ Back to Top


WAS Service Restart Using WinRM over HTTPS (5986) on Azure DevOps

πŸ“Œ Code Example Pipeline (Azure DevOps YAML)

Below is a working Azure DevOps YAML pipeline example to START / STOP / RESTART an IBM WebSphere (WAS) Windows service using WinRM over HTTPS (5986). Secrets are stored securely in a Variable Group.


# ============================================================
# PIPELINE: WinRM (HTTPS 5986) – START / STOP / RESTART WAS Service
# TARGET  : 172.23.XX.XX
# SERVICE : IBMWAS85Service - AppNode1
# AGENT   : AppOps-Win-AgentPool
# SECRETS : Variable Group "WinRM-Secrets" (expects remotePassword)
# ============================================================

# Manual run only (no CI trigger)
trigger: none

# Azure DevOps agent pool (Windows agent recommended for this task)
pool:
  name: AppOps-Win-AgentPool

# Runtime choice: which action to perform
parameters:
  - name: OPERATION
    displayName: "Select RESTART-APPNODE1 operation"
    type: string
    default: RESTART_WAS
    values:
      - START_WAS
      - STOP_WAS
      - RESTART_WAS

# Variables + Secret Variable Group
variables:
  # Secret variable group should contain:
  # - remotePassword (secret)
  - group: WinRM-Secrets

  # Target server (WinRM endpoint)
  - name: remoteHost
    value: "172.23.XX.XX"

  # WinRM HTTPS port
  - name: httpsPort
    value: "5986"

  # WAS Windows Service name (must match service name on target)
  - name: wasServiceName
    value: "IBMWAS85Service - AppNode1"

  # PSSession options (relaxed cert validation for internal IP use cases)
  # NOTE: For PROD hardening, remove Skip* flags and use proper cert CN/SAN.
  - name: pssOptions
    value: "-SkipCNCheck -SkipCACheck -SkipRevocationCheck -IdleTimeout 7200000 -OperationTimeout 0 -OutputBufferingMode Block"

steps:
  # ============================================================
  # START WAS
  # ============================================================
  # Runs ONLY when OPERATION = START_WAS
  - ${{ if eq(parameters.OPERATION, 'START_WAS') }}:
      - task: PowerShellOnTargetMachines@3
        displayName: "WAS START (Windows Service)"
        inputs:
          # Remote host + WinRM port
          Machines: "$(remoteHost):$(httpsPort)"

          # Local admin user on target (change to domain user if needed)
          UserName: ".\\username"

          # Password from secret variable group (WinRM-Secrets)
          UserPassword: "$(remotePassword)"

          # WinRM protocol
          CommunicationProtocol: "Https"

          # Default authentication (Negotiate)
          AuthenticationMechanism: "Default"

          # Session options passed to New-PSSessionOption on agent side
          NewPsSessionOptionArguments: "$(pssOptions)"

          # Fail fast on any error
          ErrorActionPreference: "Stop"
          FailOnScriptError: true

          # Single target execution
          RunPowershellInParallel: false

          # Inline PowerShell executed on target
          ScriptType: "Inline"
          InlineScript: |
            # Stop immediately if any command fails
            $ErrorActionPreference = 'Stop'

            # Service name from pipeline variable
            $service = '$(wasServiceName)'

            Write-Host "============================================================"
            Write-Host "ACTION  : START_WAS"
            Write-Host "SERVICE : $service"
            Write-Host "HOST    : $env:COMPUTERNAME"
            Write-Host "USER    : $(whoami)"
            Write-Host "============================================================"

            Write-Host "Starting service: $service"
            Start-Service -Name $service
            Start-Sleep -Seconds 5

            $status = (Get-Service -Name $service).Status
            Write-Host "Current service status: $status"

            if ($status -ne 'Running') {
              throw "WAS service failed to start"
            }

            Write-Host "RESULT: WAS service is RUNNING"

  # ============================================================
  # STOP WAS
  # ============================================================
  # Runs ONLY when OPERATION = STOP_WAS
  - ${{ if eq(parameters.OPERATION, 'STOP_WAS') }}:
      - task: PowerShellOnTargetMachines@3
        displayName: "WAS STOP (Service + Cleanup)"
        inputs:
          Machines: "$(remoteHost):$(httpsPort)"
          UserName: ".\\username"
          UserPassword: "$(remotePassword)"
          CommunicationProtocol: "Https"
          AuthenticationMechanism: "Default"
          NewPsSessionOptionArguments: "$(pssOptions)"
          ErrorActionPreference: "Stop"
          RunPowershellInParallel: false
          FailOnScriptError: true
          ScriptType: "Inline"
          InlineScript: |
            $ErrorActionPreference = 'Stop'

            $service     = '$(wasServiceName)'
            $profilePath = 'D:\IBM\WebSphere\AppServer\profiles\AppSrv02'
            $wstempPath  = Join-Path $profilePath 'wstemp'
            $tempPath    = Join-Path $profilePath 'temp'

            Write-Host "============================================================"
            Write-Host "ACTION  : STOP_WAS"
            Write-Host "SERVICE : $service"
            Write-Host "PROFILE : $profilePath"
            Write-Host "HOST    : $env:COMPUTERNAME"
            Write-Host "============================================================"

            Write-Host "Stopping service: $service"
            Stop-Service -Name $service -Force
            Start-Sleep -Seconds 5

            $status = (Get-Service -Name $service).Status
            Write-Host "Current service status: $status"

            if ($status -ne 'Stopped') {
              throw "WAS service failed to stop"
            }

            # Timestamped rename = safe backup (NO deletion)
            $timestamp = Get-Date -Format "yyyyMMdd_HHmmss"

            if (Test-Path $wstempPath) {
              Write-Host "Renaming wstemp -> wstemp_$timestamp"
              Rename-Item $wstempPath "wstemp_$timestamp" -Force
            } else {
              Write-Host "INFO: wstemp not found: $wstempPath"
            }

            if (Test-Path $tempPath) {
              Write-Host "Renaming temp   -> temp_$timestamp"
              Rename-Item $tempPath "temp_$timestamp" -Force
            } else {
              Write-Host "INFO: temp not found: $tempPath"
            }

            # Cleanup scripts (standard WAS maintenance)
            Write-Host "Running: clearClassCache.bat"
            & "$profilePath\bin\clearClassCache.bat"

            Write-Host "Running: osgiCfgInit.bat"
            & "$profilePath\bin\osgiCfgInit.bat"

            Write-Host "RESULT: STOP completed successfully (service stopped + cleanup done)"

  # ============================================================
  # RESTART WAS
  # ============================================================
  # Runs ONLY when OPERATION = RESTART_WAS
  - ${{ if eq(parameters.OPERATION, 'RESTART_WAS') }}:
      - task: PowerShellOnTargetMachines@3
        displayName: "WAS RESTART (Stop + Cleanup + Start)"
        inputs:
          Machines: "$(remoteHost):$(httpsPort)"
          UserName: ".\\username"
          UserPassword: "$(remotePassword)"
          CommunicationProtocol: "Https"
          AuthenticationMechanism: "Default"
          NewPsSessionOptionArguments: "$(pssOptions)"
          ErrorActionPreference: "Stop"
          RunPowershellInParallel: false
          FailOnScriptError: true
          ScriptType: "Inline"
          InlineScript: |
            $ErrorActionPreference = 'Stop'

            $service     = '$(wasServiceName)'
            $profilePath = 'D:\IBM\WebSphere\AppServer\profiles\AppSrv02'
            $wstempPath  = Join-Path $profilePath 'wstemp'
            $tempPath    = Join-Path $profilePath 'temp'

            Write-Host "============================================================"
            Write-Host "ACTION  : RESTART_WAS"
            Write-Host "SERVICE : $service"
            Write-Host "PROFILE : $profilePath"
            Write-Host "HOST    : $env:COMPUTERNAME"
            Write-Host "============================================================"

            # -------- 1) STOP --------
            Write-Host "Stopping service: $service"
            Stop-Service -Name $service -Force
            Start-Sleep -Seconds 5

            $status = (Get-Service -Name $service).Status
            Write-Host "Status after STOP: $status"

            if ($status -ne 'Stopped') {
              throw "WAS service failed to stop"
            }

            # -------- 2) CLEANUP (NO delete, only rename) --------
            $timestamp = Get-Date -Format "yyyyMMdd_HHmmss"

            if (Test-Path $wstempPath) {
              Write-Host "Renaming wstemp -> wstemp_$timestamp"
              Rename-Item $wstempPath "wstemp_$timestamp" -Force
            } else {
              Write-Host "INFO: wstemp not found: $wstempPath"
            }

            if (Test-Path $tempPath) {
              Write-Host "Renaming temp   -> temp_$timestamp"
              Rename-Item $tempPath "temp_$timestamp" -Force
            } else {
              Write-Host "INFO: temp not found: $tempPath"
            }

            Write-Host "Running: clearClassCache.bat"
            & "$profilePath\bin\clearClassCache.bat"

            Write-Host "Running: osgiCfgInit.bat"
            & "$profilePath\bin\osgiCfgInit.bat"

            # -------- 3) START --------
            Write-Host "Starting service: $service"
            Start-Service -Name $service
            Start-Sleep -Seconds 8

            $status = (Get-Service -Name $service).Status
            Write-Host "Status after START: $status"

            if ($status -ne 'Running') {
              throw "WAS service failed to restart"
            }

            Write-Host "RESULT: WAS restarted successfully"

✅ Notes

  • Manual run only: trigger: none
  • Secure channel: WinRM over HTTPS 5986
  • Safe cleanup: No delete, only rename (timestamped)
  • Audit logs: printed directly to Azure DevOps console