Jan 6, 2019 - Flash Cisco AP from a Mac

This is for a Cisco AIR 3502.

  1. Start off by installing the Tftp Server(http://ww2.unime.it/flr/tftpserver/oon your mac
  2. Acquire the Cisco Firmware that will be flashed on the access point.
  3. Place the firmware in the /private/tftpboot/ and start the tftp service
  4. Change the permission chmod 744 /private/tftpboot/and owner chown root:wheel /private/tftpboot
  5. Connect a usb serial adapter to the mac and test the device with ls /dev/cu.usbserialor ls /dev/ttyUSB0
  6. On the mac open terminal and open a console to the access points with screen /dev/cu.usbserial 9600 cs8 -ixof
  7. Enter the username and password (hint: defaults are Cisco Cisco)
  8. If you need to reset the device password press and hold the the mode button while the power is connected to the access point wait until the ap: prompt is displayed

The following commands will be run in the access point console

  1. Set IP of the access point set IP_ADDR and netmask set NETMASK
  2. Tell the AP the router’s ip set DEFAULT_ROUTER
  3. Configure the AP to accept new firmware over tftp tftp_init
  4. Start an ethernet connection to accept firewareether_init
  5. Allow for flash memory to be accessed flash_init
  6. Flash the tar -xtract tftp://<TFTP SERVER IP>/<FIRMWARE>.tar flash: an example tar -xtract tftp://<TFTP SERVER IP>/ap3g1-k9w7-tar.153-3.JF4.tar flash:
  7. Wait about 20 minutes, grab a coffee
  8. Set the newly added firmware to bootset BOOT flash:/ap3g1-k9w7-mx.153-3.JF4/ap3g1-k9w7-mx.153-3.JF4
  9. set MANUAL_BOOT no
  10. set boot
  11. Reboot the access point and see if the newly added firmware boots
  12. Log back into the access point and delete the old firmware to free up space delete /force /recursive flash:<FIRMWARE>

Dec 22, 2017 - Using Additional Ansible Facts

This article is an addition to Additional Ansible Windows Facts.

To view the facts after running the role enter in the following in a terminal.

ansible <HOST or GROUP>  -m debug -a "var=ansible_getFacts"

To search for host for a signal program:

ansible <HOST or GROUP> -m debug -a "var=hostvars[inventory_hostname]['ansible_getFacts']['<PROGRAM NAME>']"

To check if a program is installed

  1. Set the register variable
    - name: get variables
      debug: var=hostvars[inventory_hostname]['ansible_getFacts']['<PROGRAM NAME>']
     register: <PROGRAM NAME>
  2. Next use the register with the ansible ‘when’ command. Below is an exaple that will run in cases of the program missing.
      when: hostvars[inventory_hostname]['ansible_getFacts']['<PROGRAM NAME>'] is undefined

Complete Example

- name: get variables
  debug: var=hostvars[inventory_hostname]['ansible_getFacts']['Microsoft Office Professional Plus 2016']
  register: msoffice_check

- name: create  ms office dir 
    path: C:\msoffice
    state: directory 
  when: hostvars[inventory_hostname]['ansible_getFacts']['Microsoft Office Professional Plus 2016'] is undefined
- name: copy ms office dir to c drive
    src:  /misc/software/msoffice2016/
    dest: C:\msoffice
  ignore_errors: yes
  when: hostvars[inventory_hostname]['ansible_getFacts']['Microsoft Office Professional Plus 2016'] is undefined

- name:  Install msoffice
  win_command: choco install msoffice.20.16.1.nupkg -y
    chdir: C:\msoffice
  ignore_errors: yes
  when: hostvars[inventory_hostname]['ansible_getFacts']['Microsoft Office Professional Plus 2016'] is undefined

- name: remove MS office dir
    path: C:\msoffice
    state: absent
  when: hostvars[inventory_hostname]['ansible_getFacts']['Microsoft Office Professional Plus 2016'] is defined

Nov 14, 2017 - Additional Ansible Windows Facts

Ansible is a great tool to manage any Linux or Windows host. However it is missing some key tools and features. Here is a playbook and instructions to gather all installed programs on a Windows host.

Start with creating a new role, I named mine facts.

Create the facts\tasks\main.yml file and add the following

- name: create Scripts dir
    path: C:\Scripts
    state: directory 

- name: create Scripts facts dir
    path: C:\Scripts\facts
    state: absent        

- name: copy custom facts file
    src: getFacts.ps1
    dest: C:\Scripts\

- name: gather extra facts
    fact_path: C:\Scripts

- name: Set intermediate fact
    vars_hack: ""

- name: set program facts
    one_fact: ansible_getFacts
    var_hack:  "" 
- name: delete json file 
    path: "/.json"
    state: absent
  failed_when: false
  delegate_to: localhost

- name: Dump all vars
  action: template src=templates/dumpall.j2 dest="/.json"
  delegate_to: localhost

- name: add to db
  script: app.py
  delegate_to: localhost
  ignore_errors: true

Now create the facts/files/getFacts.ps1 file and add the follwoing below. This file will be copied to each Windows host and run return a dictionary of all installed programs.

#sourced from https://hindenes.com/trondsworking/2016/11/05/using-ansible-as-a-software-inventory-db-for-your-windows-nodes/
$packages = Get-WmiObject -Class Win32_Product
$returnpackages = @{}
foreach ($package in $packages)
   $subpackagedictionary = @{"Name" = $Package.Name; "Version" = $Package.Version; "Caption" = $Package.Caption;}
   $returnpackages.Add($Package.Name, $subpackagedictionary)
#Write-Host $returnpackages."Google Chrome".Name
#Write-Host $returnpackages."Google Chrome".Version

For debugging purposes you may want to create JSON files from the returned dictionary. To do so create a facts/templates/dumpall.j2 and add the following.

  {{ vars_hack | to_json }}

Create the facts\files\app.py and add the following below. This files erases passwords dumped in the the json files.

#!/usr/bin/env python
# orginal found at https://hindenes.com/trondsworking/2016/11/05/using-ansible-as-a-software-inventory-db-for-your-windows-nodes/

import os
import json

from os import listdir
from os.path import isfile, join

tempfolder = '../roles/facts/files/data/json/'

if not os.path.isdir(tempfolder):

onlyfiles = [f for f in listdir(tempfolder) if isfile(join(tempfolder, f))]

for file in onlyfiles:
  host_name = str(file).replace('.json','')  ##I am using host ips, to use hostnames use str(file).split(".")[3]
  with open(os.path.join(tempfolder, file),'r+') as data_file:
      data = json.load(data_file)
      data['ansible_password'] = ''
      data['ansible_password_ad'] = ''
  with open(tempfolder+'/'+file, 'w+') as outfile:
    json.dump(data, outfile, sort_keys=True, indent=2, separators=(',', ': '))

Create one last file the vars file for the role. Create vars/main.yml and add the following.

json_files: '../roles/facts/files/data/json/'
host_program_csv: '../roles/facts/files/data/programs'

Now install the redis service. For Centos 7

yum install redis
systemctl enable redis
systemctl start redis

Generate a hash for redis

echo "redis-password-string" | sha256sum 

Edit the redis config file in /etc/redis.confand find the line requirepass and insert the generated hash

Edit your base ansible.cfg usualy in the first directory of your ansible setup and add the line

fact_caching_connection = <redis-ip>:6379:0:<redis-hash>

Updated: 2/7/2019