Modem.psm1
$MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = { Write-Host "Module Modem.psm1 removed on $(Get-Date)" } $MyInvocation.MyCommand.ScriptBlock.Module.AccessMode = "readonly" [String]$result = '0' [String]$name = 'minutes' function Get-Modem { <# .SYNOPSIS Display GPRS online activity from selected date. .DESCRIPTION The Get-Modem cmdlet scans the Internet Explorer Event log for events relating to GPRS online activity, specifically events 5003 (Connect) and 5004 (Disconnect), generated via Huawei USBs; a Balloon Tip appearing in the Navigation area when the SIM card has 5 days remaining before expiry. It is necessary to install the Network Monitor Service (from the website below) as this writes an event 300 to the Internet Explorer Event Log whenever offline status is detected with details of the data transmitted and Adapter in use. .EXAMPLE Get-Modem -After 23/10/2017 -Verbose Display GPRS online activity from selected date. Shows all online times since 23/10/2017 with individual entries displayed. In the rare cases of Connect and Disconnect events not being logged in the IE Event Log, the former will be suffixed with '#' and the latter with '*' in any -Verbose display; these times therefore not being 100% accurate. PS D:\Scripts> Get-Modem -After 23/10/2017 -Verbose VERBOSE: Command activation - User [Peter] Computer [SEA3-W12GOLNKFB] VERBOSE: Network Monitor - Running Calculating total connect time of all GPRS modem devices... VERBOSE: Disconnect at: 25/10/2009 18:55:50. Online - 00:45:56 minutes VERBOSE: Connect at: 25/10/2009 18:09:54. VERBOSE: Disconnect at: 25/10/2009 13:52:55. Online - 00:30:32 minutes* VERBOSE: Connect at: 25/10/2009 13:22:23. VERBOSE: Disconnect at: 24/10/2009 19:19:56. Online - 00:33:53 minutes VERBOSE: Connect at: 24/10/2009 18:46:03. VERBOSE: Disconnect at: 24/10/2009 13:48:03. Online - 00:11:12 minutes VERBOSE: Connect at: 24/10/2009 13:36:51. VERBOSE: Disconnect at: 24/10/2009 13:30:56. Online - 00:20:08 minutes# VERBOSE: Connect at: 24/10/2009 13:10:48. Total online usage since Monday 23 October 2017 is 02:21:41 hours (7 Mb). VERBOSE: Data values: Download = 5.716 Mb, Upload = 1.175 Mb (Sessions = 5) VERBOSE: SIM card will expire in 28 days on Wednesday, 29 November 2017 .EXAMPLE Get-Modem -Today Lists entries for today only and also invokes the Verbose switch for more detail (NOTE: should both the -Today and -After parameters be used together, the former will always take preference). PS D:\Scripts> Get-Modem -Today VERBOSE: Command activation - User [Peter] Computer [SEA3-W12GOLNKFB] VERBOSE: Network Monitor - Running Calculating total connect time of all GPRS modem devices... VERBOSE: Disconnect at: 06/11/2009 20:43:22. Online - 00:25:47 minutes VERBOSE: Connect at: 06/11/2009 20:17:35. Total online usage for today Friday 06 November 2009 is 00:25:47 minutes (0 Mb). VERBOSE: Data values: Download = 0.000 Mb, Upload = 0.000 Mb (Sessions = 1) VERBOSE: SIM card will expire in 25 days on Wednesday, 29 November 2017 .EXAMPLE Get-Modem -Hours 2:20:00 Add or subtract an extra amount of time to or from the total. For example, if the same SIM card has had time deducted when used on another computer. To subtract an amount of time just use a leading '-': Get-Modem -Hours -01:10:00 in this case. PS D:\Scripts> Get-Modem -Hours 2:20:00 Calculating total connect time of all GPRS modem devices... Total online usage since Tuesday 03 November 2009 is 10:20:54 hours (7 Mb). (including 02:20:00 hours adjustment time) .EXAMPLE Get-Modem -Month 15/11/2017 Reset the default monthly date. Note that it will be necessary to restart the current PowerShell session to activate this new date. Any dates after today will be invalid. PS D:\Scripts> Get-Modem -Month 15/11/2017 WARNING: [Get-Usb] Creating new default GPRS (Monthly) search date New default GPRS (Monthly) search date created for: 15/11/2017. Restart PowerShell to activate. .NOTES Twenty five days after the date set with the -Month switch, a reminder message will appear in the Notification Area and will reappear each day until the 30 days has expired. Additionally, whenever the -Verbose switch is in use, this will also indicate the day when the SIM will expire and the number of days until then (NOTE: these messages can always be suppressed by resetting the default '-Limit' from 30 to a larger number). If an -Adjust value is to be permanently added, an Alias function can be included to accomplish this: function GPRS { Invoke-Expression "Get-Modem -Adjust 01:01:01 $args" } This must also be included in the Manifest FunctionsToExport = 'GPRS' The -Device parameter may be used to select download/upload data from a different device; the default being 'Adapter: Remote NDIS*'. Note the final '*' as a wildcard character. .LINK Http://www.SeaStar.co.nf #> [CmdletBinding()] param ( [String]$eap = $errorActionPreference, [String]$next = '5004', #We need a DISCONNECT event to start with. Otherwise ONLINE. [String]$_tag, [String]$disconn, [String]$connect, [ValidateNotNullOrEmpty()] [ValidateRange(30,100)] [Int]$limit = 30, [Alias("From")] [ValidateNotNullOrEmpty()] [String]$after = $env:dtac, [ValidateNotNullOrEmpty()] [Parameter(position=0)] [String]$month = '00/00/0000', #Format will be checked before use. [ValidateNotNullOrEmpty()] [Alias("Hours")] [String]$adjust ='00:00:00', #Format will be checked before use. [Switch]$today, [Int]$count = 0, [Double]$download = 0.0, [Double]$upload = 0.0, [ValidateNotNullOrEmpty()] [String]$device = "Adapter: Remote NDIS*", #Input must end with * here. [String]$pattern = "^.*(?<adapter>Adapter: .*\)).*= -?(?<down>(\d+\W\d+)).*= -?(?<up>(\d+\W\d+)).*$" ) [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") $GLOBAL:notifyIcon = New-Object System.Windows.Forms.NotifyIcon $GLOBAL:notifyIcon.Icon = [System.Drawing.SystemIcons]::Information $GLOBAL:notifyIcon.BalloonTipIcon = "Info" #Symbol for message. $GLOBAL:notifyIcon.BalloonTipTitle = "Get-Modem SIM information" function convert ([String]$dateUK) { $temp = $dateUK.Split("/ ") [DateTime]$new = $temp[1] + '/' + $temp[0] + '/' + $temp[2] [String]$weekday = "{0:dddd, }" -f [DateTime]$new [String]$after = $weekday + $new.ToLongDateString() } function AddTime ([String]$hhmmss) { $PRIVATE:PrivateData = $MyInvocation.MyCommand.Module.PrivateData [Int]$h = $MyInvocation.MyCommand.Module.PrivateData['h'] [Int]$m = $MyInvocation.MyCommand.Module.PrivateData['m'] [Int]$s = $MyInvocation.MyCommand.Module.PrivateData['s'] if ($hhmmss -match '^\d+:[0-5][0-9]:[0-5][0-9]$') { $plus = $hhmmss.Split(':') $h+= $plus[0] $m+= $plus[1] $s+= $plus[2] if ($s -gt 59) { [Int]$min = $s/60 [Int]$sec = $s%60 $m+= $min $s = $sec } if ($m -gt 59) { [Int]$hour = $m/60 [Int]$min = $m%60 $h+= $hour $m = $min } $MyInvocation.MyCommand.Module.PrivateData['h'] = $h $MyInvocation.MyCommand.Module.PrivateData['m'] = $m $MyInvocation.MyCommand.Module.PrivateData['s'] = $s $SCRIPT:result = "{0:D3}:{1:D2}:{2:D2}" -f $h, $m, $s $content = '^(-?)(0)(\d+:\d\d:\d\d)$' $SCRIPT:result = $result -replace $content, '$1$3' } } function SubtractTime ([String]$hhmmss) { $PRIVATE:PrivateData = $MyInvocation.MyCommand.Module.PrivateData [Int]$h = $MyInvocation.MyCommand.Module.PrivateData['h'] [Int]$m = $MyInvocation.MyCommand.Module.PrivateData['m'] [Int]$s = $MyInvocation.MyCommand.Module.PrivateData['s'] if ($hhmmss -match '^\d+:[0-5][0-9]:[0-5][0-9]$') { $minus = $hhmmss.Split(':') if (($s - [Int]$minus[2]) -lt 0) { $s+= (60 - [Int]$minus[2]) [Int]$minus[1]+= 1 } else { $s = $s - [Int]$minus[2] } if (($m - [Int]$minus[1]) -lt 0) { $m+= (60 - [Int]$minus[1]) [Int]$minus[0]+= 1 } else { $m = $m - [Int]$minus[1] } $h = $h - $minus[0] $MyInvocation.MyCommand.Module.PrivateData['h'] = $h $MyInvocation.MyCommand.Module.PrivateData['m'] = $m $MyInvocation.MyCommand.Module.PrivateData['s'] = $s $SCRIPT:result = "{0:D3}:{1:D2}:{2:D2}" -f $h, $m, $s $content = '^(-?)(0)(\d+:\d\d:\d\d)$' $SCRIPT:result = $SCRIPT:result -replace $content, '$1$3' } } if ($month -ne '00/00/0000') { if ($month -match '^(0?[1-9]|1[0-9]|2[0-9]|3[01])/(0?[1-9]|1[0-2])/(201[78])$') { $now = Get-Date #Will produce today's date. $runDate = (Get-Date $month).Date if ($runDate -le $now) { Write-Warning "[Get-Usb] Creating new default GPRS (Monthly) search date" Write-Host "New default GPRS (Monthly) search date created for: $month. Restart PowerShell to activate." [Environment]::SetEnvironmentVariable("DTAC","$month","User") #Everything valid so change the date and quit now. } else { Write-Warning "Monthly default date must be today or earlier." } } else { Write-Warning "Format '$month' is invalid. Use 'dd/mm/2017' only." } return } if ($today) { [String]$SCRIPT:result = 0 $verbosePreference = 'Continue' $after = ([DateTime]::Now).ToShortDateString() } if ($after -notmatch '^(0?[1-9]|1[0-9]|2[0-9]|3[01])/(0?[1-9]|1[0-2])/(201[78])$') { if ($env:dtac -eq $null) { #We will get this message on a first time run only. Write-Warning "Use the -Month option to create a valid start date." } else { Write-Warning "Format '$after' is invalid. Use 'dd/M/2017' only. Terminating..." } return } $ErrorActionPreference = 'Stop' try { $_network = (Get-Service -Name NetMonitor).status #Will fail if service not installed. } catch { $_network = "Not installed" } $ErrorActionPreference = $eap Write-Verbose "Command activation - User [$($env:USERNAME)] Computer [$($env:COMPUTERNAME)]" Write-Verbose "Network Monitor - $_network" Write-Host "Calculating total connect time of all GPRS modem devices..." $MyInvocation.MyCommand.Module.PrivateData['h'] = 0 #Clear totals otherwise they are added again! $MyInvocation.MyCommand.Module.PrivateData['m'] = 0 $MyInvocation.MyCommand.Module.PrivateData['s'] = 0 $log = Get-EventLog -LogName 'Internet Explorer' -After $after $log | Where-Object {($_.eventID -eq '5004') -or ($_.eventID -eq '5003') -or ($_.eventID -eq '300') } | ForEach-Object { $MyObject = $_ switch ($_.EventID) { '5004' { #Check DISCONNECT events. We need earliest so ignore rest. if ($next -ne '5004') { #Remove next line for latest event. $disconn = $MyObject.TimeWritten.ToString() $_tag = '*' break } $disconn = $MyObject.TimeWritten.ToString() $next = '5003' } '5003' { #Check CONNECT events. We need the earliest one here. if ($next -ne '5003') { $connect = $myObject.TimeWritten.ToString() $_tag = '#' break } $connect = $myObject.TimeWritten.ToString() $subtract = New-TimeSpan $connect $disconn if ($subtract.TotalSeconds -gt 3599) { $show = 'hours' } else { $show = 'minutes' } AddTime $subtract $next = '5004' Write-Verbose "Disconnect at $disconn. Online - $subtract $show$_tag" Write-Verbose " Connect at $connect." $_tag = '' $count+= 1 } '300' { if (!$MyObject.Message.Contains(' WiFi ')) { if (($MyObject.Message -match $pattern) -and ($matches.adapter -like $device)) { $download+= $matches.down $upload+= $matches.up } } } } } if ((Get-UIculture).Name -eq 'en-US' -and (Get-Culture).Name -eq 'en-GB') { convert $after } [String]$sum = "{0:N0}" -f ($upload + $download) #Format for output. if ($adjust -ne '00:00:00') { #An adjust value has been added. if ($adjust -match '^([-+]?[0-9]?[0-9]):([0-5][0-9]):00$') { $_tag = '+' if ($adjust.StartsWith('-')) { if ($adjust.replace('-','') -gt $result) { Write-Warning "Adjustment exceeds total usage. Please enter a lower value." $_tag = '' } else { SubtractTime $adjust.replace('-','') } } else { AddTime $adjust } } else { Write-Warning "Format '$adjust' is invalid. Use 'hh:mm:00' only. Terminating..." return } } [Int]$since = $MyInvocation.MyCommand.Module.PrivateData['h'] #Retrieve the total hours. if ($since -gt 0) { $name = 'hours' } Write-Host "Total online usage since $after is $result $name ($sum Mb)" if (($_tag -eq '+') -and ($today -eq $false)) { #No need to show for -Today. Write-Host "(including $adjust hours adjustment time)" } Write-Verbose "Data values: Download = $download Mb, Upload = $upload Mb (Sessions = $count)" $output = New-Timespan (Get-Date $env:dtac).Date ([DateTime]::Today).Date $unit = ($limit-$output.Days) $expires = (Get-Date $env:dtac).AddDays($limit) $invalid = "$($expires.DayOfWeek), $($expires.ToLongDateString())" switch ($unit) { {($_ -lt 31) -and ($_ -gt 5)} { #Corrected from -lt 30 Write-Verbose "SIM card will expire in $unit days on $invalid" break } {($_ -lt 6) -and ($_ -gt 1)} { $GLOBAL:notifyIcon.Visible = $true $GLOBAL:notifyIcon.BalloonTipText = "SIM card expires in $unit days on $($expires.ToLongDateString())." $GLOBAL:notifyIcon.ShowBalloonTip(500) Write-Verbose "SIM card will expire in $unit days on $invalid" break } {($_ -eq 1)} { $GLOBAL:notifyIcon.Visible = $true $GlOBAL:notifyIcon.Icon = [System.Drawing.SystemIcons]::Warning $GLOBAL:notifyIcon.BalloonTipIcon = "Warning" $GLOBAL:notifyIcon.BalloonTipText = "SIM card will expire tomorrow." $GLOBAL:notifyIcon.ShowBalloonTip(500) Write-Verbose "SIM card will expire tomorrow" break } {($_ -eq 0)} { $GLOBAL:notifyIcon.Visible = $true $GLOBAL:notifyIcon.BalloonTipText = "SIM card will expire today." $GLOBAL:notifyIcon.ShowBalloonTip(500) Write-Verbose "SIM card will expire today" break } {$_ -lt 0} { $GLOBAL:notifyIcon.Visible = $true $GLOBAL:notifyIcon.BalloonTipText = "SIM card expired on $invalid." $GLOBAL:notifyIcon.ShowBalloonTip(500) Write-Verbose "SIM card expired on $invalid." break } } #Write-Verbose "SIM card will expire in $unit days on $invalid" if ($GLOBAL:notifyIcon.Visible) { Start-Sleep -Seconds 5 $GLOBAL:notifyIcon.Visible = $false $GLOBAL:notifyIcon.Dispose() } } #End Get-Modem function gprs { #Show all adapters. Use 'Adapter: dtac*' for dtac only. Invoke-Expression "Get-Modem -Adjust '01:06:00' -Device 'Adapter:*' $args" } #NOTE: Any extra $args need to be in quotes if they contain spaces. New-Alias usb Get-Modem Export-ModuleMember -Function Get-Modem, gprs -Alias usb |