Pages

12/18/2014

Powershell Report HP Virtual Connect VLANs

Create a report from HP virtual connect for all VLAN's defined in each server profile.

$cmd = 'C:\Program Files\HP\Virtual Connect Enterprise Manager\Virtual Connect Enterprise Manager CLI\vcemcli.exe'
 $arg1 = '-export'
 $arg2= 'profiles'
 $arg3 = '-exportfile'
 $arg4 = 'profiles.csv'
 &$CMD $arg1 $arg2 $arg3 $arg4
 $raw = ".\profiles.csv" | import-csv -header ''
 $list = $raw | format-list -property "Profile Name", "*Network Name" | out-string 
 $list = $list.split("`n")
 foreach ($item in $list) { 
  $item = $item.replace("`n","")
  $descr = $item.split(":")[0]
  $value = $item.split(":")[1]
  if ( $descr -like "Profile Name*") { 
   write-output "-----------------------------"
   write-output $value
   }
  else { 
   if ( $value -notlike "*N/A*") {
    write-output "    $value"
    }
   }
  }

12/11/2014

Linux - persistent sessions

sometimes it takes a long while for a task to run. It is possible to open a screen in Linux and let it continue to run after you close out your session to the machine. Then you can logon again later, switch to the screen and check the progress.

create/open a new screen:
    screen

Leave a screen open:
    CTRL+A, CTRL+D

list open screens:
    screen -ls

switch to a screen:
    screen -r 

close the screen:
    exit

11/04/2014

Let’s talk Security … DMZs, VLANs, and L2 Attacks | VMware vSphere Blog - VMware Blogs

Let’s talk Security … DMZs, VLANs, and L2 Attacks | VMware vSphere Blog - VMware Blogs

The idea of consolidating a DMZ to a single host (one of the scenarios described in the paper) has stirred some opinions in the VMware Communities. The subject of security always does.

I thought one of the replies to the ongoing discussion was worth reposting. This post is from our own Serge Maskalik (aka vSerge on communities). You can read the rest of the thread here to get the context of the discussion, but the points about L2 attacks I think stand on their own (and hence why I reposted them here)…

These are really good questions, and there are a number of considerations with regards to using VLANs and how to properly secure L2 environments to reduce your attack surface area. To say that VLANs aren’t secure and can’t be used for DMZ usage isn’t fair – the reality is that there lots of very secure VLAN implementation in production networks since the early part of this decade, especially seen in service provider networks. When you go to a Savvis, Global Crossing, AT&T, etc – you get a VLAN + CIDR block and datacenters’ tenants are split up this way across the access layer. I recall building out the GlobalCenter datacenters in the late 90s/early part of this decade (these are now Savvis through Exodus acquisition), and the flat edge network which was Catalyst 5500s with shared broadcast domains became Catalyst 6500s or 7600s or comparable solutions by other vendors with VLAN segregation by customer with VLAN counts in 1k+ range per datacenter. That was almost 10 years ago and we now see lots of large and small enterprise networks heavily leverage VLANs to reduce numbers of physical NICs, simplify physical topology, reduce port density requirements on the switching edge, provide more configuration flexibility, reach large consolidation ratios by having more VMs run on smaller number of ESX servers in collapsed DMZ+Internal environments, etc.

The following is a little bit of information about L2 attacks that folks often talk about and how to put some controls in place to prevent them.

1. CAM flooding or MAC flooding. Switches use content-addressable memory which contain VLAN/PORT/MAC-ADDRESS tables for looking up egress ports as frames are forwarded. These are the forwarding tables for the switches and they have limits in size. The CAM tables are populated by looking at the source MAC on a frame and creating a CAM entry that records which port maps to what source MAC. This attack type tries to overrun the table by generating large numbers of frames with different MACs, to the point that there is no more room in the CAM to store the MAC entries. When the CAM can no longer be populated, the switch will act like a hub and flood frames to all ports except the one the frame came in on (to prevent loops). To avoid this, there are features like setting the max number of MAC entries per port – in most cases you only need one per NIC. By setting this configuration, you get rid of this risk. Secondly, you have to evaluate the risk of such attack. The attacker has to penetrate into the DMZ, own a host within the DMZ or be already on a segment close to the DMZ to run this attack. This attack could not occur if there are intermediate routers in the path, since a mac rewrite occurs on those nodes. It’s a good idea to limit your L2 broadcast domains and the diameter of the switched network to avoid propagation of these type of issues.

2. VLAN Cross-talk Attacks (or VLAN Hopping) – on Cisco switches, the dot1q trunks pass all tags be default. When you configure the ESX host to uplink via a dot1q trunk, and guest tagging is allowed, it’s conceivable that a rogue guest can generate frames for VLANs it should not be a part off. Avoid enabled guest tagging and monitor your vSwitch configuration activity for such things. Another way to hop VLANs is to spoof dynamic trunk configuration frames from a host; protocols like these are used by vendors to automatically configure 802.1q trunks to set up and allow VLANs. To avoid this, configure switch ports passing tagged frames explicitly to be trunks and to explicitly forward specific tags. Also, don’t allow for unplugged ports on the switches to remain in a VLAN used by important assets – put them into an unused VLAN to avoid the possibility of someone plugging in to a port and getting access to the VLAN. Avoid using default VLANs (like VLAN1 on Ciscos).

3. ARP spoofing – this is where a host on the same segment as other hosts modify the ARP table on the edge router/gateway to point to the attacker’s MAC and are able to redirect traffic to themselves. This can be done using ARP request or Gratuitous ARP mechanisms. This is a bit tougher to defend against, but can happen regardless of whether you are using VLANs or not.

4. Spanning-Tree attacks – this is where attackers could cause a DoS and bring down the L2 network section by generated malicious STP BDPUs and become root bridges or confuse the protocol to block specific ports. This can happen regardless of usage of VLANs, plus features like bpdu-guard and root-guard help prevent this type of stuff.

5. VRRP or HRSP tampering – break the failover protocol for the default gateway, take over the gateway MAC yourself, etc.

6. Starve out the DHCP address range – not as big of deal of DMZ, unless you are using DHCP for servers.

We on the vShield Zones teams recognize these issues and try to provide visibility to VMs and flows destined/sourced to and from VMs from a network perspective. Using Zones, you can see an ARP spoofing attack from a VM or a physical host on a segment and remediate the issue. Security best practices claim that you need visibility into L2 to deal with these type of issues, so in addition to providing firewalling functionality, we spent a lot of time on providing microflow visibility.

