Monthly Archive

Categories

Monthly Archives: August 2011

Outlook: removing calendar entries

We recently looked at dumping the Calendar entries

http://msmvps.com/blogs/richardsiddaway/archive/2011/08/23/outlook-viewing-calendar-entries.aspx

 

I usually leave entries to build up in the Calendar but a simple clean operation is to delete everything that occurred before a certain date

function remove-calendaritem {            
param (            
 [datetime]$date            
)            
$outlook = New-Object -ComObject Outlook.Application            
            
get-mailfolders |             
where {$_.Path -like "*calendar*" -and $_.Path -notlike "*birthday*"} |            
foreach {            
  $targetfolder = $outlook.Session.GetFolderFromID($_.EntryID, $_.StoreID)            
              
  $targetfolder.Items | foreach {            
    if ($_.StartTime -lt $date){$_.Delete()}            
  }             
}            
}

The date parameter defines the date for which we want to delete all earlier entries. Get the calendar folders and test the StartTime of each entry. If its before our date then delete it.

Network Adapter details

In this post - http://msmvps.com/blogs/richardsiddaway/archive/2011/07/09/linking-the-network-card-to-the-registry-settings.aspx – I showed how to get the NetLuidIndex by linking the network card to the matching registry settings.  There is another way to get some that same information.

function get-adapter {            
param(            
 [string]$computer="."            
)            
Get-WmiObject -Namespace root\wmi -Class MSNdis_EnumerateAdapter `
-ComputerName $computer |            
foreach {            
 $nic = Get-WmiObject -Namespace root\wmi -Class MSNdis_EnumerateAdapterEx `
-ComputerName $computer -Filter "InstanceName = '$($_.InstanceName)'"            
            
$header = $nic.EnumerateAdapter.Header            
            
 New-Object -TypeName PSobject -Property @{            
  Computer = $_.__SERVER            
  Adapter = $_.InstanceName            
  Device = $_.DeviceName            
  Active = $_.Active            
  Index = $($nic.EnumerateAdapter.IfIndex)            
  NetLuid = $($nic.EnumerateAdapter.NetLuid)            
  Revision = $header.Revision            
  Size = $header.Size            
  Type = $header.Type            
 }            
}            
}

Use the MSNdis_EnumerateAdapter  class to get the adapters and match to the MSNdis_EnumerateAdapterEx  class on the Instance name. Not sure what size and type signify but they are identical on all adapters on my Windows 7 machines.

 

NOTE: The Index property is NOT the same as the DeviceId/Index property on the Win32_NetworkAdapter\Win32_NetworkAdapterConfiguration classes.

Testing the network speed

In the last post I showed how to use the MSNdis_LinkSpeed class. Digging into the class information I found a suggestion that the speed returned was in Kbps. The answers didn’t look right especially when they suggested my wireless network was running at 540Mbps!

At bit of experimentation produced this

function test-linkspeed{            
param(            
 [string]$computer="."            
)            
            
Get-WmiObject -Namespace root\wmi -Class MSNdis_LinkSpeed `
-ComputerName $computer |             
foreach {            
 $nic = Get-WmiObject -Class Win32_NetworkAdapter `
 -ComputerName $computer -Filter "Name = '$($_.InstanceName)'"            
            
New-Object -TypeName PSObject -Property @{            
 Name = $_.InstanceName            
 NdisLinkSpeed = $_.NdisLinkSpeed            
 TestNdis = $_.NdisLinkSpeed / 10000            
 Speed = $nic.Speed            
 Test = $nic.Speed / 1000000            
} | select Name, NdisLinkSpeed, TestNdis, Test, Speed            
            
}            
            
}

Use the MSNdis_LinkSpeed class as before. Pipe into foreach and get the corresponding Win32_NetworkAdapter class. I know that the speed reported there is in bits per second. Create an object that shows the speeds reported by the two classes, convert Win32_NetworkAdapter speed to Mbps and play around with the divisor for Ndis speed until it matches. Turns out MSNdis_LinkSpeed reports in 100s of bits per second.

Odd but fun

Network Link Speed

The root\wmi Namespace contains a class that just returns the link speed of your network card. Quick and easy to use function.

