teknoglot:

  • Home
  • Home
  • Microsoft
    • Hyper-V
    • OpsMgr 2007
    • SQL 2005
    • SQL 2008
    • Windows XP
    • Windows Vista
    • Windows 2008
  • Linux
    • Fedora 11
    • RedHat ES
    • SLES
    • Ubuntu
  • Code
    • PowerShell
    • VBS
  • Series
    • MP Dev: TG WinAutoSvc
  • Definitions
    • System Center Operations Manager 2007
      • Classes
      • Service Model
      • Singleton
  • Technobabble
Twitter RSS
Category Archives: Code

Quick-Hack: Send SMS through Powershell [#powershell]

Posted on May 15, 2012 by Sam T
No Comments

Decided to do a quick-hack/fast-publish on this one as I have had a bit less time to create a nice clean production-ready version as of yet… and people has been asking about how far off the article is.

What this script does is to send a text message using a GSM/GPRS modem connected to a local (or LAN-connected with local drivers) serial port using Powershell.

Disclaimer!

This script “works” but is not fit for production. See it as an example of the general concept to evolve and adapt into something worthy of production use.

What’s missing in the latest iteration is:

  • A working Event-Handler to deal with asynchronous call-backs.
  • Support for AT+MSGW (write to modem memory)
  • Reusing messages in modem memory for multiple recipients.
  • Various error- and exeption-handlers.
  • Actually verifying that the modem is AT-capable.
  • Querying the system for available modems and their ports.

The Script

So, a short note before digging into the script. Prerequisites for this script is that you have identified which COM-port to use and it’s supported baud-rates and whether it supports DTR or not. If you do not know what the hell I am talking about, you could probably have it work with my preconfigured settings anyway. If you are unsure about if your modem supports AT commands you could open a serial connection to the modem using Hyperterminal or PuTTY and run AT+CMGF=1. If supported, the return should be OK. If it is not supported (you get ERROR instead) you would have to use PDU-mode which require a bit of hex-encoding of your messages. This is nothing I have had to do yet and will not be including in this script. Maybe in the future. Maybe.

So, looking a some powershelling then. First thing would be to connect to the modem.


# Create your instance of the SerialPort Class
$serialPort = new-Object System.IO.Ports.SerialPort
# Set various COM-port settings
$serialPort.PortName = "COM1"
$serialPort.BaudRate = 19200
$serialPort.WriteTimeout = 500
$serialPort.ReadTimeout = 3000
$serialPort.DtrEnable = "true"
# Open the connection
$serialPort.Open()

With the connection established, you the set to modem in AT-mode and start sending the message to the modem.

# Tell the modem you want to use AT-mode
$serialPort.Write("AT+CMGF=1`r`n")

# Start feeding message data to the modem
# Begin with the phone number, international
# style and a <CL>... that's the `r`n part
$serialPort.Write("AT+CMGS=`"+46888888888`"`r`n")

# Now, write the message to the modem
$serialPort.Write("This is a test!`r`n")

# Send a Ctrl+Z to end the message.
$serialPort.Write($([char] 26))

As you may notice, the message is only stored in the modems memory until you send a Ctrl+z which will end the message and send it. It is possible to add more text to the message before sending it if you would like. Personally, I prefer to store the message into a regular powershell variable and pass that one to the script. The SerialPort library is sort of clever and a local phone number will probably work. For safety, I always use international number with country code as it will work every time.

Only thing left now is to close the serial port connection and end the script. Like this.

$serialPort.Close()

The Copy/Paste part…

Here’s the entire script with some added control-features and check to avoid trying to send text messages with no serial connection.


### DISCLAIMER ###
## This script is a quick-hack to demonstrate
## the basics of sending an SMS using an AT-
## compatible GSM modem connected a local
## serial port through PowerShell.
## No error-handling is implemented and this
## is NOT a script fit for production.
##################

# Create your instance of the SerialPort Class
$serialPort = new-Object System.IO.Ports.SerialPort
# Set various COM-port settings
$serialPort.PortName = "COM1"
$serialPort.BaudRate = 19200
$serialPort.WriteTimeout = 500
$serialPort.ReadTimeout = 3000
$serialPort.DtrEnable = "true"
# Open the connection
$serialPort.Open()
# Add variables for phone number and the message.
$phoneNumber = "+46888888888"
$textMessage = "This is a test message!"

try {
 $serialPort.Open()
}
catch {
 # Wait for 5s and try again
 # Told you this is a quick-hack, right?
 Start-Sleep -Seconds 5
 $serialPort.Open()
}
If ($serialPort.IsOpen -eq $true) {
 # Tell the modem you want to use AT-mode
 $serialPort.Write("AT+CMGF=1`r`n")
 # Start feeding message data to the modem
 # Begin with the phone number, international
 # style and a <CL>... that's the `r`n part
 $serialPort.Write("AT+CMGS=`"$phoneNumber`"`r`n")
 # Give the modem some time to react...
 Start-Sleep -Seconds 1
 # Now, write the message to the modem
 $serialPort.Write("$textMessage`r`n")
 # Send a Ctrl+Z to end the message.
 $serialPort.Write($([char] 26))
 # Wait for modem to send it
 Start-Sleep -Seconds 1
}
# Close the Serial Port connection
$serialPort.Close()
if ($serialPort.IsOpen -eq $false) {
 echo "Port Closed!"
}

# That's all folks
# Now, add call-backs, event-handlers, and return-
# message handling.

Enjoy!

Categories: PowerShell | Tags: GSM, PowerShell, Quick-hack, SMS

Bulk disable ACS Forwarders (with wildcards)

Posted on July 7, 2011 by Sam T
2 Comments

Here’s a little something-something for the wicked.

Me and my apprentice is currently decommissioning an entire Management Group with a thousand (-ish) agents. Long story short, we got a new Management Group, migrated all the agents, added a couple of hundreds more, deployed a bunch of gateways and now we are shutting down the old one.

Now, uninstalling the old Management Group from all the agents is a breeze using SCCM and handling the few 20-ish servers that are left is not a biggie either. Shutting down ACS, however, is a different matter.

Although you do configure your forwarders using Operations Manager, removing the management group you were running ACS in does not mean the agents will shut down and disable the AdtAgent service or stop trying to forward audit events to your collector. Now, selecting 10 agents at the time and running the “Disable Audit Collection” task–in case you did not know, there’s a limitation on how many agents you can run a task on in the Operations Console–is not my idea of a jolly good day and since Powershell is a bucket of joy in comparison; here’s a script for you all!

DisableACSForwarders

It is zipped to avoid security alerts, but as with any script found on the internet I implore to to read the code before actually running it.

Anyway, you can use it in a couple of ways.

To run it interactively, just go to the directory where you unpacked it and run it. You will be requested to enter the FQDN of you Root Management Server and a wildcard search for ACS Forwarders.
For example:

PS C:\..\Scripts> .\DisableACSForwarders.ps1
Root Management Server: rms.teknoglot.local
ACS Forwarder name (wildcard): *.teknoglot.local

You can also run it with parameters (for scheduling?) like this:

PS C:\..\Scripts> .\DisableACSForwarders.ps1 rms.teknoglot.local *.teknoglot.local

If you need to run the task with different credentials there’s a switch for that. Just add -UseCredentials to the command and you will be prompted for it.
Like this:

PS C:\..\Scripts> .\DisableACSForwarders.ps1 -UseCredentials

As you might already have realized, the wildcard search does not require actual wildcards. If you only want to disable the ACS forwarder on a single machine, just enter it’s FQDN. As for what wildcards it will accept; anything supported by the powershell -like operator is valid.

[UPDATE!] You might get false failures when running the script on clustered machines because of a bug in the AC Management Pack

 

For the source code, read on!

Read more …

Categories: OpsMgr 2007, PowerShell | Tags: ACS, OpsMgr, PowerShell, Script

“Load Balancing” Powershell Script for Operations Manager

Posted on April 15, 2010 by Sam T
3 Comments

I’ve been looking for at way to evenly distribute agents between Gateway Servers (or Management Servers for that matter, but I’ll stick to GWs this time) for some time but haven’t really got to fixing it myself until now.

The situation is basically that we’re monitoring customers through gateway servers connected to our central Operations Manager environment. To have a bit of redundancy we always put two (or more) gateway servers per site (or customer, really) and they, in turn, talks to a couple of central management servers. I guess a drawing would be nice, but I have no Visio on this computer. The gateways are manually configured to talk to different management servers and have the others configured for fail-over (through powershell) and since we’re talking about no more than a few handfuls (say 20-ish) it’s not a problem handling it that way.

Agents, on the other hand, are a different matter. Even though we try to spread them out somewhat evenly at deployment between the gateway servers at each site we still end up looking at a 3:2 ratio after a while and since agents do not automatically fail-over between gateway servers we need a way to fix that too.
So I wrote a little powershell script that takes a bunch of gateway servers (or management servers) as parameters, gathers all connected agents, spreads the agents evenly between the servers and configures the others as fail-over servers while at it.

It’s all pretty crude, but it works and you can download it from here: DistributeAgents.ps1
Save it somewhere on disk and call it from the Operations Manager Shell like this:

C:DistributeAgents.ps1 gateway01.customer.local,gateway02.customer.local,gateway03.customer.local

Yes, you should replace “C:” with whatever path you decided to save the script to and “gatewayXX.customer.local” with a real servername. ;)

