Showing posts with label Windows. Show all posts
Showing posts with label Windows. Show all posts

Tuesday, December 11, 2018

Cisco CME - Emergency Call History Notification - Part 2

Let's say you wanted to notify all phones that a Lockdown scenario has started  or 911 was dialed at this location.  We would need to find all registered phones and push out a message.

Short version...
a) Person dials the predetermined emergency number
b) CME Syslog see this event and runs the Event Manager applet
c) The CME uploads the TXT file to the Windows server and the PowerShell script sees the new file and runs the PHP script. 
d) The PHP script then reads each line of the uploaded TXT file and pushes out the XML file to the registered phones.



See the start of the event manager applet on Part 1

Find all register phones (SCCP and SIP) and add them to an variable
 action 002.60.01  cli command "show ephone registered sum | include 192.168"
 action 002.60.02 foreach line "$_cli_result" "\n"
 action 002.60.03  regexp "192\.168\....\...." "$line"
 action 002.60.04  if $_regexp_result eq "1"
 action 002.60.05   regexp "192\.168\.[0-9]+\.[0-9]+" "$line" temp_IP
 action 002.60.06   append array_IP "$temp_IP\n"
 action 002.60.07  end
 action 002.60.08 end
 action 002.61.01 cli command "show voice register pool registered | include IP address"
 action 002.61.02 foreach line "$_cli_result" "\n"
 action 002.61.03  regexp "192\.168\....\...." "$line"
 action 002.61.04  if $_regexp_result eq "1"
 action 002.61.05   regexp "192\.168\.[0-9]+\.[0-9]+" "$line" temp_IP
 action 002.61.06   append array_IP "$temp_IP\n"
 action 002.61.07  end
 action 002.61.08 end
 Send the results to a file on a TFTP server.  (In our case it's a TFTP server running on Windows Server 2016)
 action 003.01.01 set result_Final "$result_Site $result_Ext $result_Mac $result_IP $result_Called"
 action 003.01.02 set result_Notify "$result_Final\n$array_IP"
 action 003.02.01 if $result_Called eq "911"
 action 003.02.02  file open fh flash:911.txt w
 action 003.02.03  file write fh $result_Final
 action 003.02.04  file close fh
 action 003.02.05 else
 action 003.02.06  file open fh flash:Notify.txt w
 action 003.02.07  file write fh $result_Notify
 action 003.02.08  file close fh
 action 003.02.09 end

 action 003.03 cli command "configure terminal"
 action 003.04 cli command "file prompt quiet"
 action 003.05 cli command "end"
 action 003.06.01 if $result_Called eq "911"
 action 003.06.02  cli command "copy flash:911.txt tftp://eventlogger/demo911.txt"
 action 003.06.03 else
 action 003.06.04  cli command "copy flash:Notify.txt tftp://eventlogger/demoLock.txt"
 action 003.06.05 end
 action 003.07 cli command "configure terminal"
 action 003.08 cli command "no file prompt quiet"
 action 003.09 cli command "end" 
 Do something with those results.

This is were some searching on the Internet found a PowerShell script that can run commands based on different file actions. Create a new task that runs at computer startup and runs as System account.
Remove-Item c:\oss_snmp\LockDownlog.log
Remove-Item c:\oss_snmp\PHPlog.log
Remove-Item c:\tftp-root\*lock.txt
### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
    $watcher = New-Object System.IO.FileSystemWatcher
    $watcher.Path = "c:\tftp-root"
    $watcher.Filter = "*lock.txt"
    $watcher.IncludeSubdirectories = $false
    $watcher.EnableRaisingEvents = $true 
### DEFINE ACTIONS AFTER AN EVENT IS DETECTED
    $LogAction = { $path = $Event.SourceEventArgs.FullPath
                $changeType = $Event.SourceEventArgs.ChangeType
                $logline = "$(Get-Date), $changeType, $path"
                Add-content "c:\oss_snmp\LockDownlog.log" -value $logline
              }   
    $PHPAction = { php -f C:\OSS_SNMP\LockdownCMEPHones.php
$path = $Event.SourceEventArgs.FullPath
                $changeType = $Event.SourceEventArgs.ChangeType
                $logline = "$(Get-Date), $changeType, $path"
                Add-content "c:\oss_snmp\LockDownlog.log" -value $logline
              } 
### DECIDE WHICH EVENTS SHOULD BE WATCHED
    Register-ObjectEvent $watcher "Created" -Action $PHPAction
    Register-ObjectEvent $watcher "Changed" -Action $LogAction
    Register-ObjectEvent $watcher "Deleted" -Action $LogAction
    Register-ObjectEvent $watcher "Renamed" -Action $LogAction
    while ($true) {sleep 1}
Install PHP for Windows on IIS.
This will allow us to run the Push2Phone function from the Cisco IP Services development kit.
Save the below text into the PHP file mention in the above PowerShell script.
<?php
//header("refresh: 30;");
$File = 'c:\TFTP-Root\demoLock.txt';
chdir('c:\OSS_SNMP');
$School = "";
$Address = "";
$Site = "Empty";
//echo "Start\n";
if (file_exists($File))
{
//echo "found \n";
$contents = file_get_contents($File);
$lines = explode("\n", $contents);
foreach ($lines as $line)
{
if ($line === ""){
//nothing
//echo 'Nothing';
}
else
{
if (strpos($line," ") !== false){
$Found = explode(" ", $line);
$Site = substr_replace(strTOUpper($Found[0]),"",-1);
$Site = str_replace($Site,"DEMO","DEMO-SITE");
$LookupSchool = SiteLocation($Site);
$School = $LookupSchool[0];
$Address = $LookupSchool[1];
//echo "$Site \n";
$Ext = $Found[1];
$Mac = $Found[2];
$IP = $Found[3];
$Number = $Found[4];
}
else
{
$IP = $line;
$Today = date("F j, Y, g:i a");
$Textdata = "$School \n$Address\nIs in LOCKDOWN\n$Today";
set_time_limit(0); //http://php.net/manual/en/function.set-time-limit.php
$uri = "http://cmephones.emailhost.ca:8080/XML/$IP.xml";
$uid = "icxml";
$pwd = "password";
$filename = "XML/$IP.xml";
$data = "<CiscoIPPhoneText><Title>$Number called from $Ext</Title><Prompt>Sent from $Ext</Prompt><Text>$Textdata</Text></CiscoIPPhoneText>";
//echo $data;
file_put_contents($filename, $data);
push2phone($IP, $uri, $uid, $pwd);
}
}
}
}
else
{
echo "$File not found \n";
}
unlink ($File); //Remove file

function push2phone($IP, $uri, $uid, $pwd)
{
$auth = base64_encode($uid.":".$pwd);
$Chime = "Play:chime.raw";
$xml = "<CiscoIPPhoneExecute><ExecuteItem Priority=\"0\"URL=\"".$Chime."\"/><ExecuteItem Priority=\"0\"URL=\"".$uri."\"/></CiscoIPPhoneExecute>";
//echo $xml;
$xml = "XML=".urlencode($xml);
$post = "POST /CGI/Execute HTTP/1.0\r\n";
$post .= "Host: $IP\r\n";
$post .= "Authorization: Basic $auth\r\n";
$post .= "Connection: close\r\n";
$post .= "Content-Type: application/x-www-form-urlencoded\r\n";
$post .= "Content-Length: ".strlen($xml)."\r\n\r\n";
$fp = fsockopen ( $IP, 80, $errno, $errstr, 30);
$response = "";
if(!$fp){ echo "$errstr ($errno)<br>\n"; }
else
{
fputs($fp, $post.$xml);
flush();
}
//return $response;
}
function SiteLocation($Site)
{
if($Site === "DEMO-SITE"){
return array("IT South","Street Address");
}
}

?>

Friday, December 29, 2017

MultiPoint Services 2016 Elevated Dashboard Issue

Multipoint Services is now part of Server 2016 so we are looking to deploy it to some of our sites.

One test system on a HP ProDesk 400 G3 has been setup it seems to be running fine.

Ran into one issue today is that you need to 'Run As Administrator' for the WMS Dashboard to launch programs even though the users is in the "WMSOperators" group.

The simple solution is to change the properties on the Multipoint Dashboard shortcut in the Start Menu.
- Right click the icon in the Start Menu
- More - Open File Location
- Click 'Advanced' under the Shortcut tab
- Click 'Run as Administrator'




For the WMS Dashboard RDP file you have to do a couple of more advanced things.
Copy and save this as a .reg file and add it the MPS server.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\TSAppAllowList\Applications\DashboardExplorer]
"CommandLineSetting"=dword:00000002
"IconIndex"=dword:00000000
"IconPath"="%SYSTEMDRIVE%\\Windows\\explorer.exe"
"Path"="C:\\Windows\\explorer.exe"
"VPath"="\"C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\MultiPoint Dashboard.lnk\""
"ShowInTSWA"=dword:00000001
"Name"="DashboardExplorer"
"ShortPath"="C:\\Windows\\explorer.exe"
"RequiredCommandLine"="\"C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\MultiPoint Dashboard.lnk\""
 Edit the Multipoint Dashboard RDP file with notepad (or text editor) created from the "Save Connection settings to file" wizard in the Multipoint Manager program.