Also, we are seeing lots of customers using vShield Zones to isolate and segment clusters to provide dual-purpose for DMZ and internal server VMs usage using VLANs + vShield Zones isolation. We will be posting papers on this front and there will be examples at VMworld on how this can work. We are seeing three major use cases in the context of this:

1. Isolated/Segment DMZ in a dedicated set of ESX hosts or cluster with multiple trust zones provided by the vShield Zones.

2. Fully collapsed DMZ where the cluster or set of ESX hosts are shared by internal VMs and Internet-facing VMs.

3. Branch office environments where there may be some VMs hosted with Internet access, some for internal server usage and VDI as well.

10/18/2014

Windows Server 2008R2 Disk Cleanup Utility

Disk Cleanup, like in Win7 is available by installing the Desktop Experience feature.
You can run it without installing Desktop Experience feature by doing the following:

Copy C:\Windows\winsxs\amd64_microsoft-windows-cleanmgr_31bf3856ad364e35_6.1.7600.16385_none_c9392808773cd7da\cleanmgr.exe C:\Windows\System32\
copy C:\Windows\winsxs\amd64_microsoft-windows-cleanmgr.resources_31bf3856ad364e35_6.1.7600.16385_en-us_b9cb6194b257cc63\cleanmgr.exe.mui C:\Windows\System32\en-US\
cleanmgr.exe /verylowdisk
You can put the above in a BAT file and it will copy the files and run without user intervention. Or just copy the files and run it to select options. run using cleanmgr.exe /? to see interesting switches for saving your selected options.

Calculating the past growth rate

I want to be able to determine the annual growth rate of data in a directory structure. I know it was created at a certain date and only "new" data was written there -- nothing was migrated from another directory structure.


Mathematically
the total $lastyear would be  $now  / (1 + $growthrate)
so the total  $pastyear $num years ago would be  $now  / (1 + $growthrate)^$num  .
but I am not sure if that would work all the way back to the first year when the total was 0 (if I use 1 GB to approximate zero, especially if the number of years is short, for example 2-3)


Solving for $growthrate:


    $pastyear = $now / ((1 + $growthrate)^$num)


    $pastyear * ((1 + $growthrate)^$num) = $now


    ((1 + $growthrate)^$num) = $now / $pastyear


    1 + $growthrate = ($now / $pastyear)^(1/$num)


    $growthrate = (($now / $pastyear)^(1/$num)) - 1


looking at the above if the $pastyear is very small to approximate zero and $num is pretty small this looks like it will be much bigger than is reasonable.


Subtly
For this specific purpose I could attempt to take a file listing of all the files in the directory structure.  Using Excel for instance:
- import the file listing above, use text to columns to split into fields, hide or delete all but date & file size
- create a 3rd column in between with formula calculating just the year of the date
- sort them by year newest to oldest
- group by year & subtotal the file size
this will tell me how much was there the first year
**when I ignore "growth" during the first year and use the amount at the end of the first year in the above formula it seems to be much more reasonable.

10/09/2014

Don't pad number strings, use modular arithmetic to calculate each digit

Example in Python:
// = integer division
% = remainder

# given t in tenths of seconds, 
# return a string of format string A:BC.D
# A = minutes, BC = seconds, with leading zero if needed, D = tenths of seconds
def format(t):
    tenths = t % 10
    t = t // 10
    sec = t % 60
    min = t // 60
    sec_ones = sec % 10
    sec_tens = sec // 10
    display = str(min) + ":" + str(sec_tens) + str(sec_ones) + "." + str(tenths)
    return display

9/30/2014

Test time to open Word documents of various sizes

Goal: Test to gather the time to open and save various size documents

function sleep(milliseconds) {
 var start = new Date().getTime();
 for (var i = 0; i < 1e7; i++) {
  if ((new Date().getTime() - start) > milliseconds){
   break;
   }
  }
 }

var myApp = new ActiveXObject("Word.Application");
myApp.Visible = true;

// Open 200K
var smopenstart = new Date().getTime();
  myApp.Documents.Open("Z:\\200K.doc");
var smopenend = new Date().getTime();

//wait 10 s
sleep(10000);

// Save 200K
var smsavestart = new Date().getTime();
  myApp.ActiveDocument.SaveAs("Z:\\NEW\\200K.doc");
var smsaveend = new Date().getTime();

// Close 200K
myApp.Documents.Close();

//quit Word
myApp.Application.Quit();

//wait 10 s
sleep(10000);

var myApp = new ActiveXObject("Word.Application");
myApp.Visible = true;

// Open 1MB
var medopenstart = new Date().getTime();
  myApp.Documents.Open("Z:\\1M.doc");
var medopenend = new Date().getTime();

//wait 10 s
sleep(10000);

// Save 1MB
var medsavestart = new Date().getTime();
  myApp.ActiveDocument.SaveAs("Z:\\NEW\\1M.doc");
var medsaveend = new Date().getTime();

// Close 1MB
myApp.Documents.Close();

//quit Word
myApp.Application.Quit();


//wait 10 s
sleep(10000);

var myApp = new ActiveXObject("Word.Application");
myApp.Visible = true;

// Open 5MB
var lrgopenstart = new Date().getTime();
  myApp.Documents.Open("Z:\\5M.doc");
var lrgopenend = new Date().getTime();

//wait 10 s
sleep(10000);

// Save 5MB
var lrgsavestart = new Date().getTime();
  myApp.ActiveDocument.SaveAs("Z:\\NEW\\5M.doc");
var lrgsaveend = new Date().getTime();

// Close 5MB
myApp.Documents.Close();

//quit Word
myApp.Application.Quit();

//define date string
var mo = new Date().getMonth()+1;
if (mo < 10) { mo = "0" + mo };
var day = new Date().getDate();
if (day < 10) {day = "0" + day};
var year = new Date().getFullYear();
var hrs = new Date().getHours();
if (hrs < 10) {hrs = "0" + hrs};
var m = new Date().getMinutes();
if (m < 10) {m = "0" + m};
var s = new Date().getSeconds();
if (s < 10) {s = "0" + s};
var dt = mo + "/" + day + "/" + year + " " + hrs + ":" + m + ":" + s

//Calculate times
var smopentime = (smopenend - smopenstart)/1000
var smsavetime = (smsaveend - smsavestart)/1000
var medopentime = (medopenend - medopenstart)/1000
var medsavetime = (medsaveend - medsavestart)/1000
var lrgopentime = (lrgopenend - lrgopenstart)/1000
var lrgsavetime = (lrgsaveend - lrgsavestart)/1000

//output results
WScript.Echo(dt, ",", smopentime, ",", smsavetime, ",", medopentime, ",", medsavetime, ",", lrgopentime, ",", lrgsavetime);
Save above as "openword.js" and call with the following BAT file

