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) 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

Tuesday, December 8, 2015

Cisco CME and TOA 8000 Paging Setup

This year it seems that we have had a lot of equipment failures do to power outages.

This has been hard on the older paging equipment in our schools resulting in the need for new equipment.

We approached our audio experts for a solution that was network accessible and would still work with a Cisco CME based phone system if one was installed at that location at a later time.

Their solution was a TOA 8000 system which can be controlled and monitored over the network.

Unlike the previous TOA 9000 and Bogen PCM units that connected using an FXS port, the TOA 8000 requires different hardware.

The FXO port (same hardware that we use to connect to our telco provider phone lines) on the Cisco CME 2921 connects into the NL-8000AL interface unit.  The Cisco paging dial peers only required a port change and no changes were made to the Singlewire LPI software configuration we had set up for the Bogen equipment. (see previous post)

We found the TOA 8000 required a setting of a 1 second delay before paging.  If the delay was set to zero, the generated DTMF tones could be heard over the speakers on random occasions.

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.

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

ephone-dn  200
 number 1498
 name Paging All
 paging ip 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.

Thursday, July 23, 2015

Cisco CME and Lync Simultaneous Ringing using Cisco SNR Feature

Cisco has a Single number reach feature that allows calls to ring more than one number. Think of it as a parallel hunt group but with the option to turn it off and on from the user's phone.

With this setup, the end user's Lync client and Cisco phone will ring a the same time.

Lync (Skype for Business) setup

Create PSTN Gateways
 - use the IP address of the CME

Create the Trunks
- Listening on port 5060 and Mediation port 5068.

Enable Enterprise Voice for user's account.

Assign a fake number to the Line URI in the user's account setup
(Example of user with extension 4025 would be Tel:+13065554025)

* You can also create a CME Dial Plan and a CME Voice Policy to allow Lync users to call out on the CME's phone lines from their Lync client.

Cisco CME setup

- If you are using Voice and Data Vlans on your CME, bind it to the CME same Vlan used by the Lync server.

interface GigabitEthernet0/0.1
 description Voice 
 encapsulation dot1Q 1
 ip address
interface GigabitEthernet0/0.134
 description Data
 encapsulation dot1Q 2
 ip address

voice service voip
  bind control source-interface GigabitEthernet0/0.1
  bind media source-interface GigabitEthernet0/0.1

Create voice translation-rules (these will add the +1306 in front of the number)

voice translation-rule 8000
 rule 1 /^81306/ /+\11306/
 rule 2 /^810101306/ /+\11306/
 rule 3 /^8306/ /+\11306/
 rule 4 /^8/ /+\11306/

voice translation-profile Lync
 translate called 8000

Create dial-peer for Lync server, 8 followed by the 7 digit phone number. 

dial-peer voice 8000 voip 
description ** SIP 7 digit to Lync13-01 ** 
translation-profile outgoing Lync 
destination-pattern 8....... 
notify redirect ip2pots 
session protocol sipv2 
session target ipv4: 

voice-class sip bind control source-interface GigabitEthernet0/0.2
voice-class sip bind media source-interface GigabitEthernet0/0.2
session transport tcp 
dtmf-relay rtp-nte 
codec g711ulaw 
fax rate disable 
fax protocol pass-through g711ulaw 
no vad

SNR on SIP Phones  (Add these commands to the basic DN and Pool settings)

voice register dn 1 
number 4025 
mobility snr 85554025 
delay 0 timeout 12 cfwd-noan 1200 
snr ring-stop 
snr answer-too-soon 1
voice register pool 1
number 1 dn 1
session-transport tcp
dtmf-relay rtp-nte sip-notify

SNR on SCCP phones (Add these commands to the basis Ephone-dn and ephone settings)

ephone-dn 300 octo-line 
snr calling-number local 
snr 85554025 delay 0 timeout 12 cfwd-noan 1200 
snr ring-stop 
snr answer-too-soon 1
ephone 1
button 1:300
See also - Cisco's Single Number Reach article

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
import-module ($Env:SMS_ADMIN_UI_PATH.Substring(0,$Env:SMS_ADMIN_UI_PATH.Length-5) + '\ConfigurationManager.psd1')
$nl = [Environment]::NewLine
$tab = "`t" #tab
$count = -1 # Allows for Null
write-host Checking Computer Name
    [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{$}
    [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
    #write-host $strComputer Not Found
    $strOutput = $strComputer
    $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{$}
    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
[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
%SYSTEMDRIVE%\Windows\System32\wpeutil.exe, "initializenetwork"
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
StrInfo = "If you require any assistance..." & vbCRLF &_
"Please send this information to the IP department." & vbCRLF &_
vbCRLF & "IP Address: " & strIP
cmdFirewall = "wpeutil disablefirewall" cmdFirewall,0,1
cmdUltra = "%systemdrive%\xtras\UltraVnc\winvnc.exe -install"
'msgbox cmdUltra cmdUltra
objShell.Popup strInfo, 90, "Message Box Title"

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.

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 "" 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.

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 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 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.