Friday, May 10, 2013

Setting up IP based Printers in SCCM 2007

When setting up migration of Windows XP to Windows 7 or just plain "ordinary" deployment with SCCM 2007, IP based printers are treated as local printers and are not migrated.

This may be problem in environment where majority of printers are setup as IP based printers.

One way to solve this would be to write a script to capture all local printers and import them back on the new machine. The problem with this solution is that most of the old printers may be transferred, sometimes not all the drivers are available for the new platform, etc.

So the decision was to document the current state and decide what printers to keep and create a package and printer definition file to add printers during final stages of the task sequence.

The script must add a local IP Port - here is Windows 7 command:
c:\windows\System32\Printing_Admin_Scripts\en-US\Prnport.vbs -a -r IP_IPAddress -h IPAddress -o raw -n 9100
Adding Printer - with following command:
rundll32 printui.dll,PrintUIEntry /if /b "Base Printer Name" /n "Printer Name" /u /f "inf file" /r "IP_PortName" /m "PrinterDriverModelName"

Note that the PrinterDriverModelName must be exact, no extra spaces or missing characters.
To get more info on the command just run:
rundll32 printui.dll,PrintUIEntry

The idea for the main script is that the script will read the definition CSV file, search for computer name and then create port(s) and printer(s). So the CSV file needs to contain Computer name, IP Address, Printer Name, Printer Driver Name, Inf File Location.

First part of the script reads the file and creates the array - I did not reinvent the wheel and found this universal function made by HunBug.

Download the addprinters.vbs
Download definition template printers.cvs


Wednesday, May 8, 2013

ProCurve Switch configuration for mass deployment - without ProCurve Manager

ProCurveWe were tasked to upgrade networking infrastructure for one of our customers and that meant to setup, configure and roll-out more than 2000 edge devices and core devices, mostly HP ProCurve 2910al, some PoE deices 2610, and 6200yl.
The switches needed to be swapped overnight at each location (average 40 devices per location) replacing old existing device.
Here is a VR image how the warehouse looks like: http://tinyurl.com/lcpqpz9


The configuration was quite simple so I decided to automate the process of config loading and firmware upgrade.

One way would be to use HP ProCurve Manager, but at the time of this project ProCurve was not very stable and would require lot of "waiting" for the switches to show up.

Firmware Upgrade
I created automated way to upgrade the firmware on the switches, but I have found that fastest way is hook up the switches to our setup network, start tftp server with the recent SW update and then use laptop and connect to console and just copy series of commands like this (HP 2810-XXG)

copy tftp flash <Your_TFTP_Server_IP> N_11_25.swi primary
y
copy flash flash secondary
y
boot
y
y


Sometimes you have to do it twice because the boot ROM needs to be updated but the major advantage is that you do not have to wait for the commands to finish - they are buffered and you can move on to the next switch as soon as the text is pasted to the window. This way you can prepare the bare switches to the uniform state for the next step.

Documentation and Configuration
Since we go all the information we needed in Excel (name, IP) and the configuration on edge devices was pretty much the same, I created a macro script with config template for each model. After unpacking switch MACs were scanned into the template and IP modified based on the site network.

Configuration Template

To deploy the config in as few steps as possible I decided not to script all the configuration commands in a telnet session, but rather generate the config file for each switch based on the template and then just telnet to the switch and use tftp to transfer the right file.