net use Z: \\SHARE\TEST\ATL
c:
cd\temp
cscript //NoLogo c:\temp\openword.js >> CHI.log
echo y | del z:\new\*.*
net use z: /delete

9/29/2014

Script: Time To Open Word Document

I want to time how long it takes to open a Word document over the WAN.

var myApp = new ActiveXObject("Word.Application");
myApp.Visible = true;
// Remember when we started
var start = new Date().getTime();
  myApp.Documents.Open("Z:\\openword\\1M.doc");
  //myApp.ActiveDocument.SaveAs("Z:\\openword\\1M.doc");
  myApp.Documents.Close();
// Remember when we finished
myApp.Application.Quit();
var end = new Date().getTime();
// Now calculate and output the difference
var time = end - start;
var mo = new Date().getMonth()+1;
if (mo < 10) { mo = "0" + mo };
var day = new Date().getDate();
if (day < 10) {day = "0" + day};
var year = new Date().getFullYear();
var hrs = new Date().getHours();
if (hrs < 10) {hrs = "0" + hrs};
var m = new Date().getMinutes();
if (m < 10) {m = "0" + m};
var s = new Date().getSeconds();
if (s < 10) {s = "0" + s};
var dt = mo + "/" + day + "/" + year + " " + hrs + ":" + m + ":" + s
WScript.Echo(dt, time / 1000);
save as c:\temp\testword.js run from CMD.EXE: cscript c:\temp\testword.js Will output something like: 9/29/2014 22:43:25 , 3.252

9/26/2014

Test Word Open & Save Repeatedly

From: OpLocks.net

var i;
var myApp = new ActiveXObject("Word.Application");
myApp.Visible = true;
for (i = 0; i < 1234; i++)
 {
  myApp.Documents.Open("C:\\TEMP\\testword.doc");
  //myApp.ActiveDocument.SaveAs("C:\\TEST\\testword.doc");
  myApp.Documents.Close();
 }
myApp.Application.Quit();
paste in editor and save as "test.js" for example. to run: cscript test.js

9/19/2014

Powershell: Get list of files in folder

Create a list of all files in a folder. Maybe in preparation for processing each file.

$workdir = "c:\parse"
$inputdir = $workdir + "\input"

# Get file listing
if (-not (test-path $inputdir)) {
 "Folder:  $inputdir"
 "Does not exist!"
 exit
 }

$files = get-childitem $inputdir -name
if (-not ($files)) {
 "Folder:  $inputdir"
 "Contains no files!"
 exit
 }

Powershell - Date String for File Name

I often need to create a temp file or output file and want to make it unique. Using the date and time can be a good way to do that. For example:

$now = get-date -format yyyyMMddHHmmss
$outfile = $now + ".csv"

8/21/2014

Powershell: Get SharePoint List

Need to get a sharepoint list but don't have access to the server -- I just have a logon that is able to browse to the list. In this example the list is named "Server Catalog." I retrieved the entire list and then selected entries with a specific value in a field named "DeploymentStatus"
$credential = get-credential
$uri = "http://tskm/apps/systemscatalog/_vti_bin/lists.asmx?WSDL"
$listName = "Server Catalog"             
            
# Create xml query to retrieve list.             
$xmlDoc = new-object System.Xml.XmlDocument            
$query = $xmlDoc.CreateElement("Query")            
$viewFields = $xmlDoc.CreateElement("ViewFields")            
$queryOptions = $xmlDoc.CreateElement("QueryOptions")            
$query.set_InnerXml("FieldRef Name='Full Name'")             
$rowLimit = "1000"            
            
$list = $null             
$service = $null              
            
try{            
    $service = New-WebServiceProxy -Uri $uri  -Namespace SpWs  -credential $credential  # -UseDefaultCredential
}            
catch{             
    Write-Error $_ -ErrorAction:'SilentlyContinue'             
}

if($service -ne $null){            
    try{                    
        $list = $service.GetListItems($listName, "", $query, $viewFields, $rowLimit, $queryOptions, $null)
    }            
    catch{             
        Write-Error $_ -ErrorAction:'SilentlyContinue'            
    }            
}

$output = $list.data.row

foreach ($item in $output) {
 if ($item.ows_DeploymentStatus = "Production") {
  [string]$server=$item.ows_Title
  [string]$status=$item.ows_DeploymentStatus
  "$server - $status"
  }
 }

NETMON CMD LINE

Run Windows Network Monitor from CMD

I had a confusing problem with Network Monitor 3.4. When I opened it, I got a warning about parsers not loading. Then the capture would not start saying the capture filter was invalid. Eventually I tried it from the command prompt and it worked.
NMCap /network * /capture /file output.cap:50M

6/24/2014

Isilon CLI - list serial numbers

Isilon:  CLI - list serial numbers

 
     isi_for_array -s isi_hw_status -i | grep SerNo:

5/31/2014

Useful Isilon Commands for Troubleshooting

Useful Isilon Commands for Troubleshooting




Thanks to NerdSector.com

Here are some some useful Isilon commands to assist you in troubleshooting Isilon storage array issues.

 

Grep the log for stalled drives on the isilon cluster

     cat /var/log/messages |grep -o 'stalled: [0-9,*:]*'|sort |uniq -c

(Stalled drives are bad, and can cause cluster problems. you could also run this command on the individual nodes /var/log/restripe.log )

Grep the log for stalled drives on the isilon cluster for month of Sept

grep 'Nov ' /var/log/messages |grep -o 'stalled: [0-9,*:]*'|sort |uniq -c

Use this on the restripe.log

  grep 'Nov ' /var/log/restripe.log |grep -o 'Stalled drives are \[[0-9,*:]*\]'|sort |uniq -c 

When reviewing the results of the stalled drives it is important to note that the drive numbers listed is the logical drive number and not the bay number.  You need to run the command “isi devices” on the node with the suspect drive to determine what bay the drive is actually in.

Display the SMART error log of all the drives on a given isilon node:

isi_radish -a|less

Display the current isilon Flexprotect Policy

isi get /ifs

Display the current isilon node hardware status:

isi_hw_status

Display the status of the isilon node network config

isi config

then while in the config utility

 status 

Display this list of alerts in wide format

 isi alerts -w

Start/Stop/Resume/Pause Restriper jobs

 isi restripe pause 
isi restripe start 
isi restripe stop 
 isi restripe resume -i

Display the drive status of a given isilon node

     #for node 3
     isi devices -d 3  

Display the SAS drives Physical Monitoring stats for errors

     less /var/log/isi_sasphymon.acc

Test Active Directory connections from all isilon nodes

     isi_for_array wbinfo -t