Replace the lines containing
alternate shell:s:||WmsDashboard.exe
remoteapplicationprogram:s:||WmsDashboard.exe
remoteapplicationname:s:WmsDashboard.exe
with
alternate shell:s:||DashboardExplorer
remoteapplicationprogram:s:||DashboardExplorer
remoteapplicationname:s:DashboardExplorer
You may have to change the TSAppAllowList fDisabledAllowList registry from 0 to 1.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\TSAppAllowList]
"fDisabledAllowList"=dword:00000001"

Monday, March 7, 2016

Adding Microsoft TTS Voice to HTA Applictions


HTA sub routine

Sub Speak (text) 'V3.20 'Dim objVoice 'Enabling this section will slow down the HTA program 'Set objVoice = CreateObject("SAPI.SpVoice") 'Set objVoice.Voice = objVoice.GetVoices("Name=microsoft sam").Item(0) 'objVoice.Speak Replace (text, "'d", "ed") 'objVoice.Speak text 'msgbox Text 'Running VBS script allows HTA to continue while message is played. cmdVoice = "voice.vbs " & chr(34) & text & chr(34) Objshell.run CmdVoice,0,0 End Sub Voice.vbs Script 'V3.20 on error resume next If wscript.arguments.Item(0) <> "" Then Text = wscript.arguments.Item(0) Set objVoice = CreateObject("SAPI.SpVoice") 'Set objVoice.Voice = objVoice.GetVoices("Name=microsoft sam").Item(0) 'objVoice.Speak Replace (text, "'d", "ed") objVoice.Speak Text end if