function get-linkspeed{            
param(            
 [string]$computer="."            
)            
Get-WmiObject -Namespace root\wmi -Class MSNdis_LinkSpeed `
-ComputerName $computer |             
select InstanceName, @{N="Speed(Mbps)"; E={$_.NdisLinkSpeed/10000}}            
            
}

The documentation I could find suggested that the NdisLinkSpeed property returned Kbps but that gave some odd results. Experimentation and a bit more research suggested I needed to divide by 10000.

Mailbox database status

 

A recent forum post on mailbox database status in Exchange 2007  proved interesting.

If I do this

PS> Get-MailboxDatabase -Status | select Name, server, storagegroup, mounted

Name Server StorageGroup
---- ------ ------------
MailDatabase EXCH07 EXCH07\Test1
MDB01 EXCH07 EXCH07\SG1
MDB02 EXCH071 EXCH071\SG2

but if I do this

PS> Get-MailboxDatabase -Status | select Name, server, storagegroup, mounted | fl *

Name : MailDatabase
Server : EXCH07
StorageGroup : EXCH07\Test1
Mounted : True

I get the mounted property. The help file says you have to use the format cmdlets to see the results of the status property

So if you want to work with the Mounted property  (or the BackupInProgress or OnlineMaintenanceInProgress properties)

You need to do something like this

Get-MailboxDatabase -Status | foreach {
$status = $_ | select -ExpandProperty Mounted
if ($status) {Write-Host "$($_.Identity) is Mounted"}
else {Write-Host "$($_.Identity) is not Mounted"}

}

The value is only visible if you use the –status switch AND you have to either use the format cmdlets or   seelct -expandproperty to be able to work with the property.

Awkward but usable.

Outlook: Viewing Calendar Entries

We have seen how to view emails – this is how to view items in your calendar

function get-calendaritem {            
            
$outlook = New-Object -ComObject Outlook.Application            
            
get-mailfolders |             
where {$_.Path -like "*calendar*" -and $_.Path -notlike "*birthday*"} |            
foreach {            
  $targetfolder = $outlook.Session.GetFolderFromID($_.EntryID, $_.StoreID)            
              
  $targetfolder.Items | foreach {            
   New-Object -TypeName PSObject -Property @{            
    Folder = $targetfolder.FolderPath            
    StartTime = $_.Start            
    EndTime = $_.End            
    Organizer = $_.Organizer            
    Subject = $_.Subject            
    Location =$_.Location            
   }            
  }             
}            
}

Use the get-mailfolders function we developed earlier. Filter for the calendar folders. For each of them get the folder and strip the appropriate properties from the entry. Create an object and display

TechEd Australia PowerShell conference

Tuesday August 30th 2011 at 9am EST there is a PowerShell conference at TechEd Australia. 

Details from

http://powershelldownunder.com/featured/teched2011/

The sessions will be available via Live meeting please register at above URL

Ping a subnet

I recently needed to find which IP addresses were active on a subnet to track down a printer. Quickest way was to ping them.

 

function ping-subnet {            
param (            
 [parameter(Mandatory=$true)]            
 [ValidatePattern("\b\d{1,3}\.\d{1,3}\.\d{1,3}\b")]            
 [string]$subnet            
)            
            
0..255 | foreach {             
             
 $address = "$subnet.$_"            
            
 if (Test-Connection -ComputerName $address -Count 1 -Quiet){            
    Test-Connection -ComputerName $address -Count 1            
 }            
            
}            
}

 

Put the subnet in as a parameter. Then work through 0 – 255 building an address from the subnet. use test-connection in quiet mode and if it responds do a 1 count test-connection (ping) to get the result.

Not necessarily the quickest but it was quick to throw together and it works

Create a process on a remote machine

We cam use the [wmiclass] to create a process but it doesn’t allow us to set the credentials. We can get round that by using a bit of .NET code. [wmiclass] is as accelerator for System.Management.ManagementClass so we go back to basics

function new-process {            
param (            
 [string]$computer="localhost",            
 [string]$procpath="C:\Program Files\Internet Explorer\iexplore.exe"            
)            
            
$conopt = New-Object System.Management.ConnectionOptions             
            
switch ($computer ) {            
 "."         {break}            
 "localhost" {break}            
 "$env:COMPUTERNAME" {break}            
 default {            
           $cred = Get-Credential            
           $conopt.UserName = $cred.UserName            
           $conopt.SecurePassword = $cred.Password            
         }            
}            
$conopt.EnablePrivileges = $true            
            
$scope = New-Object System.Management.ManagementScope             
$scope.Path = "\\$computer\root\cimv2"             
$scope.Options = $conopt             
            
$path = New-Object System.Management.ManagementPath            
$path.ClassName = "Win32_Process"              
            
$proc = New-Object System.Management.ManagementClass($scope, $path, $null)             
            
$proc.Create($procpath)             
}

 

The computer name and path to the exe we want to run are given as parameters. We create the System.Management.ConnectionOptions. If we are  targeting a remote machine we can add the credentials (doesn’t work for local machine). The switch simplifies the coding of avoid local machine

 

The scope and management path (name space and class) are set and then we create a new instance of the class. We can then use the Create method to create the process.

Ethernet Errors

While we are looking at the MSNdis_Ethernet* classes we should consider these three that pick up potential problems

MSNdis_EthernetReceiveErrorAlignment
MSNdis_EthernetOneTransmitCollision
MSNdis_EthernetMoreTransmitCollisions

 

If all is well we will get an answer of zero for each of them – no errors and no collisions. Its a bit awkward working through each class in turn and we get a lot of “noise” returned so the following function concatenates the results.

function test-etherneterror {            
param(            
 [string]$computer="."            
)            
Get-WmiObject -Namespace root\wmi -Class MSNdis_EthernetReceiveErrorAlignment `
-ComputerName $computer |            
foreach {            
                
  $one = Get-WmiObject -Namespace root\wmi  `
  -Class MSNdis_EthernetOneTransmitCollision -ComputerName $computer `
  -Filter "InstanceName='$($_.InstanceName)'"            
            
  $more = Get-WmiObject -Namespace root\wmi  `
  -Class MSNdis_EthernetMoreTransmitCollisions -ComputerName $computer `
  -Filter "InstanceName='$($_.InstanceName)'"            
            
  New-Object -TypeName PSobject -Property @{            
  Computer = $_.__SERVER            
  Adapter = $_.InstanceName            
  ReceiveError = $_.NdisEthernetReceiveErrorAlignment            
  OneCollision = $one.NdisEthernetOneTransmitCollision            
  MoreCollision = $more.NdisEthernetMoreTransmitCollisions            
 }            
}            
}

Start by getting the members of the MSNdis_EthernetReceiveErrorAlignment  class. Loop through them and get the related MSNdis_EthernetOneTransmitCollision  and MSNdis_EthernetMoreTransmitCollisions classes.

 

Create an object for output