To find an open file on Isilon Windows share

     isi_for_array -q -s smbstatus | grep 
  then find the PID from the results and  then run this to get the user
     isi_for_array -q -s smbstatus -u| grep    to get the user

Note: The isi_for_array command runs the command on all of the nodes. This command will ask for the user’s password so that it can login to the other nodes and complete the command. When passing the results of a “isi_for_array” command to another command such as grep (like the example above) will require the user password so that it can be passed to the other nodes. There is no prompt for the password so you must enter it on the next line and press enter to get the results of the command.

5/15/2014

Redistribute selected static routes into OSPF

Cisco:  Redistribute Selected Static Routes into OSPF


ip access-list standard 10
10 permit 10.15.1.0 0.0.0.255
20 permit 10.15.10.0 0.0.0.255
30 permit 10.15.101.0 0.0.0.255
40 permit 10.15.201.0 0.0.0.255

route-map CLT-Routes permit 10
match ip address 10

router ospf 1
redistribute static subnets route-map CLT-Routes

ASA Site-to-Site VPN

Great overview of ASA Site-to-Site VPN:
http://www.soundtraining.net/i-t-tutorials/cisco-tutorials/47-cisco-asa-site-to-site-vpn-configs

3/20/2014

Cisco Nexus SNMP Hang

SNMP Process hangs on Cisco Nexus Switch

The SNMP process will stop responding on Nexus 5010 NXOS version 5.0(3)N2(1)
It appears upgrading to latest version is supposed to fix it.
Or a workaround is to unload the BRIDGE-MIB with the following command from config mode:
    no snmp-server load-mib dot1dbridgesnmp
(this will not persist after a reload.)

3/04/2014

Cisco ASA - Java Issues

Cisco ASA - Java Issues

recent java update caused mayhem.
coworker found that it was fixed by adding a security exception for the ASA in the Java Control Panel

Windows: Start > Control Panel > Java Control Panel
Mac: click on Java icon in System Preferences
- Go to the Security tab
- In the Exception Site List section at the bottom, click Edit Site List and add the ASA you want to manage with ASDM:   https://x.x.x.xwhere x.x.x.x is the IP address of the ASA

3/03/2014

Windows Domain Time Sync

Windows Domain Time Sync

Do the following on servers/workstations to point them to the domain as time reference and sync time:


w32tm /config /syncfromflags:DOMHIER /update
w32tm /resync /rediscover

2/21/2014

EXCEL: SUM of only visible cells

EXCEL: SUM of only visible cells

From: http://stackoverflow.com/questions/759656/how-does-one-sum-only-those-rows-in-excel-not-filtered-out

If you are 'filtering' by hiding rows, the function number should be updated to 109.
=SUBTOTAL(109,B1:B20)

The function number 109 is for the SUM function as well, but hidden rows are ignored.

Network Load Balancing in vSphere

Network Load Balancing in vSphere: NLB in vSphere

VMware KB: Microsoft NLB not working properly in Unicast Mode

VMware KB: Microsoft NLB not working properly in Unicast Mode: Microsoft NLB not working properly in Unicast Mode

VMs Setup to Use Windows NLB in Unicast Mode Lose Network Connectivity When HP Virtual Connect Module is Replaced - VirtuallyHyper

VMs Setup to Use Windows NLB in Unicast Mode Lose Network Connectivity When HP Virtual Connect Module is Replaced - VirtuallyHyper: VMs Setup to Use Windows NLB in Unicast Mode Lose Network Connectivity When HP Virtual Connect Module is Replaced

VMware KB: Microsoft Network Load Balancing Multicast and Unicast operation modes

VMware KB: Microsoft Network Load Balancing Multicast and Unicast operation modes: Microsoft Network Load Balancing Multicast and Unicast operation modes

2/18/2014

MICROSOFT Performing a Software True-up in Under 5 Minutes

Performing a Software True-up in Under 5 Minutes: Performing a Software True-up in Under 5 Minutes

Cisco Configuration Differences

See Cisco Configuration Differences

show archive config differences

Windows 2008 R2 multiprocessor HAL

Windows 2008 R2 - Switch to multiprocessor HAL

1. See the current HAL version: Open Device Manager and Expand COMPUTER Right-click the HAL and go to drivers tab and Update Driver to install a new one. 2. msconfig -> boot options -> advanced -> Confirm that the # processors is not defined there - uncheck the box. Also from here, there is option to "rescan for HAL"

2/06/2014

Wireshark Troubleshooting

Wireshark Troubleshooting Videos

There is a lot of great stuff on YouTube. By the way I find it is even more excellent to watch YouTube with my Roku. But I digress. There are a lot of Laura Chappell videos about network troubleshooting with Wireshark. Much of it is in the Laura's Lab Kit distribution at: http://llk11-2014.s3.amazonaws.com/lauraslabkit11b.zip Here is one example of a great video that demonstrates Wireshark features for troubleshooting: https://www.youtube.com/watch?v=70dRbN4Y2no&feature=player_embedded&list=UUfdeux1c9erKgFAwSpTlICA Links to others and my notes from each are available in this document: Wireshark Notes

Cisco Daisy Chained Consoles

Cisco Daisy Chain Console

Daisy Chaining from one device to another can be a great backup method to access network devices without having to have a modem (or more than one.) So, if I want to be able to get to the console on a core switch at a site after having a local contact boot it up, I could enable this by connecting a cisco rollover cable from my router to the switch. This would allow me to connect to the router over the WAN side interface and then connect to the switch from the router.

Cable to buy

Need a “rollover cable.” This is the product:
Rollover Cable
http://www.cdw.com/shop/products/StarTech.com-Cisco-Console-Rollover-Cable-RJ45-Ethernet-network-cable/2437620.aspx

Setup

  • connect rollover cable from router AUX port to Core Switch CONSOLE port
  • Config on Router:
    • line aux 0
    • transport input telnet ssh

How to use

  • Connect to router and logon
  • telnet [ROUTER IP] 2001
  • Logon
  • To exit and return to router session, type CTRL+SHIFT+6 and then hit X

1/30/2014

Run a command on every server in domain. (Powershell v2 compatible)



#############################################################################################################
#
#   run-remote.ps1
#
#   run a command on each server in the domain
#   log results to file and e-mail report of failures
#

$rcmd = "ping cmsweb"
$success = "Reply from"
$logfile = ".\run-remote.log"
$outfile = ".\cmsweb-test.html"
$rptname = "cmsweb reachability"
$recipient = "user@domain.com"