Monday, November 16, 2015

Singlewire's InformaCast LPI solution for Bells using a Cisco CME

We had been using SingleWire's InformaCast and LPI solution to run our bells schedule.
It integrated well with our Bogen equipment and allowed bells to ring both on the SCCP phones and Bogen paging system using a FXS port.

A few years ago we were installing a new CME into one of our remote sites, and found that the new version of Cisco OS was no longer compatible with InformaCast.  Or at least that is what SingleWire was telling us.

We couldn't downgrade the Cisco CME OS because the SRE module running the CUE would not work with older versions of Cisco CME OS.

After a little bit of trial and error, installing the InformaCast software using the HRE install option worked. Bells would now ring even though it reported an error about not being able to talk to the Communications Manager cluster... (see below)


Both the CUCM or CME install options for InformaCast wanted to 'talk' to the CME every time a bell was to ring and since it couldn't 'talk' to the new OS... the bell would not ring.

It's been working great until this year... now we are not sure if the Bogen equipment is starting to fail due to age or if the numerous power outages this summer have caused damage to the Bogen.  Either way the DTMF tones from the LPI software are not triggering the Bogen zones.  However paging from the Cisco CME using the same DTMF tones worked everytime.

After several tests, solutions were found for 3 out of 5 sites.  Adjusting the DTMF length and volume in the LPI device settings resolved the issue.  1 site will be getting new equipment as the Bogen is over 10 years old.  The other site will be testing this solution.

The previous config had the LPI software sending the DTMF tones based on the speaker on the single Device (ex 1410).  (Sip Address is the Voice Vlan IP of the CME)


The CME already has paging dial peers for the zones, so the LPI software will use those numbers (ex. 1411) when calling the CME via SIP calls.  The CME will pass along the DTMF codes and then the bell (aka message) will play.  (Sip Address is the Voice Vlan IP of the CME)

dial-peer voice 1411 pots
 destination-pattern 1411
 port 0/1/0 'FXS port connected to Bogen
 prefix ,07#

The problem was that the LPI device software needs at least 1 DTMF code or it will not create the InformaCast speaker.

The solution was rather simple after testing different volumes and time outs.
Change the "DTMF Via" option from "RFC2833" to "SIP INFO".
Now you do not hear the extra DTMF tones before the bell.



The other feature we lost in changing to HRE mode was the ability to play the messages on the phones.

Solution:
Create a paging group for phones (In our case all phones)

ephone-dn  200
 number 1498
 name Paging All
 paging ip 239.1.1.2 port 20482 'Works with SIP and SCCP phones
 paging group 201,202,203,204,205,206,207,208,251,303

Create a LPI Paging device that calls the 1498 via SIP.


Now create the speakers in InformaCast and add the Phones speaker to any of the InformaCast Paging Recipient Groups.  You may have to increase the "Wait Time" on the messages to allow the CME to send the DTMF tones.  The "Example Humoctopus Alert" message is perfect for testing.
 



Tuesday, May 5, 2015

Find SCCM Device Variables Using Powershell

Sometimes you want a report of all the variables that computer/device will have when it runs the task sequence.

Here's a script that will report ...
a) device name
b) device assigned variables
c) Collection name with the assigned variables of which the device is a member.

It requires the SCCM console installed and you must provide the computer name in the command line.

The script will report back if the computer name is not valid and kill the powershell process.
For testing, run the script from a command prompt. i.e. powershell .\variables.ps1 computername

