<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Automation Archives - InfoTech Ninja</title>
	<atom:link href="https://infotechninja.com/category/automation/feed/" rel="self" type="application/rss+xml" />
	<link>https://infotechninja.com/category/automation/</link>
	<description></description>
	<lastBuildDate>Tue, 07 Apr 2026 00:00:00 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>PowerShell 7: 10 Scripts Every SysAdmin Should Have in Their Toolkit</title>
		<link>https://infotechninja.com/powershell-7-sysadmin-scripts/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=powershell-7-sysadmin-scripts</link>
					<comments>https://infotechninja.com/powershell-7-sysadmin-scripts/#respond</comments>
		
		<dc:creator><![CDATA[Morris James]]></dc:creator>
		<pubDate>Tue, 07 Apr 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[ActiveDirectory]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[Windows]]></category>
		<guid isPermaLink="false">https://infotechninja.com/?p=4</guid>

					<description><![CDATA[<p>PowerShell 7 (built on .NET 6+) is a genuine upgrade from Windows PowerShell 5.1. It's cross-platform, significantly faster for parallel workloads, and brings modern language features that make complex automation dramatically cleaner.</p>
<p>The post <a href="https://infotechninja.com/powershell-7-sysadmin-scripts/">PowerShell 7: 10 Scripts Every SysAdmin Should Have in Their Toolkit</a> appeared first on <a href="https://infotechninja.com">InfoTech Ninja</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="entry-lead">PowerShell 7 (built on .NET 6+) is a genuine upgrade from Windows PowerShell 5.1. It&#8217;s cross-platform, significantly faster for parallel workloads, and brings modern language features that make complex automation dramatically cleaner. If you&#8217;re still defaulting to PS 5.1 out of habit, this article will convince you to make the switch and give you scripts worth keeping.</p>
<h2>Why PS7 Changes Everything for SysAdmins</h2>
<p>The headline feature for infrastructure work is <code>ForEach-Object -Parallel</code>. In PowerShell 5.1, looping over hundreds of servers to run a command was sequential — painfully slow when each operation involves a network call. In PS7, adding <code>-Parallel</code> to your ForEach-Object pipeline runs iterations concurrently (up to a configurable throttle limit), collapsing a 10-minute sequential run to under a minute. Combined with the <code>-ThrottleLimit</code> parameter, you get controlled parallelism without overwhelming your network or target systems.</p>
<p>PowerShell 7 also ships with null-coalescing operators (<code>??</code> and <code>??=</code>), pipeline chain operators (<code>&amp;&amp;</code> and <code>||</code>), ternary expressions, and significantly improved error handling. The <code>Get-Error</code> cmdlet provides structured, detailed error information that makes debugging complex scripts far easier. Module compatibility has improved too — most PS 5.1 modules work in PS7 via a compatibility shim, though a handful of modules that rely on Windows-only COM components remain PS5.1-only.</p>
<h2>Bulk AD User Management</h2>
<p>Managing Active Directory users at scale through the GUI is tedious and error-prone. PowerShell with the ActiveDirectory module makes bulk operations straightforward and auditable. Common tasks like disabling accounts for departed employees, resetting passwords, updating department attributes for an org restructure, or moving users between OUs all lend themselves to one-liners or short scripts that you can test in a non-production OU first.</p>
<p>The script below processes a CSV file of user updates — useful when HR sends over a spreadsheet of 200 employees who need their department and manager attributes updated after a reorg. Run it with <code>-WhatIf</code> first to preview changes without applying them, then remove the switch for the actual run.</p>
<pre><code># BulkUpdateADUsers.ps1 — Update AD attributes from CSV
# CSV columns: SamAccountName, Department, Manager, Title
#Requires -Modules ActiveDirectory

param(
    [Parameter(Mandatory)][string]$CsvPath,
    [switch]$WhatIf
)

$users = Import-Csv -Path $CsvPath
$results = [System.Collections.Concurrent.ConcurrentBag[object]]::new()

$users | ForEach-Object -Parallel {
    $bag = $using:results
    $whatIf = $using:WhatIf
    try {
        $params = @{
            Identity   = $_.SamAccountName
            Department = $_.Department
            Title      = $_.Title
            Manager    = (Get-ADUser $_.Manager).DistinguishedName
            WhatIf     = $whatIf.IsPresent
        }
        Set-ADUser @params
        $bag.Add([pscustomobject]@{ User=$_.SamAccountName; Status="OK" })
    } catch {
        $bag.Add([pscustomobject]@{ User=$_.SamAccountName; Status="FAIL: $_" })
    }
} -ThrottleLimit 20

$results | Export-Csv -Path ".\update-results.csv" -NoTypeInformation
Write-Host "Done. Results at .\update-results.csv"</code></pre>
<h2>Automated Patch Reporting</h2>
<p>Keeping track of patch status across a fleet of Windows servers is a common pain point. WSUS gives you a dashboard, but exporting useful reports for management or auditors is clunky. A PowerShell script that queries hotfix history across multiple servers and generates a clean report is something every Windows admin should have. The script below uses PS7&#8217;s parallel foreach to query multiple servers simultaneously, dramatically reducing the time it takes to gather data.</p>
<p>Combine this with a scheduled task or Azure Automation runbook to generate weekly patch compliance reports automatically. Export to CSV for easy import into Excel or your ITSM tool, or format as HTML for email distribution. Adding logic to flag servers that haven&#8217;t received updates in more than 30 days gives you an actionable compliance metric for your next audit.</p>
<pre><code># Get-PatchReport.ps1 — Query hotfix status across multiple servers
param([string[]]$Servers = @("SRV01","SRV02","SRV03"))

$report = $Servers | ForEach-Object -Parallel {
    $server = $_
    try {
        $hotfixes = Get-HotFix -ComputerName $server -ErrorAction Stop |
            Sort-Object InstalledOn -Descending |
            Select-Object -First 1
        [pscustomobject]@{
            Server       = $server
            LastPatch    = $hotfixes.HotFixID
            InstalledOn  = $hotfixes.InstalledOn
            DaysSince    = (New-TimeSpan -Start $hotfixes.InstalledOn -End (Get-Date)).Days
            Status       = "Online"
        }
    } catch {
        [pscustomobject]@{ Server=$server; LastPatch="N/A"; InstalledOn="N/A"; DaysSince=999; Status="Error: $_" }
    }
} -ThrottleLimit 10

$report | Sort-Object DaysSince -Descending | Format-Table -AutoSize
$report | Export-Csv ".\patch-report-$(Get-Date -f yyyyMMdd).csv" -NoTypeInformation</code></pre>
<h2>Calling REST APIs from PowerShell</h2>
<p><code>Invoke-RestMethod</code> is PowerShell&#8217;s built-in REST client, and it&#8217;s surprisingly capable. It automatically deserializes JSON responses into PowerShell objects, handles common authentication schemes, and supports all HTTP methods. Combined with PS7&#8217;s improved performance and parallelism, you can build lightweight integration scripts between your on-prem tooling and cloud APIs without pulling in external dependencies or standing up middleware.</p>
<p>A common use case: querying your monitoring tool&#8217;s API to get a list of alerts, then correlating them with your CMDB API to enrich the data before posting to a Teams channel via the incoming webhook API. Three API calls, all handled with <code>Invoke-RestMethod</code>, tied together in a script that runs every 15 minutes as a scheduled task. It&#8217;s not glamorous, but it&#8217;s the kind of practical automation that saves your team hours every week.</p>
<p>The post <a href="https://infotechninja.com/powershell-7-sysadmin-scripts/">PowerShell 7: 10 Scripts Every SysAdmin Should Have in Their Toolkit</a> appeared first on <a href="https://infotechninja.com">InfoTech Ninja</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://infotechninja.com/powershell-7-sysadmin-scripts/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">22</post-id>	</item>
		<item>
		<title>Getting Started with Ansible: Write Your First Playbook in 30 Minutes</title>
		<link>https://infotechninja.com/ansible-playbooks-beginner/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ansible-playbooks-beginner</link>
		
		<dc:creator><![CDATA[Morris James]]></dc:creator>
		<pubDate>Tue, 24 Feb 2026 00:00:00 +0000</pubDate>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[Ansible]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[IaC]]></category>
		<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">https://infotechninja.com/?p=10</guid>

					<description><![CDATA[<p>Ansible is the Swiss Army knife of infrastructure automation. No agents to install, no complex architecture to manage — just Python, SSH, and YAML. If you know your way around Linux, you can write a useful playbook today.</p>
<p>The post <a href="https://infotechninja.com/ansible-playbooks-beginner/">Getting Started with Ansible: Write Your First Playbook in 30 Minutes</a> appeared first on <a href="https://infotechninja.com">InfoTech Ninja</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="entry-lead">Ansible is the Swiss Army knife of infrastructure automation. No agents to install, no complex master-client architecture to manage, no proprietary DSL to learn. Just Python, SSH, and YAML. If you can write a shell script and you know your way around Linux, you can write a useful Ansible playbook today.</p>
<h2>No Agents, No Drama: The Ansible Model</h2>
<p>Ansible&#8217;s architecture is deliberately simple. The control node (your workstation, a bastion host, or a CI/CD runner) connects to managed nodes over SSH (or WinRM for Windows), executes tasks, and disconnects. There&#8217;s no agent process running on managed nodes consuming resources or requiring updates. The only requirement on managed nodes is Python (which is present on virtually every Linux system) and a user account with appropriate sudo privileges.</p>
<p>Idempotency is Ansible&#8217;s most important design principle. Every built-in module is designed so that running a task multiple times produces the same result as running it once. If nginx is already installed and running, the <code>package</code> and <code>service</code> modules report &#8220;OK&#8221; rather than reinstalling or restarting. This means you can run your playbooks safely at any time — to enforce desired state, to verify compliance, or to bring a drifted system back in line — without worrying about destructive side effects.</p>
<h2>Your Inventory File</h2>
<p>Ansible&#8217;s inventory defines the hosts and groups your playbooks target. The simplest format is an INI-style text file. You can also use YAML format or dynamic inventory plugins that query cloud provider APIs (AWS EC2, Azure VMs, GCP instances) to build the inventory automatically from your actual running infrastructure — no manual list maintenance required.</p>
<p>Groups make targeting flexible. You might have a <code>[webservers]</code> group, a <code>[dbservers]</code> group, and a <code>[production]</code> group containing hosts from both. Group variables (stored in <code>group_vars/</code> directories) let you define different settings per group — staging might use a self-signed certificate while production uses a real one, but the same playbook handles both.</p>
<pre><code># inventory/hosts.ini — Sample inventory file
[webservers]
web01.example.com ansible_user=ubuntu
web02.example.com ansible_user=ubuntu

[dbservers]
db01.example.com ansible_user=ubuntu ansible_port=2222

[production:children]
webservers
dbservers

[production:vars]
env=production
nginx_worker_processes=4

# Test connectivity to all hosts:
# ansible all -i inventory/hosts.ini -m ping</code></pre>
<h2>Writing Your First Playbook</h2>
<p>A playbook is a YAML file containing one or more plays. Each play targets a group of hosts and defines a list of tasks to execute in order. Tasks use modules — the unit of work in Ansible. There are thousands of built-in modules covering package management, file operations, service management, cloud resources, network devices, and more. The module name is self-documenting: <code>ansible.builtin.apt</code>, <code>ansible.builtin.copy</code>, <code>ansible.builtin.systemd</code>.</p>
<p>The playbook below installs nginx, deploys a custom configuration, and ensures the service is running and enabled. Run it with <code>ansible-playbook -i inventory/hosts.ini playbooks/nginx.yml</code>. Add <code>--check</code> for a dry run that shows what would change without making any changes.</p>
<pre><code># playbooks/nginx.yml — Install and configure nginx
---
- name: Configure web servers
  hosts: webservers
  become: true

  vars:
    nginx_port: 80
    server_name: "{{ inventory_hostname }}"

  tasks:
    - name: Ensure nginx is installed
      ansible.builtin.package:
        name: nginx
        state: present

    - name: Deploy nginx configuration
      ansible.builtin.template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/sites-available/default
        owner: root
        group: root
        mode: "0644"
      notify: Reload nginx

    - name: Ensure nginx is started and enabled
      ansible.builtin.systemd:
        name: nginx
        state: started
        enabled: true

  handlers:
    - name: Reload nginx
      ansible.builtin.systemd:
        name: nginx
        state: reloaded</code></pre>
<h2>Variables, Templates, and Handlers</h2>
<p>Variables in Ansible can be defined at multiple levels — in the playbook itself, in separate variable files, in the inventory, or passed on the command line with <code>-e</code>. Jinja2 templates (files ending in <code>.j2</code>) use double-brace syntax (<code>{{ variable_name }}</code>) to interpolate variables into configuration files. This is how one nginx template can produce correctly configured files for dozens of different servers, each with the right hostname, port, and SSL certificate path.</p>
<p>Handlers are tasks that only run when notified by another task. The classic use case: a task that updates a configuration file notifies the &#8220;Reload nginx&#8221; handler. If the configuration file didn&#8217;t change (because it was already correct), the handler never fires and nginx isn&#8217;t unnecessarily reloaded. If multiple tasks in a play all notify the same handler, the handler runs only once at the end of the play. This prevents redundant service restarts and makes your playbooks more efficient.</p>
<p>The post <a href="https://infotechninja.com/ansible-playbooks-beginner/">Getting Started with Ansible: Write Your First Playbook in 30 Minutes</a> appeared first on <a href="https://infotechninja.com">InfoTech Ninja</a>.</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">28</post-id>	</item>
	</channel>
</rss>