############################################################################################
# Create $list of server names for all Windows servers in Active Directory
#
$strCategory = "computer" 
$strOS = "Windows*Server*"
$objDomain = New-Object System.DirectoryServices.DirectoryEntry 
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher 
$objSearcher.SearchRoot = $objDomain
$objSearcher.Filter = ("OperatingSystem=$strOS")
$colProplist = "dnshostname"
foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}
$colResults = $objSearcher.FindAll()
foreach ($objResult in $colResults) 
 { 
  $objComputer = $objResult.Properties;  
  $Server = $objComputer.dnshostname
  $Server = $Server -replace "\s{2,}", ""
  $Server = $Server -replace "\.usa\.domain\.com", ""
  if ($Server) { $list = $list + $Server } #skip a null value
  } 
$list = $list | sort-object
###

clear-host
$today = get-date
$today | out-file $logfile

"Run:  $rcmd"
$username = read-host "Logon"
$pw = read-host -AsSecureString "Password"
$pass = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
   [Runtime.InteropServices.Marshal]::SecureStringToBSTR($pw))
############################################################################################
# Report Heading

$report=@'
<STYLE>
BODY{font-family: Verdana, Arial, Helvetica, sans-serif;font-size:12;font-color: #000000}
TABLE{border-width: 2px;padding: 1px;border-style: solid;border-color: black;border-collapse: collapse;} 
TH{border-width: 2px;padding: 1px;border-style: solid;border-color: black;background-color: #dddddd;font-size:16;font-weight:bold}
TD{border-width: 2px;padding: 2px;border-style: solid;border-color: black;background-color: #efefef; font-size:12;font-weight:normal} 
TD.error{border-width: 2px;padding: 2px;border-style: solid;border-color: black;background-color: #ffffff;font face="monospace";font-size:10;font-color: #cccccc}
</STYLE> 
<HTML> 
<HEAD> 
<TITLE></TITLE> 
</HEAD> 
<BODY> 
<H2>Server Time Issues</H2> 
<H4>
'@
$report+=$today
$report+="Command:  $rcmd"
$report+="</H4><table><th>Server</th><th>IP Number</th><th>Result</th></tr>"

############################################################################################
# Run for every server in list 


foreach ($computer in $list) {
 If (Test-Connection -computername $computer -Quiet -count 1){ #respond to ping?
  #get IP address
  $conn = test-connection -computername $computer -count 1
  $ip = $conn.IPV4Address.IPAddressToString
  "Executing remotely from $computer - $ip"
  $cmd = "c:\util\psexec.exe /acceptEula \\$computer -u $username -p $pass -w c:\ $rcmd"
  $result = invoke-expression $cmd
  if ($result -like "$success*") { #success 
   "$computer - $ip" + ": <$rcmd> -> Success" | out-file $logfile -append
#   $report+=('<tr><td>' + $computer + '</td>') 
#   $report+=('<td >$ip</td>')  
#   $report+=('<td >Success</td>')  
#   $report+=('</tr>')
   } 
  else { #fail 
   "$computer - $ip" + ": <$rcmd> -> Fail" | out-file $logfile -append
   $report+=('<tr><td>' + $computer + '</td>') 
   $report+=('<td >$ip</td>')  
   $report+=('<td >Fail</td>')  
   $report+=('</tr>')
   }
  }#end if connection
 }#end foreach computer
clear-host
notepad $logfile

$report+="</TABLE></BODY></HTML>" 

$report | out-file $outfile 

############################################################################################
#e-mail the report

$messageSubject = $rptname
$smtpServer = "smtp.domain.com"
$smtpFrom = "noreply@domain.com"
$smtpTo = $recipient
$message = $report
send-mailmessage -to $smtpTo -cc "admin@domain.com" -from $smtpFrom -subject $messageSubject -body $message -smtpserver $smtpServer -BodyAsHtml 
###

1/29/2014

NMCap: the easy way to Automate Capturing - Network Monitor - Site Home - TechNet Blogs

NMCap: the easy way to Automate Capturing - Network Monitor - Site Home - TechNet Blogs: NMCap: the easy way to Automate Capturing

newsoft's tech blog: Pentester trick #8: command-line sniffing made easy

newsoft's tech blog: Pentester trick #8: command-line sniffing made easy: command-line sniffing made easy



The most reliable and lightweight tool I know is ... the one made by Microsoft, a.k.a. Microsoft Network Monitor. It relies on Windows built-in packet capture features, therefore leaving minimal footprint on the target system. It can run without install. It works on all Microsoft-supported Windows versions, in x86, x64 and even IA64 flavors.

How to use it ?
  1. Download and install Microsoft Network Monitor on a standalone computer.
  2. Upload nmconfig.exe and nmcap.exe on the target computer.
  3. Enable the Microsoft Network Monitor Driver: nmconfig /install
  4. Test: nmcap /displaynetworks
  5. Sniff all TCP traffic on every local interface: nmcap /network * /capture tcp /File tcp.cap
  6. Disable the Microsoft Network Monitor Driver: nmconfig /uninstall
(Caveat: the capture file format is not Winpcap-compatible. However, Wireshark (and others) know how to read it.)

Technical thoughts: Dependence between ARP max age time and MAC-address aging on Cisco switches

Technical thoughts: Dependence between ARP max age time and MAC-address aging on Cisco switches: Dependence between ARP max age time and MAC-address aging on Cisco switches

1/15/2014

Check Time on VMWare Hosts

Check Time on VMware Hosts Similar to my previous script reporting on Windows Server time.

##########################################################################################
# esx-time.ps1
#
# Gather local time and time zone for all servers in AD.
# Report servers with time different from machine on which script is run
# E-Mail report to designated recipient.
#
# Requires vmware power cli
# "set-powercliconfiguration -InvalidCertificateAction Ignore" to ignore cert errors
#
#
##########################################################################################

Add-PSSnapin VMware.VimAutomation.Core  -ErrorAction SilentlyContinue

#VCS
$vcs="privcs01" # PRIVDIVC1, PRIDEVVC1, PRIVCSVDI01, SECVCS01

# E-Mail Recipient 
$recipient="administrator@DOMAIN.com"

# Greatest acceptable time difference
$maxdiff=59

$outfile = "c:\dev\esx-time.html"
$user = "usa\svc_vmware"
$pw = Read-Host "Password for $user" -AsSecureString
$rootpw = Read-Host "Password for root" -AsSecureString
#convert $pw to plain text
    $pass = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
        [Runtime.InteropServices.Marshal]::SecureStringToBSTR($pw))
#convert $rootpw to plain text
    $rootpass = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
        [Runtime.InteropServices.Marshal]::SecureStringToBSTR($rootpw))

############################################################################################
# Get List of Host Names from VCS server
#
write-host "Getting Server List from VCS"
connect-viserver -Server $vcs -User $user -Password $pass -ErrorAction SilentlyContinue > $null
$hosts = get-vmhost
disconnect-viserver -confirm:$false -ErrorAction SilentlyContinue > $null
$list = @()
foreach ($Server in $hosts) { 
  $Server = $Server -replace "\s{2,}", ""
  $Server = $Server -replace "\.usa\.DOMAIN\.com", ""
  if ($Server) { $list = $list + $Server } #skip a null value
  } 
$list = $list | sort-object
write-host "COMPLETE"
###


#clear-host
$today = get-date

############################################################################################
# Report Heading

$report=@'
<STYLE>
BODY{font-family: Verdana, Arial, Helvetica, sans-serif;font-size:12;font-color: #000000}
TABLE{border-width: 2px;padding: 1px;border-style: solid;border-color: black;border-collapse: collapse;} 
TH{border-width: 2px;padding: 1px;border-style: solid;border-color: black;background-color: #dddddd;font-size:16;font-weight:bold}
TD{border-width: 2px;padding: 2px;border-style: solid;border-color: black;background-color: #efefef; font-size:12;font-weight:normal} 
TD.error{border-width: 2px;padding: 2px;border-style: solid;border-color: black;background-color: #ffffff;font face="monospace";font-size:10;font-color: #cccccc}
</STYLE> 
<HTML> 
<HEAD> 
<TITLE></TITLE> 
</HEAD> 
<BODY> 
<H2>VMWare Host Time Issues</H2> 
<H4>
'@
$report+=$today
$report+="</H4><table><th>Server</th><th>Date</th><th>Time</th><th>Off(s)</th></tr>"

############################################################################################
# Query every server in list 

write-host "Checking each server:"

foreach ($item in $list) {
  $flag=" "
  $dt=""
  $srvtime=""
  $hour = ""
  $min = ""
  $sec = ""
  $month = ""
  $day = ""
  $year = ""
  $comp = ""
  $d = ""
  $t = ""
   $computer = $item 
  $comp = "{0,-16}" -f $computer
  $comp = $comp.padright(16," ")

write-host ">$computer<"

 If (Test-Connection -computername $computer -Quiet -count 1){ #respond to ping?
write-host "    PING - SUCCESS"
write-host "    Time Query"
  $output=""
  $block = @'
  $machine = $args[0]
  $pass = $args[1]
  Add-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue
  connect-viserver -server $machine -user "root" -password $pass -WarningAction SilentlyContinue -ErrorAction SilentlyContinue > $null
#  $time = (get-view serviceinstance).CurrentTime()
#  $time
  ((get-view serviceinstance).CurrentTime())
'@
  $sb = [scriptblock]::create($block)
  $args=@()
  $args = ($computer, $rootpass)
  start-job -name $computer -scriptblock $sb -argumentlist $args > $null
  Wait-Job -name $computer -Timeout 60 > $null 
  $output = Receive-Job $computer
#$output
  #disconnect-viserver -server $computer -confirm:$false #-ErrorAction SilentlyContinue > $null
  if ($output) {  
  $dt = $output
write-host "DT=$dt"
  }
  else {   
  write-host "$computer`tERROR:  No time Query Output"
   $report+='<tr><td class="error">' + $comp + '</td>' 
    $report+='<td colspan="4" class="error">' + "ERROR - No response to date/time query" + '</td>'  
   $report+='</tr>' 
  continue
  } # end if output
 }#end if ping
 else { # No PING response
  write-host "$computer`tERROR:  No PING Response"
   $report+='<tr><td class="error">' + $comp + '</td>' 
          $report+='<td colspan="4" class="error">' + "CONNECTION ERROR:  No response to PING" + '</td>'  
   $report+='</tr>' 
  continue
  }
 [string] $month = [System.Convert]::ToString($dt.Month)
 $month = $month.padleft(2,"0")
 [string] $day = [System.Convert]::ToString($dt.Day)
 $day = $day.padleft(2,"0")
 [string] $year = [System.Convert]::ToString($dt.Year)
 $year = $year.padleft(4,"0")
 $d = $month + "/" + $day + "/" + $year
write-host "    Date=$d"
 [string] $hour = [System.Convert]::ToString($dt.Hour)
 $hour = $hour.padleft(2,"0")
 [string] $min = [System.Convert]::ToString($dt.Minute)
 $min = $min.padleft(2,"0")
 [string] $sec = [System.Convert]::ToString($dt.Second)
 $sec = $sec.padleft(2,"0")
 $t = $hour + ":" + $min + ":" + $sec
write-host "    Time=$t"
 if ($dt) { #$dt not null
  $srvtime=($dt.Minute)*60+($dt.Second)
  $refmin = ""
  $refsec = ""
  $now = get-date
  $cmptime = ($now.Minute)*60+($now.Second)
  [string] $min = [System.Convert]::ToString($now.Minute)
  $refmin = $min.padleft(2,"0")
  [string] $sec = [System.Convert]::ToString($now.Second)
  $refsec = $sec.padleft(2,"0")
  $reftime=$refmin+":"+$refsec
  #Compare server time to script machine time.
  $diff=$cmptime-$srvtime
write-host "    Time Diff=$diff"
  if (($diff -gt $maxdiff) -or ($diff -lt (-1*$maxdiff))) { $flag="*" }
   write-host "$flag$comp`t$d`t$t`t$flag$diff$flag`t" $timezone.Description 
   if ($flag -eq "*") { #time difference is too great
    $report+=('<tr><td>' + $comp + '</td>') 
    $report+=('<td >' + $d + '</td>')  
    $report+=('<td >' + $t + '</td>')  
    $report+=('<td >' + $diff + '</td>')  
    $report+=('</tr>') 
    }
  }# end if null 
}#end foreach computer
###
$report+="</TABLE></BODY></HTML>" 

$report | out-file $outfile 

############################################################################################
#e-mail the report

$messageSubject = "VMWare Host Time Report"
$smtpServer = "smtp.DOMAIN.com"
$smtpFrom = "noreply@DOMAIN.com"
$smtpTo = $recipient
$message = $report
send-mailmessage -to $smtpTo -from $smtpFrom -subject $messageSubject -body $message -smtpserver $smtpServer -BodyAsHtml 
###


remove-job * -force

1/03/2014

Putting code example in HTML documents

Use the XMP tag
<pre><code><xmp>
   ...code...
</xmp></code></pre>

Powershell Format Operator

Powershell Format Operator "-f"




OperatorExampleResultsDescription


{0}Display a particular element"{0} {1}" -f "a", "b"a b
{0:x}Display a number in Hexadecimal"0x{0:x}" -f 1813420x2c45e
{0:X}Display a number in Hexadecimal uppercase"0x{0:X}" -f 1813420x2C45E
{0:dn}Display a decimal number left justified, padded with zeros"{0:d8}" -f 300000003
{0:p}Display a number as a percentage"{0:p}" -f .12312.30 %
{0:c}Display a number as currency"{0:c}" -f  12.34$12.34
{0,n}Display with field width n, left aligned"|{0,5}|" -f "hi"|   hi|
{0,-n}Display with field width n, right aligned"|{0,-5}| -f "hi"|hi   |
{0:hh}
{0:mm}
Display the hours and minutes from a date time value"{0:hh}:{0:mm}" -f (Get-Date)01:34
{0:C}Display using the currency symbol for the current culture"|{0,10:C}|" -f 12.3|  $12.40|

1/02/2014

Powershell:  WMI Timeouts locking up scripts

There are a few folks with suggestions out there.  One is to use a job to run the query.  Unfortunately this leaves those jobs stuck out there so if a lot of my servers have WMI screwed up I suppose doing this could crash my management machine.
This example is to get the current time and time zone from every server machine in my AD domain. 

##########################################################################################
# CHECK-TIME.PS1
#
# Gather local time and time zone for all servers in AD.  Convert times to GMT & compare
# Report servers with time different from machine on which script is run
# E-Mail report to designated recipient.
#
##########################################################################################


# E-Mail Recipient 
$recipient="user@domain.com"

# Greatest acceptable time difference
$maxdiff=59

$outfile = "c:\dev\check-time.html"
If (Test-Path $outfile){
	Remove-Item $outfile
}

$logfile = "c:\dev\check-time.log"
If (Test-Path $logfile){
	Remove-Item $logfile
}

$mytimezone = get-wmiobject Win32_Computersystem -property CurrentTimeZone, daylightineffect
$myoffset = $mytimezone.CurrentTimeZone #GMT offset in minutes
$mydst = $mytimezone.daylightineffect
   if ($mydst) {
   	$myoffset+=60
   	}

##########################################################################################
# FUNCTION:  Check for TCP response on $port

function Test-Port {  
    Param(  
      [string] $srv,  
      $port=135,  
      $timeout=1500,  
      [switch]$verbose  
    )  
    # TCP connect $port
    $ErrorActionPreference = "SilentlyContinue"
    $tcpclient = new-Object system.Net.Sockets.TcpClient 
    $iar = $tcpclient.BeginConnect($srv,$port,$null,$null) 
    $wait = $iar.AsyncWaitHandle.WaitOne($timeout,$false) 
    # Check to see if the connection is done 
    if(!$wait) 
    { 
    # Close connection, report timeout 
    $tcpclient.Close()  
        if($verbose){write-host "Connection Timeout" }  
        Return $false  
    }  
    else  
    {  
        # Close connection, report any error
         $error.Clear()  
         $tcpclient.EndConnect($iar) | out-Null  
         if(!$?){if($verbose){write-host $error[0]};$failed = $true}  
         $tcpclient.Close()  
     }  
     # Return $true if connection established  
      if($failed){  
          return $false  
      } else {  
          return $true  
      }  
    } # http://technet.microsoft.com/en-us/library/ff730959.aspx


#
# End of functions
##########################################################################################


############################################################################################
# Create $list of server names for all Windows servers in Active Directory
#
$strCategory = "computer" 
$strOS = "Windows*Server*"
$objDomain = New-Object System.DirectoryServices.DirectoryEntry 
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher 
$objSearcher.SearchRoot = $objDomain
$objSearcher.Filter = ("OperatingSystem=$strOS")
$colProplist = "dnshostname"
foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}
$colResults = $objSearcher.FindAll()
foreach ($objResult in $colResults) 
 { 
  $objComputer = $objResult.Properties;  
  $Server = $objComputer.dnshostname
  $Server = $Server -replace "\s{2,}", ""
  $Server = $Server -replace "\.usa\.domain\.com", ""
  if ($Server) { $list = $list + $Server } #skip a null value
  } 
$list = $list | sort-object
###

clear-host
$today = get-date

############################################################################################
# Report Heading

$report=@'
<STYLE>
BODY{font-family: Verdana, Arial, Helvetica, sans-serif;font-size:12;font-color: #000000}
TABLE{border-width: 2px;padding: 1px;border-style: solid;border-color: black;border-collapse: collapse;} 
TH{border-width: 2px;padding: 1px;border-style: solid;border-color: black;background-color: #dddddd;font-size:16;font-weight:bold}
TD{border-width: 2px;padding: 2px;border-style: solid;border-color: black;background-color: #efefef; font-size:12;font-weight:normal} 
TD.error{border-width: 2px;padding: 2px;border-style: solid;border-color: black;background-color: #ffffff;font face="monospace";font-size:10;font-color: #cccccc}
</STYLE> 
<HTML> 
<HEAD> 
<TITLE></TITLE> 
</HEAD> 
<BODY> 
<H2>Server Time Issues</H2> 
<H4>
'@
$report+=$today
$report+="</H4><table><th>Server</th><th>Date</th><th>Time</th><th>Off(s)</th><th>Time Zone</th></tr>"

############################################################################################
# Query every server in list 

foreach ($result in $list) {
	 $flag=" "
	 $timezone=""
	 $dt=""
	 $srvtime=""
	 $hour = ""
	 $min = ""
	 $sec = ""
	 $comp = ""
	 $d = ""
	 $t = ""
 	 $computer = $result 
	 $comp = "{0,-16}" -f $computer
	 $comp = $comp.padright(16," ")
#write-host ("$Computer"+":") 
#("$Computer"+":")|out-file $logfile -append
	If (Test-Connection -computername $computer -Quiet -count 1){ #respond to ping?
	    $a = Test-Port $computer 
	    $dst=""
	    $timezone=""
	    $output=""
	    $offset=""
	    if ($a) { # resonds on RPC?
		#timezone
			$block = "get-wmiobject Win32_Computersystem -computer $computer -property CurrentTimeZone, daylightineffect"
			$sb = [scriptblock]::create($block)
			start-job -name $computer $sb > $null
			Wait-Job -name $computer -Timeout 10 > $null
			$output = Receive-Job $computer
			$block = "Get-WmiObject -class Win32_TimeZone -ComputerName $computer"
			$sb = [scriptblock]::create($block)
			start-job -name $computer $sb > $null
			Wait-Job -name $computer -Timeout 10 > $null
			$timezonedesc = Receive-Job $computer
			$tz = $timezonedesc.description
			if ($output -ne $null) {  
			    $timezone = $output
			    $offset = $timezone.CurrentTimeZone #GMT offset in minutes
			    $dst = $timezone.daylightineffect
			    if ($dst) {
			    	$offset+=60
			    	}
				 }
			else {   
			write-host "$computer`tERROR:  No WMI Query Output"
			"$computer`tERROR:  No WMI Query Output" | out-file $logfile -append
			 $report+='<tr><td class="error">' + $comp + '</td>' 
		         $report+='<td colspan="4" class="error">' + "WMI ERROR - No response to timezone query" + '</td>'  
			 $report+='</tr>' 
			continue
			}#end if output
		#date/time
			$block = "Get-WmiObject -class win32_localtime -ComputerName $computer"
			$sb = [scriptblock]::create($block)
			start-job -name $computer $sb > $null
			Wait-Job -name $computer -Timeout 10 > $null 
			$output = Receive-Job $computer
			if ($output -ne $null) {  
			$dt = $output
			}
			else {   
			write-host "$computer`tERROR:  No WMI Query Output"
			"$computer`tERROR:  No WMI Query Output" | out-file $logfile -append
			 $report+='<tr><td class="error">' + $comp + '</td>' 
		         $report+='<td colspan="4" class="error">' + "WMI ERROR - No response to date/time query" + '</td>'  
			 $report+='</tr>' 
			continue
			} # end if output
	    }#end if port
	    else {# No response on port
		write-host "$computer`tERROR:  No RPC Response"
		"$computer`tERROR:  No RPC Response" | out-file $logfile -append
		 $report+='<tr><td class="error">' + $comp + '</td>' 
	         $report+='<td colspan="4" class="error">' + "RPC ERROR - No response on port " + $port + '</td>'  
		 $report+='</tr>' 
		continue
		}    
	}#end if ping
	else { # No PING response
		write-host "$computer`tERROR:  No PING Response"
		"$computer`tERROR:  No PING Response" | out-file $logfile -append
		 $report+='<tr><td class="error">' + $comp + '</td>' 
	         $report+='<td colspan="4" class="error">' + "CONNECTION ERROR:  No response to PING" + '</td>'  
		 $report+='</tr>' 
		continue
		}
	[string] $month = [System.Convert]::ToString($dt.Month)
	[string] $day = [System.Convert]::ToString($dt.Day)
	[string] $year = [System.Convert]::ToString($dt.Year)
	[string] $hour = [System.Convert]::ToString($dt.Hour)
	$hour = $hour.padleft(2,"0")
	[string] $min = [System.Convert]::ToString($dt.Minute)
	$min = $min.padleft(2,"0")
	[string] $sec = [System.Convert]::ToString($dt.Second)
	$sec = $sec.padleft(2,"0")
	$d = $month + "/" + $day + "/" + $year
	$t = $hour + ":" + $min + ":" + $sec
	if ($dt) { #$dt not null
		#convert to object
		$dObj = get-date "$d $t"
		#adjust to GMT
		$srvtime=$dObj.addminutes(-$offset)
#write-host "    $computer time=$srvtime"	
#"    $computer time=$srvtime" | out-file $logfile -append
		$now = get-date
		$cmptime = $now.addminutes(-$myoffset)
		[string] $min = [System.Convert]::ToString($now.Minute)
		$diff = $cmptime-$srvtime
		$diff = $diff.totalseconds
		$diff = [decimal]::round($diff)
		if (($diff -gt $maxdiff) -or ($diff -lt (-1*$maxdiff))) { $flag="*" }
			write-host "$flag$comp`t$d`t$t`t$flag$diff$flag`t$tz"
			"$flag$comp`t$d`t$t`t$flag$diff$flag`t$tz" | out-file $logfile -append
			$zone = $timezonedesc.Description.tostring()
			if (-not($timezonedesc )) { #no zone returned
				$flag="*"
				$zone = "ERROR:  Invalid Time Zone Response"
				write-host "*$zone*"
				"*$zone*" | out-file $logfile -append
				}
			if ($flag -eq "*") { #time difference is too great
				$report+=('<tr><td>' + $comp + '</td>') 
				$report+=('<td >' + $d + '</td>')  
				$report+=('<td >' + $t + '</td>')  
				$report+=('<td >' + $diff + '</td>')  
				$report+=('<td >' + $zone + '</td>')  
				$report+=('</tr>') 
				}
	 }# end if null 
}#end foreach computer
###
$report+="</TABLE></BODY></HTML>" 

$report | out-file $outfile 

############################################################################################
#e-mail the report

$messageSubject = "Server Time Report"
$smtpServer = "smtp.domain.com"
$smtpFrom = "noreply@domain.com"
$smtpTo = $recipient
$message = $report
send-mailmessage -to $smtpTo -cc "admin@domain.com" -from $smtpFrom -subject $messageSubject -body $message -smtpserver $smtpServer -BodyAsHtml 
###
remove-job * -force

Dealing with WMI Timeouts — Steven Murawski

Dealing with WMI Timeouts — Steven Murawski: Dealing with WMI Timeouts

Get-WmiCustom (aka: Get-WMIObject with timeout!) - musc@> $daniele.work.ToString() - Site Home - MSDN Blogs

Get-WmiCustom (aka: Get-WMIObject with timeout!) - musc@> $daniele.work.ToString() - Site Home - MSDN Blogs: Unfortunately, the Get-WmiObject cmdlet does not let you specify a timeout. Therefore I cooked my own function which has a compatible behaviour to that of Get-WmiObject, but with an added “-timeout” parameter which can be set.

Function Get-WmiCustom([string]$computername,[string]$namespace,[string]$class,[int]$timeout=15) 
{ 
$ConnectionOptions = new-object System.Management.ConnectionOptions 
$EnumerationOptions = new-object System.Management.EnumerationOptions 

$timeoutseconds = new-timespan -seconds $timeout 
$EnumerationOptions.set_timeout($timeoutseconds) 

$assembledpath = "\\" + $computername + "\" + $namespace 
#write-host $assembledpath -foregroundcolor yellow 

$Scope = new-object System.Management.ManagementScope $assembledpath, $ConnectionOptions 
$Scope.Connect() 

$querystring = "SELECT * FROM " + $class 
#write-host $querystring 

$query = new-object System.Management.ObjectQuery $querystring 
$searcher = new-object System.Management.ManagementObjectSearcher 
$searcher.set_options($EnumerationOptions) 
$searcher.Query = $querystring 
$searcher.Scope = $Scope 

trap { $_ } $result = $searcher.get() 

return $result 
}