param (
    [Parameter(Mandatory=$true, HelpMessage="Computer Name",ValueFromPipeline=$true)] $strComputer
)
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
cls
import-module ($Env:SMS_ADMIN_UI_PATH.Substring(0,$Env:SMS_ADMIN_UI_PATH.Length-5) + '\ConfigurationManager.psd1')
CD SITENAME:\
$nl = [Environment]::NewLine
$tab = "`t" #tab
$count = -1 # Allows for Null
write-host Checking Computer Name
If(!$strComputer){
    [System.Windows.Forms.MessageBox]::Show("Error! - No Source Computer Entered")
    stop-process $pid -Force #End Powershell task
}
#Verify Names
$Verify =  Get-CMDevice -Name $strComputer | forEach{$_.name}
If(!$Verify){
    [System.Windows.Forms.MessageBox]::Show("No Record for "+ $strComputer)
    stop-process $pid -Force #End Powershell task
}
#Get-CMDeviceVariable -DeviceName <String>
# Find System Variables
write-host Checking System Variables
$Result = Get-CMDeviceVariable -DeviceName $strComputer
If(!$Result){
    #write-host $strComputer Not Found
    $strOutput = $strComputer
}
else{
    $Result = Get-CMDeviceVariable -DeviceName $strComputer | forEach{$_.Name + $tab + $_.Value} |Out-String
    $strOutput = $strComputer.toUpper() + " Assigned Device Variables"+ $nl + "Variable Name" +$tab +"Variable Value" +$nl + $Result
}
If($ErrCount -ge 1){
    [System.Windows.Forms.MessageBox]::Show("Error" + $ErrCount)
    stop-process $pid -Force #End Powershell task
}
$strOutput = $strOutput + $nl + $strComputer.toUpper() + " Assigned Collection Variables"
write-host Checking Collection Variables
#Find Collection Variables
$ResID = Get-CMDevice -Name $strComputer | forEach{$_.ResourceID}
$Collections = (Get-WmiObject -ComputerName "SCCM SERVER NAME" -Class sms_fullcollectionmembership -Namespace root\sms\site_SITENAME -Filter "ResourceID = '$($ResID)'").CollectionID
foreach($collection in $Collections){
    $CollName = Get-CMDeviceCollection -CollectionId $Collection | forEach{$_.name}
    write-host $CollName
    $CollVar = Get-CMDeviceCollectionVariable -CollectionName $CollName | forEach{$CollName + $tab + $_.Name + $tab + $_.Value} |Out-String
    If ($CollVar){
        $CollOutput = "Collection Name" +$tab + "Variable Name" + $tab + "Variable Value"
        $CollOutput = $CollOutPut + $nl + $CollVar
    }
}
$strOutput = $strOutput + $nl + $CollOutput
#[System.Windows.Forms.MessageBox]::Show($strOutput)
[IO.File]::WriteAllText('variables.txt', $strOutput)



More SCCM related posts

Friday, May 1, 2015

SCCM Boot Image with UltraVNC remote access

In preparing for a Universal Imaging Task sequence, the thought came across my mind, what if I want to see what's going on and the computer is 2 hours away?

Once the task sequence installs Windows, we have it install UltraVNC so after that point it is possible to remotely connect.  However what about before when the computer has booted from our PXE server and is running Windows PE.

Here is the quick and dirty version of how we can now VNC into a computer that has started up in Windows PE.



1) Create Standard WIM file using the Windows ADK and then before committing the changes...
1a) Created an 'xtras' folder on the root of the mount folder (I called it 'xtras' because it's always drive x: in our PE environment)

2) UltraVNC program with password protection
2a) Installed on test system running Windows 7 with any settings (i.e. password)
2b) Copied the UltraVNC found in Program Files to mount\xtras

3) Create Computername.vbs and copy into mount\xtras
3a) Basic script that extracts the IP address of the computer using WMI
3b) Disables the WinPE firewall - "wpeutil disablefirewall"
3c) Installs UltraVNC
3d) Popup message with IP address - only on screen for 90secs so that it does not prevent the task sequence from running.

4) Create startup.cmd file in mount\xtras
4a) In that file, it runs wscript.exe %systemdrive%\xtras\computername.vbs

5) Once files have been copied to the mount\xtras folder, you can commit the changes to the WIM and proceed with importing it into SCCM.

6) Create at 'winpeshl.ini' file (See below)
6a) Save to... C:\Program Files\Microsoft Configuration Manager\OSD\bin\x64 or C:\Program Files\Microsoft Configuration Manager\OSD\bin\i386

7) Add Drivers and any extra components that you require

8) Distribute/update boot images.

'winpeshl.ini' file contents
[LaunchApps]
%SYSTEMDRIVE%\Windows\System32\wpeinit.exe
%SYSTEMDRIVE%\Windows\System32\wpeutil.exe, "initializenetwork"
%SYSTEMDRIVE%\xtras\startup.cmd
%SYSTEMDRIVE%\sms\bin\x64\TsBootShell.exe
computername.vbs example.
 'Extract Computer Details
