Some scripting help for an extension attribute

blackholemac
Valued Contributor III

So my goal here is to create a simple extension attribute that will tell me whether a device is on or off the network. Given the wide swath of 10.x.x.x IPs that we use here (some are internal on the network, others are guest off the network), and the logic to that is hard to boil down easily, I have decided to go at this with an extension attribute.

Basically the extension attribute would go something like this:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE extensionAttribute PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<extensionAttribute>
  <displayName>On the network or not</displayName>
  <displayInCategory/>
  <dataType>string</dataType>
  <description>This Extension Attribute will let me know whether it is possible to ping a specific only on the network site. If the device cannot ping this site, then it is off the network.</description>
  <scriptContentsMac>#!/bin/sh

# my goal here is to send 2 pings to a given internal server. I know a status of 0 on exit means I can successfully ping the server. I just don't know how to write this syntax

if  [ /sbin/ping -c 2 'myinternalserver.local' HELP NEEDED HERE TO WRITE SYNTAX, IF THIS PING EXITS WITH A 0 STATUS ] ; then

   /bin/echo "on the network"

else
  /bin/echo "off the network"

fi
exit</scriptContentsMac>
</extensionAttribute>
6 REPLIES 6

alexjdale
Valued Contributor III

Here is what I use to test connection to my JSS, you can tweak this for other ports or servers:

connTest() {
    ncTest=`nc -z -w 5 $JSS 8443 > /dev/null; echo $?`
    if [ "$ncTest" -eq 0 ]; then
        log "JSS Reachable"
    else    
        log "JSS Not Reachable, exiting"
        exit 0
    fi
}

mm2270
Legendary Contributor III

No need to check exit status for a ping.
Something like this should work:

if [[ $(ping -c 2 -o 'myinternalserver.local') ]]; then
      echo "on the network"
else
      echo "off the network"
fi

BTW, the -o flag tells it to exit the pings as soon as it receives a successful response, so it should "lighten" the Extension Attribute script a little (not that pings are anything to be concerned with)

jrippy
Contributor III

Here's mine as well. I haven't used nc.
#!/bin/bash

SERVER="www.google.com"

function pingServer()
{ pingResult=$(ping -c 2 "$SERVER") if [ -z "$pingResult" ]; then result="off the network." elif [ ! -z $(echo $pingResult | grep "Request timeout") ]; then result="off the network." else result="on the network." fi
}

pingServer
echo "<result>$result</result>"

exit 0

c0n0r
Contributor

So, I would need to know more about the specifics you are trying to do, but I don't know if I think network state as an extension attribute is the best solution. Since extension attributes are only updated on recon, if you don't have your JSS available externally, the attribute will always show as being on network. But even if your JSS is reachable externally, network state can change multiple times between scheduled recons, especially in a VPN setting, so the extension attribute is likely to always be out of date.

Instead, I might suggest that you scope the policy to machines regardless of network state, and then build code into the script to determine action based on network state. Here is the code I use in several scripts:

VerifyConnection(){ curl -L -s -o /dev/null --silent --head --write-out '%{http_code}' "$FilerURL/" --location-trusted -X GET; }

If the website "$FilerURL/" (for bonus points, you could set the variable to $4-$11 and define those in the JSS interface) is online, then the above function will return "200". If it's not available, then you'll get the usual 403, 404, 500, etc.

One of the additional benefits of this method as you are testing not only for the client to have a viable route to the service, but also that the service is running on the server. My function works for HTTP services, if I needed to test SMB, FTP to other protocols (or any connection other than the usual web ports), I would agree with those recommending NetCat above. I would avoid Ping as it simply doesn't tell you enough about the state of the service.

blackholemac
Valued Contributor III

Thank everyone for the help.

To give context, JSS is both external and internal. Distribution point is not. Up until recently, we didn't really care, but now I need policies to run both places except for ones that install packages. On those I wish to exclude off the network macs so the policy doesn't show as failed to run. Ideas welcome. Distribution point is traditional AFP share right now. I figured the extension attribute method would work since the alternative would be scoping around network segments (which is a bag of hurt on our network)

c0n0r
Contributor

The solution I would use requires nested policy.

First, create a policy to deploy the package, scoped to all computers, ongoing, with a custom trigger.
Second, create a policy, scoped to all machines missing the software in question, schedule unimportant, on a recurring checkin. The second policy runs a script that checks for network connectivity to the distribution point, and if it can connect, it then fires off the custom trigger for the first policy.

Use the FIRST policy, not the second, for your metrics/logs.