Ok, I’m a powershell freshman and I’m pretty sure you could do this a prettier way, but here’s the script:

Param([array]$CSVServerList)

$arrServerObject = @()
$arrAgentObject = @()

foreach($Server in $CSVServerList)
{
	$arrServerObject += Get-ManagementServer | where {$_.Name -eq $Server}
	echo "Looking for $Server"
}
$ServerCount = $arrServerObject.Count
if ($ServerCount -gt 1)
{
	echo "Found $ServerCount management servers"
} else {
	echo "Found only 1 (or less) management servers. Aborting..."
	Exit
}

echo "Getting agents..."
foreach ($Server in $arrServerObject)
{
	$arrAgentObject += Get-Agent | where {$_.PrimaryManagementServerName -eq $Server.Name}
}
$AgentCount = $arrAgentObject.Count
if ($AgentCount -gt 1)
{
	echo "Found $AgentCount agents"
	Start-Sleep -m 200
} else {
	echo "Found only 1 (or less) agents. Aborting..."
	Exit
}
$i = 0
foreach ($Agent in $arrAgentObject)
{
	if ($i -ge $ServerCount)
	{
		$i = 0
	}
	$arrTemp = @($arrServerObject | Where-Object {$_ -ne $arrServerObject[$i]})
	# $FailoverServers = $arrTemp -join ","
	Set-ManagementServer -AgentManagedComputer: $Agent -PrimaryManagementServer: $arrServerObject[$i] -FailoverServer: $arrTemp

	$arrTemp = $null
	$i++
}

