Menu

Showing posts with label DevOps Automation. Show all posts
Showing posts with label DevOps Automation. Show all posts

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

29 Oct 2025

🐧 Linux Shell Scripting for Beginners – Part 1: What is a Variable?πŸ’»

Welcome to this Shell Scripting series! In this first part, we will learn about variables in a very simple and easy-to-understand way.

πŸ“‘ Table of Contents



🌟 What is a Variable?

A variable is like a small box where you store some information. Later, you can open the box and use that information again in your script.

✏️ How to Create a Variable

name="Pradeep"
course="Shell Scripting"
count=10

Important: There should be no space before or after the = sign.

❌ Wrong

name = "Pradeep"

✅ Correct

name="Pradeep"

πŸ“’ How to Use a Variable

echo "Hello $name, welcome to $course training!"
Hello Pradeep, welcome to Shell Scripting training!

🧊 Variables That Cannot Change (readonly)

readonly company="MiddlewareBox"

If you try to change it again, the script will not allow it.


🌍 Global and Local Variables

name="Pradeep"   # Global variable

greet() {
  local name="DevOps Engineer"
  echo "Inside function: $name"
}

greet
echo "Outside function: $name"
Inside function: DevOps Engineer
Outside function: Pradeep

🧠 Store Command Output in a Variable

today=$(date)
echo "Today is: $today"

πŸ’» Simple Practical Example: System Info

host=$(hostname)
os=$(uname -s)
kernel=$(uname -r)

echo "Hostname: $host"
echo "OS: $os"
echo "Kernel: $kernel"

πŸš€ Simple Use Case: App Deployment Path

app="orderservice"
version="v2.3"
path="/opt/apps/$app"

echo "Deploying $app version $version"
mkdir -p $path
cp $app-$version.jar $path/


🧡 Multi-Word Values (Use Quotes)

msg="Hello Shell Scripting Learners"
echo "$msg"

πŸ” Use Variables as Counters

count=1

while [ $count -le 3 ]; do
  echo "Count: $count"
  count=$((count+1))
done

❓ Check if a Variable is Empty

if [ -z "$name" ]; then
  echo "Name is empty"
else
  echo "Name is $name"
fi

⏱️ Use Time in Variable (Backup File Name)

time=$(date +%Y-%m-%d_%H-%M-%S)
file="backup_$time.tar.gz"
echo "Backup file name: $file"

🧰 Small Real-Life Script: Create User and Log

username="john"
log="/var/log/user_creation.log"

echo "Creating user: $username" | tee -a $log
useradd $username
echo "User $username created at $(date)" | tee -a $log

πŸ‘ Quick Summary

TopicMeaning
VariableA box to store data
$variableUse the value
readonlyLock the value
localUse only inside a function
$(command)Save output of a command