'Version 3.01 WMI Query
'May 1, 2015
on error resume next
Dim oTaskSequence
'Create Objects
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2") 'Local computer WMI
Set objShell = CreateObject("WScript.Shell")
strQuery = "SELECT * FROM Win32_NetworkAdapterConfiguration WHERE MACAddress > ''"
Set colItems = objWMIService.ExecQuery( strQuery, "WQL", 48 )
For Each objItem In colItems
for each IP in ObjItem.IPAddress
If left(IP,4) = "192." then
strIP = IP & vbCRLF & strIP
end if
next
Next
StrInfo = "If you require any assistance..." & vbCRLF &_
"Please send this information to the IP department." & vbCRLF &_
vbCRLF & "IP Address: " & strIP
cmdFirewall = "wpeutil disablefirewall"
objShell.run cmdFirewall,0,1
cmdUltra = "%systemdrive%\xtras\UltraVnc\winvnc.exe -install"
'msgbox cmdUltra
ObjShell.run cmdUltra
objShell.Popup strInfo, 90, "Message Box Title"
References...

More SCCM related posts

Monday, April 20, 2015

Blocking Cyber Attacks on Windows Servers using CyberArms software and PowerShell scripts

Recently the number of audit failures on our Remote Desktop and IIS servers has increased drastically in the last month.
List of IP addresses found here.
Found this program for our 2012 servers (or any RDP using TLS)

CyberArms Intrusion Detection and Defence System

Default config...
After 3 failed login attempts, it would temporarily block the IP for 20 minutes. (Soft Lock)
After 10 login attempts, it would block the IP for 24 hours. (Hard lock)
-There is the option to hard lock the IP address forever.

Issues
1) No option to customized notification emails. -wanted to include
2) Cannot white-list a service provider only IP addresses.
3) No Response to inquiry about their products and licensing.

Since the program creates an event log for when it blocks the IP address, a PowerShell script was created to add firewall rules (permanent rules) and send email notifications out with detailed information.

The original PowerShell script just sent out emails with the server name when an event log with 4001 or 9001 is created in the "CyberArms" event log.

It worked great on our 2012 servers, however 2008 stored the Event log data with extra returns and spaces in the IP addresses.  In testing it caused the local network to be blocked via firewall.  Good thing it was a virtual machine and could still be access through Virtual Center.

Updated the PowerShell script to distinguish between 2008 and 2012 servers.

Another VBscript was created to manually delete any firewalls from 'trusted' IP addresses using netsh from another computer.

After the first weekend having to check each IP address and manually delete the rules got old and time consuming.

The next revision of the script added NSlookup to a ProviderLookup function in the script.

The ProviderLookup function was created to allow certain IP addresses or provider names (provided by NSLookup) to be unblocked automatically.

Example if NSlookup returned a provider name with "Domain.ca" in it, then we trusted it and the firewall was deleted.

Emails now include the IP address, the provider information and if the rule was deleted.

Steps...
Install CyberArms software
Enable any security agents in CyberArms
Download PowerShell Script "CyberArms Eventlog Script.txt"
- Rename to .PS1 and change "DOMAIN.CA" and email settings.
Create Task Sequence to run the script when event 4001 or 9001 is logged.

Update - April 21, 2015

The ProviderLookup function will now include Country and ISP information extracted from http://ipaddress.com if it cannot find a DNS name for the IP address.

Future options
1) Create the same firewall rule on more that one server via PowerShell Array variable.
2) Create a pause between rule creation and rule deletion, just in case there was malicious intentions.
- probably use a ping command to 127.0.0.1 for 10 minutes then have it delete the rule.
3) Working on cleaning up the ProviderLookup function so that certain ISP names will be allowed.

Tuesday, March 31, 2015

Intel NUC and SCCM issues

We purchased a couple of the Intel NUC mini desktops (model NUC5i3RYK) for our custom Lync Room systems.

Deploying with Microsoft System Center Configuration Manager...

Same with any new system... the Window PE boot image needed new drivers for the Ethernet adapter. (In our case the 64 bit driver - e1d64x64.inf)

Created a driver pack for the Intel NUC system, however the drivers were not getting installed into the image by the "Apply Device Drivers" task.

Decided to try the "Apply Driver Package" and picked the Intel NUC package option to see what would happen.

Now the task sequence fails with...
This task sequence cannot be run because a package referenced by the task sequence could not be found. For more information, please contact your system administrator or helpdesk operator.

Using F8 and cmtrace to open the \windows\temp\SMSTS.log file and found this error message...
Failed to resolve selected task sequence dependencies. Code(0x80040104)

Found this website and updated the distribution points so that the source version number would not be '1' and now the task sequence is working and drivers are installing.

More SCCM related posts

Friday, March 6, 2015

SCCM Task Sequence User Verification

We know that Config Manager's Task Sequences run with a system account and can only be advertised to Device collections.

What if we wanted only certain people to have permission to re-image their computer?

This script will record the logged in username via wmi as a Task Variable.
If that account is a member of a specific domain group then the 'ValidUser' Task Variable will be set as True.

You can then use that 'ValidUser' Task Variable to allow groups or other commands/applications to run.