I have used it on a couple of occasions now and have only discovered a problem with an error when one of the servers don’t have any agents at all (probably a new one), but the script still works so I haven’t really dived into it.
Now, as with all scripts you download on the ‘net it’s up to you to test it in a lab before shooting wildly among your in-production systems. I really can’t give any warranties that it won’t FSU royally at your place.

Categories: OpsMgr 2007, PowerShell | Tags: OpsMgr, PowerShell, Script

Change Gateway Powershell Script

Posted on March 31, 2010 by Sam T
No Comments

This script has pretty much already been covered in my previous post about Changing or Replacing an Operations Manager Gateway Server.

This time I’ve basically put parameter support in it to make it easier to use.

Here’s the script anyway.


Param($OldGW,$NewGW)

$OldMS= Get-ManagementServer | where {$_.Name -eq $OldGW}
$NewMS = Get-ManagementServer | where {$_.Name -eq $NewGW}
$agents = Get-Agent | where {$_.PrimaryManagementServerName -eq $OldGW}
$agents = $agents
"Moving " + $agents.count + " agents from " + $OldMS.Name + " to " + $NewMS.Name
Start-Sleep -m 200
Set-ManagementServer -AgentManagedComputer: $agents -PrimaryManagementServer: $NewMS -FailoverServer: $OldMS

To use it, create a textfile called ChangeGW.ps1 and paste the code into it. Save the file somewhere neat (maybe C:Scripts) for easy access. If you don’t feel like copy/pasting, you can download the script here.

To use it, open the Operations Manager Command Shell and type:
C:ScriptsChangeGW.ps1 <old.gatewayserver.dns.name> <new.gatewayserver.dns.name>

For example:

C:ScriptsChangeGW.ps1 gwserver01.domainname.local gwserver02.domainname.local
Categories: OpsMgr 2007, PowerShell | Tags: OpsMgr, PowerShell, Script

Replace/Change a Gateway Server

Posted on September 24, 2009 by Sam T
1 Comment

If you are looking into replacing an (or just switching to another primary) Operations Manager 2007 Gateway Server for any reason, there’s a little more to consider than just right-clicking the clients and selecting “Change Primary Management Server” in the Operations Console.
You could end up with agents not being able to connect to the Management Group at all due to a small problem with the order in which Operations Manager do things.

Here’s basically what happens:

  • You tell Operations Manager to change Primary Management Server for AGENTX from GW1 to GW2.
  • The SDK Service (i guess) tells GW1 that “You’re no longer the Primary Management Server for AGENTX”
  • GW1 acknowledges this and stops talking to AGENTX. And I mean Completely stops talking to AGENTX.
  • OpsMgr then tells GW2 to start accepting communication from AGENTX.
  • OpsMgr tries to tell AGENTX that it should talk to GW2 since GW1 won’t listen.

Spotted the problem?
This modus operandi probably works when agents are on the same network and in the same domain where fail-over is sort of automatic. The problem we are facing now is that the server are telling the Gateway to stop accepting communications to and from the agent before the agent is notified that there is a new Gateway server to talk to. The agent will continue to talk to GW1 but will be completely ignored and you will probably start seeing events in the Operations Manager eventlog on GW1 with EventID 20000.