Because of the specific configuration let me just show some of the logic and  behind The Config Button from the image above:

  • Individual config files are generated with names like 2800_IPADDRESS.cfg
  • Configuration file defining scopes and reservations for local DHCP is generated based on the target network information.
    This will define the scope 10.123.40.0 on server 10.10.1.9
    # ======================================================================
    #          Scope name: TEST_40
    # ======================================================================
    # Add scope for 10.123.40.0
    Dhcp Server 10.10.1.9 add scope 10.123.40.0 255.255.255.0 "TEST_40" ""
    Dhcp Server 10.10.1.9 Scope 10.123.40.0 set state 1
    # ======================================================================
    #  Add Ipranges to the Scope 10.123.40.0, Server 10.10.1.9
    Dhcp Server 10.10.1.9 Scope 10.123.40.0 Add iprange 10.123.40.1 10.123.40.100
    # ======================================================================
    #  Add Excluderanges to the Scope
    Dhcp Server 10.10.1.9 Scope 10.123.40.0 add excluderange 10.123.40.1 10.123.40.1
    # ======================================================================
    #  Add OptionValues to the Scope
    Dhcp Server 10.10.1.9 Scope 10.123.40.0 set optionvalue 51 DWORD "3600"
    Dhcp Server 10.10.1.9 Scope 10.123.40.0 set optionvalue 3 IPADDRESS "10.123.40.1"


    This will add a reservation to a scope defined above:
    Dhcp Server 10.10.1.9 Scope 10.123.40.0 Add reservedip 10.123.40.10 005056C00008 "XXX-IDFXX-sALXX" "" "BOTH"
  • no the script will remotely execute commands for DHCP configuration
    netsh exec "TEST_scopes.txt"
    netsh exec "TEST_reservations.txt"
  • Next step is to configure the the vlan on the core to ensure connectivity to the dhcp server
    from the configuration vlan:
    I used powershell to script the telnet session to the core using Windows Automation Snapin for Powershell
    <#
    Name: Scripted telnet session 
    Description: Configures VLAN, 
    Version: 1.0 - Jan, 2010
    
    This script is provided "AS IS" with no warranties and
    is not supported by the authors or deployment4everyone.
    WARNING if you do not fully understand this - it will break your network.
    Feel free to use and modify for your needs. 
    
    Author - Milos Pec
    Blog: http://deployment4everyone.blogspot.com
    #>
    cls
    Import-Module "c:\scripts\wasp.dll"
    
    ########################################################
    # Annoyance fix for x64 version of windows - lost path to telnet.exe ...
    # More info: http://www.skyeagle.net/blog/post/Missing-64-bit-native-commands-in-Powershell-%28x86%29.aspx
    if ( (Test-Path "$($env:systemroot)\sysnative") -and (($env:path).split(';') -notcontains "$($env:systemroot)\sysnative") ) {
        $env:path = "$($env:path);$($env:systemroot)\sysnative"
        Write-Host "Path updated to include: $($env:systemroot)\sysnative"
    } 
    ########################################################
    
    
    $switch = "COREIP"
    $user = "ADMINUSER"
    $pwd = ""
    
    #get arguments for the script
    if ($args[0]) {
            $netw = $args[0]
        }else{
            $netw = read-host "Enter second octet network number [10.XXX.40.0]"
    }
    
    if ($netw -eq "") {
        write-host "Panic - network number is needed ..." 
        } else {
    $_switch = read-host "Confirm switch IP [$switch]"
        if($_switch -eq ""){#Default
            }
        elseif($_switch -eq $null) {#Default
            }
        else{$switch = $_switch}
    
    $_user = read-host "Enter username [$user]"
        if($_user -eq ""){#Default
            }
        elseif($_user -eq $null) {#Default
            }
        else{$user = $_user}
    
    $pwd = read-host "Enter password" -AsSecureString
    $pwdenc = [Runtime.InteropServices.Marshal]
    $pwd = $pwdenc::PtrToStringAuto( $pwdenc::SecureStringToBSTR($pwd))
    Start telnet.exe $switch
    Start-Sleep -s 1
    Select-Window telnet | send-keys "~"
    Start-Sleep -s .2
    Select-Window telnet | send-keys "$user~"
    Start-Sleep -s .2
    Select-Window telnet | send-keys "$pwd~"
    Start-Sleep -s .2
    Select-Window telnet | send-keys "config ~"
    Start-Sleep -s .2
    Select-Window telnet | send-keys "vlan 40 ~"
    Start-Sleep -s .2
    Select-Window telnet | send-keys "no ip add ~"
    Start-Sleep -s .2
    Select-Window telnet | send-keys "ip add 10.$netw.40.1 255.255.255.0 ~"
    Start-Sleep -s .2
    Select-Window telnet | send-keys "untag c1-c24,d1-d24 ~"
    Start-Sleep -s .2
    Select-Window telnet | send-keys "write mem ~"
    Start-Sleep -s .2
    Select-Window telnet | send-keys "logout ~"
    Start-Sleep -s 1
    }
  • The switches can be turned on and they should get the correct IP address
  • The macro is setup to automatically start the TFTP server (I am using opensource TFTPD32) configured with source directory where all the switch configs are stored and then using again PowerShell scripted session to run simple commands to download the right configuration:
    copy tftp startup-config TFTP_IP 2600_SWITCHIP_ip.cfg
Next missing step is 3 hours on site replacing switches ... but that can be fun to :-).