To test the sequence with the msgbox dialogs you will need the ServiceUI.exe file from the Microsoft Development kit.

'Find Logged in user
'Version 1.60
on error resume next
Dim objNetwork, objDomain, oTaskSequence
'msgbox "Testing"
'Create Objects
Set objNetwork = CreateObject("Wscript.Network")
Set objDomain = GetObject("LDAP://RootDSE")
Set oTaskSequence = CreateObject ("Microsoft.SMS.TSEnvironment")

' Obtain user information.
'strUserName = objNetwork.UserName
strcomputer = "."

Set objWMI = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 
Set colSessions = objWMI.ExecQuery ("Select * from Win32_ComputerSystem",,48) 
For Each objItem in colSessions 
if objItem.Username <> "" then
strUserName = Replace(Lcase(objItem.UserName),"prairiesouth","")
oTaskSequence("UserName") = replace(strUserName,chr(92),"")
'msgbox strUserName
else
strUserName = objNetwork.UserName
end if
next

If not lcase(strUserName) = "system" then
'Verifies not the System account.
strDomain = objDomain.Get("dnsHostName")
Set objUser = GetObject("WinNT://" & strDomain & "/" & strUserName)
For Each strGroup in objUser.Groups
If Lcase(strGroup.Name) = "help desk end users" or Lcase(strGroup.Name) = "information technology department" then
strValid = 1
oTaskSequence("UserGroup") = strGroup.Name
'msgbox strGroup.Name
exit for
end if
Next
else
strValid = 0
end if

If strValid = 1 then
oTaskSequence("ValidUser") = "True"
'msgbox strValid
Else
oTaskSequence("ValidUser") = "False"
'msgbox strValid
end if


More SCCM related posts

Thursday, January 29, 2015

SCCM 2012 Task Sequence for Failing Hard Drive

Now that you have collections created based S.M.A.R.T diagnostics or Disk event log entries baselines for failing hard drives... (See previous post)

We can create a custom Task Sequence to notify the user of the problem, when they log onto the computer.

Optionally, you could also deploy this as an available task sequence, for end users to manually check hard drive status.

Here are my suggestions for the task sequence...

Name: Hard Drive Diagnostic
Progress notification text: "Please submit a help desk ticket if the hard drive reports as failing."  (or use the standard "Running: <Task sequence name>")
Suppress task sequence notifications - Optional
Maximum run time: 5 minutes
Run on any platform.

Sequence of Tasks... (Keep in mind that the "Name" is what the end user will see on the screen)
  1. Set Task Sequence Variable
    1. Name: Testing hard drive health. Please wait.
    2. Variable: HD Failure
    3. Value: True
    4. Options:Add a WMI query Condition
      1. WMI Namespace: root\wmi
      2. WQL Query: select * from MSStorageDriver_FailurePredictStatus Where PredictFailure = True
  2. Group 1:
    1. Name: Hard Drive Diagnostic Finished
    2. Options: Add a Task Sequence Variable
      1. Variable: HD Failure
      2. Condition: Equals
      3. Value: True
    3. Run Command Line (Under Group 1)
      1. Name: The hard drive is failing
      2. Command line: ping 127.0.0.1 -n 30
        1. Should last about 30 seconds on the screen
    4. Run Command Line (Under Group 1)
      1. Name: We recommend replacing the hard drive.
      2. Command line: ping 127.0.0.1 -n 30
        1. Should last about 30 seconds on the screen
  3. Group 2:
    1. Name: Hard drive Diagnostics Finished
    2. Options: Add a Task Sequence Variable
      1. Variable: HD Failure
      2. Condition: Not Exists
    3. Run Command Line (Under Group 1)
      1. Name: Hard drive passed diagnostics
      2. Command line: ping 127.0.0.1 -n 10
        1. Should last about 10 seconds on the screen.

More SCCM related posts

Using SCCM 2012 Compliance Settings to Determine Hard Drive Health

As long as your computer has S.M.A.R.T hard drive diagnostic capabilities, the following can be used to track hard drive failures.

Configuration Item(s) in SCCM 2012.


Option 1 - Using WQL query

Name - Hard Drive Predictive Failure
Platforms - All (Although, if they are virtual machines this will not work.)

Settings -
  • Name: Storage Driver Failure Prediction
  • Type: WQL Query
  • Data: String
  • Namespace: root\wmi
  • Class: MSStorageDriver_FailurePredictStatus
  • Property:PredictFailure
Compliance Rules
  • Name: Possible Hard Drive Failure is True
    • I named it this to remind me that "False" is the result we want.
  • Rule: Storage Driver Failure Prediction Equals False
  • Noncompliance severity: Critical


 Option 2 - Using PowerShell script to read system event log

This option will read the System event log and count any 'disk' source logs that are not Information level. 
Note: This will include issues with temporarily attached external hard drives or USB drives.

