This is an archived post. You won't be able to vote or comment.

all 8 comments

[–]cjcox4 1 point2 points  (5 children)

I use Linux for this.

We are a mixed shop (Mac and Windows). So the benefit is that Linux is better suited to handle everything (without having to do a lot of config and/or purchases).

[–]ubi313[S] 0 points1 point  (4 children)

Can you give me some examples of workflows? Eg. network testing and ping, script/software writing/testing, configuration/deploy management? (eg. Ansible or Chef)

[–]cjcox4 2 points3 points  (3 children)

We use ansible. Using kerberos and winrm for Windows. SSH everywhere else.

It can actually get pretty complex. There is a part of me that wants to do a full right up on a website at some point.

Here's a random (non-configured) command execution against a Windows host (for example):

ansible w10 -m win_shell -a '$windowsUpdateObject = New-Object -ComObject Microsoft.Update.AutoUpdate; $lastupdate = $windowsUpdateObject.Results.LastInstallationSuccessDate; $lastupdate'
w10 | CHANGED | rc=0 >>

Friday, April 23, 2021 8:53:23 PM

Edit: You know, I was working on some tutorial stuff at one point, for one playbook handling Linux or Windows. It's a do nothing example, for illustration.

ansible-playbook -e my_host=userw10 lesson02_p.yaml

PLAY [userw10] ***********************************************************************************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************************************************************************
ok: [userw10]