How do I get around this little feature then?

No matter if you found this article after running into the mentioned troubles or if you are googling ahead of time to be prepared, the fix is the same and consists of a few powershell scripts. These scripts are out there allready, but in different contexts, hence this post.

First step: Install the new Gateway

Documentation on this from Microsoft is good enough, but here’s the short version.

  1. Verify name resolution to and from Gateway server and Management Server
  2. Create certificate for the Gateway server
  3. Approve the Gateway server
  4. Install Gateway server
  5. Import certificates on Windows system
  6. Run MOMCertImport.exe on Gateway server to add the certificate into Gateway server configuration
  7. Wait

The wait is for the gateway server to get all needed configuration from RMS and to download all neccesary management packs, run all the discovery scripts and so on. When the Operations Manager event log has calmed down a bit, move to step two.

Second step: Configure Agent Failover

Connect to an Operations Manager Command Shell. Any will do, as long as it’s connected to the correct Management Group.
Then run the following script:

$primaryGW= Get-ManagementServer | where {$_.Name -eq 'GW2.domain.local'}
$failoverGw = Get-ManagementServer | where {$_.Name -eq 'GW1.domain.local'}
$agents = Get-Agent | where {$_.primarymanagementservername -eq 'GW1.domain.local'}
Set-ManagementServer -AgentManagedComputer: $agents -PrimaryManagementServer: $primaryGW -FailoverServer: $failoverGw

Remember to change “GW1.domain.local” to you OLD Gateway servername and “GW2.domain.local” to your NEW Gateway servername.
If you don’t know powershell, this script basically configures all agents using the old Gateway to use the new one as primare, but keep the old one as a fail-over server. The Gateways will still get to know the changes before the agents, but since the old on is still listening to the agents (though, as the fail-over host) it will be able to tell them to go to the new one, GW2.

Categories: OpsMgr 2007, PowerShell | Tags: How-To, OpsMgr, PowerShell, Script

w3Socket in VBScript

Posted on April 21, 2007 by Sam T
No Comments

I’ve been doing quite a lot of VBScripting in a couple of projects lately. The current one requires med to connect to a couple of telnet servers and look for… stuff.
Since we’re not in VB6 och .Net i cannot simply user Winsock as normally due to the lack of licensing features in VBS/WSH.

Thankfully for me, Dimac has release a nifty little component for free that makes talking telnet in VBS very simple.

I thought that, hey! I must share this!
So here’s an example in Classic VBS:

Dim oTelnet
oTelnet = CreateObject("Socket.Tcp")

With oTelnet
.DoTelnetEmulation = True
.TelnetEmulation = "TTY"
.Host = "192.168.242.1:23"
.Open
.WaitFor "SLUSSEN login:"
.SendLine "ANiftyUsename"
.WaitFor "Password:"
.SendLine "TEHP@ssw0rd"
.WaitFor "~ #"
.SendLine "ifconfig"
MsgBox .Buffer
.Close
End With

Set oTelnet = Nothing

Not very hard at all. This one is connecting to my router (with fake user/pwd… DUH!) and there’s no support for setting the prompt type there, thus the “~ #”.
The result of running this script with correct login info gives me a popup with the routers NIC-configuration.

Categories: VBS | Tags: Script
  • kaTWEET!

    • @joe_elway hehe, true. Bridgeways has always been a set-and-forget operation on my experience. Interesting to hear though.
  • Categories

    • Code
      • PowerShell
      • VBS
    • Linux
      • Fedora 11
      • RedHat ES
      • SLES
      • Ubuntu
    • Microsoft
      • Hyper-V
      • OpsMgr 2007
      • OpsMgr 2012
      • SQL 2005
      • SQL 2008
      • Windows 2008
      • Windows Vista
      • Windows XP
    • Technobabble
  • Recent Posts

    • Load-balanced SCOM2012 SDK Services for Network Illiterates [#opsmgr, #nlb]
    • Quick-Hack: Send SMS through Powershell [#powershell]
    • Rant – The Concept of Booth-Babes
    • Parameter Replacement in AlertName
    • Virtual OpenVPN Server at Home
  • Recent Comments

    • Sam T on “Load Balancing” Powershell Script for Operations Manager
    • ChrisAbel on “Load Balancing” Powershell Script for Operations Manager
    • pandora vpn on Virtual OpenVPN Server at Home
    • Giulise on Installing SQL Reporting Services 2005 on Windows 2008 x64
    • Sam T on Bulk disable ACS Forwarders (with wildcards)
© teknoglot:. Proudly Powered by WordPress | Nest Theme by YChong