Name - Event Log Disk Errors
Platforms - All (This will work for servers and virtual machines)
Settings
  • Name: Report disk errors found in Event Log
  • Type: Script
  • Discovery script (See end of post)
    • Counts the events and writes that value.
Compliance Rules
  • Name: Disk error count
  • Rule: Less than 1 (That's a number one)
  • Noncompliance severity: Critical
Now that you have created the Configuration Items, you can add (one or both) to a Configuration Baseline and deploy them to your collections.

Once deployed create collections for the non compliant systems and then use that information in reports for your help desk or create a Task sequence that alerts the end user that the hard drive is may be failing.

Here's the PowerShell script...
- Updated Feb 3, 2015 to exclude '*Device\Harddisk1\DR1*' event logs.

#Version 2.30 Feb 3, 2015
#Designed for SCCM Baseline
$AllEvents = 0

#Default Event Logs
$Provider = "disk"
$HourChange = 24 #Up to you how far back you want to go
$TimeNow = [DateTime]::Now
$TimeChange = [DateTime]::Now.AddHours(-$HourChange)

#Check Event Log for errors
$EventLogNames = "System"

ForEach ($log in $EventLogNames){
    $entry = " "
    #Search Event Logs
   
    $LogEntry = Get-WinEvent -LogName $log | Where-Object {$_.timeCreated -ge $TimeChange -and $_.ProviderName -contains $Provider -and ($_.LevelDisplayName -eq 'Warning' -or $_.LevelDisplayName -eq 'Error' -or $_.LevelDisplayName -eq 'Critical')}
        ForEach ($entry in $LogEntry){
            $EvLevel = "Level: `t" + $entry.LevelDisplayName + $nl
            $EvEventID = "EventID: `t" + $entry.ID + $nl
            $EvMessage = "Message: `t" + $entry.Message + $nl
            $EvSource = "Source: `t" + $entry.ProviderName + $nl
            $EvTime = "Time Created: `t" + $entry.TimeCreated + $nl
            #write-host $EvLevel + $EvEventID + $EvMessage + $EvSource +$EvTime + $nl


            #If ($entry.LevelDisplayName -eq "Critical" -or $entry.LevelDisplayName -eq "Warning" -or $entry.LevelDisplayName -eq "Error"){
            If ($EvMessage.tostring() -like '*Device\Harddisk1\DR1*'){
                #nothing
            }
            ElseIf ($entry.LevelDisplayName -eq "Critical" -or $entry.LevelDisplayName -eq "Warning" -or $entry.LevelDisplayName -eq "Error"){
             $AllEvents += 1
            }
                       
        }

}
write-host $AllEvents



More SCCM related posts

Monday, January 12, 2015

Cleaning up CCMCache folder in SCCM 2012

One thing I have found with System Center Configuration Manager is that the client cache folder can take up a lot space on the hard drive.  Filled with updates or applications source files that no longer are needed.

Only way is to set the Cache size to smaller value using a vbs script (or powershell) that runs these commands...
set oUIResManager = createobject("UIResource.UIResourceMgr")
set oCache=oUIResManager.GetCacheInfo()
oCache.TotalSize=4096

However, if you were to install a program like AutoCAD that requires more than 4GB of cache storage, it would likely fail.

The PowerShell script listed at the bottom of this post (based on Kaido Järvemets posting at http://cm12sdk.net) will clean up the "old" content in ccmcache based on the LastReferenced WMI information. 

The '$ReferenceAge.Days -gt 30' section deletes anything not referenced in the last 30 days. 

The "#Change Cache size" section is optional and only included for reference.

The 'stop-process $pid -Force' command however is required as there have been cases where the PowerShell script fails to exit.

It can be run on a remote computer using the psexec program from Sysinternals.

Example.
copy the file over to hard drive of the remote system.
psexec.exe -s \\computername powershell -noprofile -file "c:\clear ccmcache.ps1"

Planned implementation... (other than manually running).

Compliance item for harddrives with less than x amount of free space that remediates with a PowerShell command.
or
Task sequence that runs every # of days.

$Today = Get-Date
$CacheInfoQuery = Get-WmiObject -Namespace Root\ccm\SoftMgmtAgent -Class CacheInfoEx
ForEach ($Item in $CacheInfoQuery) {
    $LastDate = [Management.ManagementDateTimeConverter]::ToDateTime($Item.LastReferenced)
    $CacheElementID = "{" + $Item.CacheID + "}"
    $ReferenceAge = $Today - $LastDate
    $FolderLocation = $item.location
   
    if ($ReferenceAge.Days -gt 30) {
        #Write-Host Found $CacheElementID Last referenced $LastDate That is $ReferenceAge ago in $FolderLocation -ForegroundColor Red
        #Based on
http://cm12sdk.net/?p=1526
  Write-Host Too old, deleting folder $FolderLocation -ForegroundColor Red
        $CMObject = New-Object -ComObject "UIResource.UIResourceMgr"
        $CMCacheObjects = $CMObject.GetCacheInfo()
        $CMCacheObjects.DeleteCacheElement($CacheElementID)
        }
    #Remove number sign from the next 2 lines to allow for more information
    #else {
  #Write-Host $FolderLocation was last referenced $LastDate  That is $ReferenceAge days ago  -ForegroundColor Green}
    }
#Change Cache size
$CacheQuery = Get-WmiObject -Namespace ROOT\CCM\SoftMgmtAgent -Class CacheConfig
$CacheQuery.Size = 1000
$CacheQuery.Put()
#Restart CcmExec service
Restart-Service -Name CcmExec

stop-process $pid -Force


More SCCM related posts

Friday, October 24, 2014

Call History Reporting via Notepad++ for Nortel/Avaya BCM Phone Systems

Call Detail Recording for Nortel (now Avaya) BCM is done with push or pull client software.  This setup allows end users to access the FTP share files using Notepad++.  (Keep in mind setup is done on Windows based machines.)

Setup the Call Detail Recording Data File Transfer to push the records to your FTP server based on what ever schedule you like.

For multiple sites, create sub folders in the root of your FTP server based on their location.  i.e. Reports\School or Reports\Office

Setup an account on the BCM end users or support staff to manually push out the file if it's an urgent request.  They just click the "Push Now" button once you have setup the information.
** Keep in mind they will see the IP address and remote user account name for the FTP server.


Now that the files are being pushed to the FTP server, we need a way to get them to the end user.

Since we are using a Windows FTP server, create a share based on the "Reports" folder in the FTP root so that end users can have read access to that folder.  Change the security on the subfolders (i.e. School or office) so that only admins and the specific end user accounts have access.

Problem: Opening text files that don't end in .txt or .csv
Now that the end user can browse to the files, then need a program to open the "record.20141024xxx" files.  Since the extension is the date of push, it will not open automatically and the extension will always change.

Solution: - Notepad++ and Scheduled Task to the rescue.

Notepad++ will open the "record.20141024xxx" files but if the end user doesn't have Notepad++ or just wants to open the txt file with another program here's a batch file that renames them to "record.20141024xxx.txt"

REM Location Cleanup
cd C:\FTP root\Reports\Location
REM copy all date files into one txt file
copy /y record.20* records.*.txt
REM delete the original date file
del record.* /q


Create scheduled task on FTP server to convert the date files to TXT files. Runs 1/2 hour after BCM Push schedule.

For the end users with notepad++

Create a new shortcut for Notepad++ then change the properties of that new shortcut.
Add the share path to the end of the existing the target path.
i.e. "C:\Program Files (x86)\Notepad++\notepad++.exe" "\\server name\Call History Reports\School\"

This will start Notepad++ and open any file that is in that folder.

Staff now press "Ctrl+F" and type in "Digits Dialed" and click "Find All in All opened Documents"
To see more information about that call...

The end user double clicks on the phone number in the "Find result" window.
Notepad++ will jump to that line in that file and show you the Line # and the STN (aka extension number)



Problem: Too many log files can cause Notepad++ to start "Not Responding" especially when using remote network locations.

Solution: Create a scheduled task that runs batch files to merge and overwrite files on the FTP server. (Or monthly depending on your record keeping needs)

Sample Cleanup batch file
- Run every Sunday night
- overwrites the existing weekly.txt file

cd C:\FTP root\Reports\Location
REM merges previous records into a one txt file
copy /y records.20*.txt Weekly.txt
REM delete previous txt files
del records.*.txt /q

Saturday, August 30, 2014

Recovering Laptop Harddrive with Sync Toy and USB Dock Master

Needed to recover data off of a laptop and moving the files just wasn't working...
 
 
Decided to try Microsoft's SyncToy. We use it on some of our laptops to backup data from the laptop user's documents folder to a server which has it's own backup.
 
Created folder pairs for syncing between the failed harddrive and new folder on my desktop.
Since the harddrive was failing (faint click sound), paging errors and the odd bad block error showed up in the event log and SyncToy would stall, but not stop responding.  (Unlike Windows explorer)
 
To get it to start copying again, simply unplugged the USB cable from my desktop and plug it in again.
 
Now most copy jobs would stop completely when you do this, but not SyncToy. It moved on to the next file and try to copy that one.  
 
Granted there would be some files that would be missed based on how long Windows took to re connect the drive however, that is better than no files at all or manually copying over file by file and trying to find out which one was failing.
 
Once that was done, reran the Windows Chkdsk program on the drive and then ran the SyncToy folder pairs again to recover more files. 
 
Since SyncToy catalogs and compares file changes, this time the Sync took less time.  The harddrive still had that faint click of death and still required unplugging and plugging the USB cable.  When SyncToy stalled on a bad file, wrote down the file name(s) and then went back into the Folder pair settings and excluded the file(s).  This helped recover as much as 90% of the folders contents in some cases.