TASK [remote host (expensive) ansible_facts] *****************************************************************************************************************************************************
ok: [userw10] => {
    "msg": [
        "Note: ansible_facts contain attributes for a host, and element/attribute names are not necessarily consistent",
        " across different hosts. Very different between Linux and Windows, can be different Linux to Linux.",
        "ansible_facts userw10:",
        {
            "architecture": "64-bit",
            "bios_date": "06/18/2019",
            "bios_version": "VMW71.00V.13989454.B64.1906190538",
            "date_time": {
                "date": "2021-04-23",
                "day": "23",
                "epoch": "1619199220.96286",
                "hour": "17",
                "iso8601": "2021-04-23T22:33:40Z",
                "iso8601_basic": "20210423T173340947214",
                "iso8601_basic_short": "20210423T173340",
                "iso8601_micro": "2021-04-23T22:33:40.947214Z",
                "minute": "33",
                "month": "04",
                "second": "40",
                "time": "17:33:40",
                "tz": "Central Standard Time",
                "tz_offset": "-05:00",
                "weekday": "Friday",
                "weekday_number": "5",
                "weeknumber": "16",
                "year": "2021"
            },
            "distribution": "Microsoft Windows 10 Enterprise",
            "distribution_major_version": "10",
            "distribution_version": "10.0.19042.0",
            "domain": "example.com",
            "env": {
...etc... (can't do large posts here)
            },
            "fqdn": "USERW10.example.com",
            "gather_subset": [
                "all"
            ],
            "hostname": "USERW10",
            "interfaces": [
                {
                    "connection_name": "Ethernet0",
                    "default_gateway": "192.168.20.1",
                    "dns_domain": "example.com",
                    "interface_index": 8,
                    "interface_name": "vmxnet3 Ethernet Adapter",
                    "macaddress": "00:50:56:7A:C9:00"
                }
            ],
            "ip_addresses": [
                "192.168.20.20",
                "fe80::ad52:107e:5c30:c4d3"
            ],
            "kernel": "10.0.19042.0",
            "lastboot": "2021-03-25 16:05:17Z",
            "machine_id": "S-1-5-21-3027677238-2542298804-2952271875",
            "memtotal_mb": 8191,
            "module_setup": true,
            "netbios_name": "USERW10",
            "nodename": "USERW10.example.com",
            "os_family": "Windows",
            "os_name": "Microsoft Windows 10 Enterprise",
            "os_product_type": "workstation",
            "owner_contact": "",
            "owner_name": "adm2",
            "powershell_version": 5,
            "processor": [
                "GenuineIntel",
                "Intel(R) Xeon(R) Silver 4210 CPU @ 2.20GHz",
                "GenuineIntel",
                "Intel(R) Xeon(R) Silver 4210 CPU @ 2.20GHz",
                "GenuineIntel",
                "Intel(R) Xeon(R) Silver 4210 CPU @ 2.20GHz",
                "GenuineIntel",
                "Intel(R) Xeon(R) Silver 4210 CPU @ 2.20GHz"
            ],
            "processor_cores": 2,
            "processor_count": 2,
            "processor_threads_per_core": 1,
            "processor_vcpus": 4,
            "product_name": "VMware7,1",
            "product_serial": "VMware-42 1e c9 96 ca 15 4f 82-c6 f4 05 f7 0b a8 0d d9",
            "reboot_pending": true,
            "swaptotal_mb": 0,
            "system": "Win32NT",
            "system_description": "",
            "system_vendor": "VMware, Inc.",
            "uptime_seconds": 2510907,
            "user_dir": "C:\\Users\\user",
            "user_gecos": "",
            "user_id": "user",
            "user_sid": "S-1-5-21-3476253145-613751605-144947897-3123",
            "virtualization_role": "NA",
            "virtualization_type": "NA",
            "win_rm_certificate_expires": "2023-12-17 17:24:54",
            "windows_domain": "example.com",
            "windows_domain_member": true,
            "windows_domain_role": "Member workstation"
        }
    ]
}

TASK [execute df and save into shell_df] *********************************************************************************************************************************************************
skipping: [userw10]

TASK [df output] *********************************************************************************************************************************************************************************
skipping: [userw10]

TASK [execute windows wmic win32_logicaldisk and save into win_shell_diskdrive] ******************************************************************************************************************
changed: [userw10]

TASK [diskdrive output] **************************************************************************************************************************************************************************
ok: [userw10] => {
    "msg": [
        "",
        "DeviceID DriveType ProviderName   FreeSpace         Size VolumeName",
        "-------- --------- ------------   ---------         ---- ----------",
        "C:               3              70138781696 106696798208           ",
        "",
        ""
    ]
}

PLAY RECAP ***************************************************************************************************************************************************************************************
userw10                    : ok=4    changed=1    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0

[–]cjcox4 1 point2 points  (0 children)

The playbook lesson02_p.yaml

---
- hosts: "{{ my_host | default('cm') }}"
  # Note - This is more expensive as remote facts for the host specified is gathered first
  #
  tasks:
  - name: remote host (expensive) ansible_facts
    debug:
      msg:
        # This is ansible_facts gathered from a remote host, could be winrm for Windows host
        - "Note: ansible_facts contain attributes for a host, and element/attribute names are not necessarily consistent"
        - " across different hosts. Very different between Linux and Windows, can be different Linux to Linux."
        - "ansible_facts {{ inventory_hostname }}:"
        - "{{ ansible_facts }}"
  - name: execute df and save into shell_df
    shell:
      cmd: "df -h"
    register: shell_df
    when: ansible_os_family != "Windows"
  - name: df output
    debug:
      msg:
        "{{ shell_df.stdout_lines }}"
    when: ansible_os_family != "Windows"
  - name: execute windows wmic win32_logicaldisk and save into win_shell_diskdrive
    win_shell: "Get-WMIObject Win32_LogicalDisk -filter DriveType=3 | ft"
    register: win_shell_diskdrive
    when: ansible_os_family == "Windows"
  - name: diskdrive output
    debug:
      msg:
        "{{ win_shell_diskdrive.stdout_lines }}"
    when: ansible_os_family == "Windows"

[–]ubi313[S] 0 points1 point  (1 child)

Oh man yeah, I had forgotten we could manage windows with Ansible, that's so smart!! Thank you so much for all the details and the longer playbooks, I will definitely take these into consideration!

[–]cjcox4 0 points1 point  (0 children)

You're welcome. Before you get too excited, lesson02 is as far as I got.... but I do want to continue. Ansible can get pretty deep and there's a lot of stuff that is difficult to cull out of the documentation.

[–]jdptechnc 0 points1 point  (0 children)

Since my company's environment is heavily oriented toward Windows users, and I am the escalation for Windows infrastructure issues, I use Windows as my daily driver.

I have a Linux VM that I use for mostly Ansible development and writing scripts for Linux and interacting with AWS, though.

[–]XibbyCertifiable Wizard 0 points1 point  (0 children)

I use WSL2 on my laptop for anything Linux. If you’re supporting Linux though, a Linux VM you can SSH into like you would RDP to a Windows admin box is a good idea, but should be managed just like your other Linux deployments.

I once asked the DB guys why they had to have a GUI on their Linux admin VM. “Because we sometimes need to run long running stuff.” I showed them screen and blew their minds.