Build a Computer Information script for your Help Desk

talkingmoose
Honored Contributor II

Jamf published Build a Computer Information script for your Help Desk on the Jamf Blog this morning. In that post I used the term "module" to refer to a short script snippet that can read a piece of information from a Mac and display that information as part of a dialog shown to the end user.

For example, this gets the computer name:

# Display computer name
runCommand=$( /usr/sbin/scutil --get ComputerName )
computerName="Computer Name: $runCommand"

05b901f8301343f282683f0a1a0b8f47

This Jamf Nation Discussion is for anyone who's needing assistance creating additional modules and/or helping others create modules.

78 REPLIES 78

rderewianko
Valued Contributor II

We have one like that, however it was just for displaying the monitor serial #.

MonitorSerialNumber=$(system_profiler SPDisplaysDataType | awk '/Display Serial Number/{print $NF;exit}')

jwojda
Valued Contributor II

it would be really helpful to have a prompt for the user to put in a ticket number and the email address to whom they wish to send it to (we have several IT people scattered across the country and don't have a single catchall email address for all of them.

The ticket number would help the tech look up and know what that user was looking for help with.

Otherwise, it looks great! thank you for sharing!

dmitchell
Contributor

I have Outlook set as the default mail app but every time I run "Enable Remote Support" mailto: pulls up Mac Mail. Can I call out Outlook? Any website or anything I use that has a mailto: link always opens Outlook. I don't know why this will not.

Also the directory binding shows as NO and connection failed, but my Mac is definitely bound to AD. Do I need modify something?

Other than that, the script works great for me.

rderewianko
Valued Contributor II

Once upon a time @Andrina wrote something to send emails through built in mail apps.

Here

In the actual script did you update the domain name for your AD?
Line in question

dmitchell
Contributor

Yeah, I already had a script that worked that sets Outlook as the default mail app. This specific script is pulling up mail though, any other mailto: link pulls up Outlook.

I did update the domain information. I will test it out again.

spalmer
Contributor III

@dmitchell Paul Bowden @pbowden from Microsoft has provided a silent PKG installer that sets Outlook as the default email client. It is compatible with Jamf Pro so it can be pushed out via policy. You could probably run this package before generating the Remote Support email. The package is located at https://macadmins.software/tools/.

dmitchell
Contributor

@spalmer This is exactly what I used. If I click a mailto: link on a website, it opens the message to send in Outlook. It's only specifically this script here that opens in Mac mail. I don't see anywhere in the script where it calls out Mac mail specifically.

spalmer
Contributor III

@dmitchell I hadn't read the article yet, but after skimming through, it doesn't look like the Remote Support section of the script is accounting for the fact that scripts run from Self Service are running as root. Since it is running as root the open "mailto:..." command will not know that Outlook is your default email client since that is a per user setting.

@talkingmoose You may want to update the article to run the open "mailto:..." command as the currently logged in Console user. You can copy the code from the postinstall script in the MailToOutlook.pkg which would essentially be:

CONSOLE=$(/usr/bin/python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");')

Then you could use that to call the mailto command as the currently logged in Console user which would hopefully pick up on the correct default email client settings.

sudo -u $CONSOLE /usr/bin/open "mailto:support@talkingmoose.pvt?subject=Computer Information ($serialNumber)&body=$displayInfo"

I haven't actually tested this so report back if it works.

ThijsX
Valued Contributor

Tried to sort out to check if it is possible to create a warranty section or age of laptop.
Like that warranty left over period is displayed.

hard to fix since there is a recaptcha on it

any thoughts?

djdavetrouble
Contributor III

I use the GSX integration to fill in warranty expiration field in the purchasing tab. @txhaflaire

ThijsX
Valued Contributor

@djdavetrouble Nice! i would love to use the GSX but the proces to request an GSX account is not that simple.
Need to be certified for repairing stuff etc right?

talkingmoose
Honored Contributor II

@jwojda, without going into some additional detailed scripting, you could remove the part of the mailto link that addresses the message to force end users to enter an address. Then you could also add to the to body or subject:

[ Please add your ticket number here ]

The Help Desk person would probably need to instruct the end user to add that.

talkingmoose
Honored Contributor II

Excellent catch @spalmer!

I'll be sure to add that mailto check. This is the same behavior folks see when opening HTTP links through Self Service and their default browser is something other than Safari.

Update: I've modified and tested the script with the change. Folks testing the mailto behavior, please let me know if it still doesn't work for you with the updated script.

tguyers360
New Contributor III

I wanted to put this on the MacBook instead of Selfservice so when there is no wi-fi connection the end user can provide information to the helpdesk on a phone call. I placed the script in /users/shared then used appify (https://mathiasbynens.be/notes/shell-script-mac-apps) to make an App and placed it in the Applications folder. I then used configurator to the create a package of the the App in Applications folder a the script in /users/shared a Doc item (called tec support with a nifty icon) to make it easy for the end user to find tec spport and the Microsoft silent PKG installer that sets Outlook as the default email client by Paul Bowden @pbowden that @spalmer mentioned above.(https://macadmins.software/tools/) now my end users can provide information over the phone and through remote support. I hope this helps someone :), happy for feedback if you have a better way

clarsanm
New Contributor

Hey guys, @rderewianko @dmitchell in that line,

where exactly should i add my domain AD?

Thanks!

mark_mahabir
Valued Contributor

Change the part after

/Active Directory/

in the following line to match your domain:

runCommand=$( /usr/bin/dscl "/Active Directory/TALKINGMOOSE/All Domains" read /Users )

clarsanm
New Contributor

@mark.mahabir thank so much for the tip, i actually did that before asking and didn't work, but i was hoping maybe that wasn't the right line, ill try on a different machine.

edit: i ask around and was using a wrong path for the domain, we correct that and we change the line 124 with the right domain address.

All good now, messing around with the other options for team-viewer now.

btw, this is a great exercise, specially for people like me with no great exposure to scripting on jamf(and in general)

thanks guys!

ianmb
Contributor

Another scripting beginner here...

How would I go about removing the 'Enable Remote Support' button altogether, is that possible? I really just want our users to be able to locate their computer name, serial & IP quickly when calling our Service Desk.

sdunbar
Contributor

Hi all,

Yet another script newbie here.

With regard to the Hardware section. Our Mac HD's are all named differently with the asset tag, is there a way to use a wild card in place of the "Macintosh HD", so we can get the disk space to display for each different user. I have tried a couple of things without success.

Also would anyone have a way to display no. of days until AD password expiry, that would be a great help to our Helpdesk.

Many thanks

ianmb
Contributor

To answer my own question, I just changed the line:

runCommand="button returned of (display dialog "$displayInfo" with title "Computer Information" with icon file posix file "/System/Library/CoreServices/Finder.app/Contents/Resources/Finder.icns" buttons {"Enable Remote Support", "OK"} default button {"OK"})"

to read:

runCommand="button returned of (display dialog "$displayInfo" with title "Computer Information" with icon file posix file "/System/Library/CoreServices/Finder.app/Contents/Resources/Finder.icns" buttons {"OK"} default button {"OK"})"

Great work and thank you, @talkingmoose

talkingmoose
Honored Contributor II

@ianmb, absolutely the right way to do that. You figured it out.

If you want to further clean up the script, you can remove the lines in the ## Run additional commands ##### section down to the exit 0. Their only purpose is to support that button. Optionally, you can leave them there in case you may want to re-add the button.

talkingmoose
Honored Contributor II

@sdunbar

With regard to the Hardware section. Our Mac HD's are all named differently with the asset tag, is there a way to use a wild card in place of the "Macintosh HD", so we can get the disk space to display for each different user. I have tried a couple of things without success.

Edit lines 146-147 and replace "Macintosh HD" with disk1s1 and test. That "device identifier" should generally work unless you've possibly partitioned your drives in some unusual way.

If that doesn't get you want you need, you can run the following command in Terminal on a test machine to find what does work. Replace "Macintosh HD" with the name of the drive on your test machine.

/usr/sbin/diskutil info -all | /usr/bin/grep "Macintosh HD" -B 6

What it's doing
The /usr/sbin/diskutil info -all part of this one-liner lists all the information for all your drives. The /usr/bin/grep "Macintosh HD" -B 6 part of the one-liner takes the results of the first command and returns just the lines that contain "Macintosh HD". Then it counts six lines up (before) from the "Macintosh HD" line and displays those lines too. The first one should be something like Device Identifier: disk1s1.

Also would anyone have a way to display no. of days until AD password expiry, that would be a great help to our Helpdesk.

This one's trickier. From what I've seen, we can read from the end user's AD account when the password was last changed, but we also need to know the domain's password policy. Does it require passwords change every 90 days? Every 180? I've yet to see a simple script that simply returns password expiration. NoMAD does have a feature to do this and will display remaining days in the menu bar. It's open source and free to use if you're willing to rely on the community for support.

Maybe someone else will have a better answer for your question.

mm2270
Legendary Contributor II

@sdunbar I'm glad you pointed that out about the "Macintosh HD" name being hardcoded. When looking at the script that popped out at me as well. These two lines

FreeSpace=$( /usr/sbin/diskutil info "Macintosh HD" | /usr/bin/grep  -E 'Free Space|Available Space' | /usr/bin/awk -F ":s*" '{ print $2 }' | awk -F "(" '{ print $1 }' | xargs )
FreePercentage=$( /usr/sbin/diskutil info "Macintosh HD" | /usr/bin/grep -E 'Free Space|Available Space' | /usr/bin/awk -F "(\(|\))" '{ print $6 }' )

Can actually be simplified to the following, which should work fine since this won't necessarily be run from another booted volume I presume. The / instead of Macintosh HD tells diskutil to look at the boot volume, so essentially the same thing as "Macintosh HD" or whatever the volume is named.

FreeSpace=$( /usr/sbin/diskutil info / | awk -F'[:|(]' '/Free Space|Available Space/{print $2}' | xargs )
FreePercentage=$( /usr/sbin/diskutil info / | awk -F'[(|)]' '/Free Space|Available Space/{print $6}' | xargs )

See if that gets you what you want.

sdunbar
Contributor

Many thanks @mm2270 & @talkingmoose

Both of those worked a charm, I think I'll go with the more generic / instead of Macintosh HD as that will be more forgiving with our eclectic naming conventions.

With regard to the AD password expiry, I did find a post on setting it as an Extension Attribute here based on a 90 day policy, but could not successfully get it into the script to display with the rest of the info.

We have looked as Nomad etc before, but I thought it would be nice and easy for the Helpdesk to have it all in just one place.

Again much appreciated for all of the above.
Cheers!

talkingmoose
Honored Contributor II

@sdunbar, that was an excellent script source for days until password expiration. It was fairly easy to make this into something you can add to the full script. I took a little liberty to clean up the code but for the most part used that solution here.

Paste the following snippet somewhere in the body of the script. I suggest around line 140 after the # Test Active Directory binding section. You'll need to modify both the domainName and maximumAge values near the top.

# Display days to AD password expiration

# NetBIOS domain name
domainName="TALKINGMOOSE"

# Maximum password age in days
maximumAge=90

# Get current user
currentUser=$( stat -f "%Su" /dev/console )

# Last password set date
lastPasswordSet=$( dscl "/Active Directory/$domainName/All Domains" read "/Users/$currentUser" SMBPasswordLastSet | awk '{print $2}' )

# Calculations
lastPasswordCalc1=$(( $lastPasswordSet / 10000000 - 1644473600 ))
lastPasswordCalc2=$(( $lastPasswordCalc1 - 10000000000 ))
timeStampToday=$( date +%s )
timeSinceChange=$(( $timeStampToday - $lastPasswordCalc2 ))
daysSinceChange=$(( $timeSinceChange / 86400 ))
daysRemaining="Active Directory password expiration: $(( $maximumAge - $daysSinceChange )) days"

The last variable daysRemaining is what we want to add to displayInfo. I suggest in this section of the script:

----------------------------------------------
ACTIVE DIRECTORY

$AD
$testAD
$daysRemaining
----------------------------------------------

The end result looks like:
0068687804d94486b9462b647ecb4346

sdunbar
Contributor

@talkingmoose, again many thanks.

I have done as you suggested, and it does give a result, but it shows as -152465 days!

So not quite sure what happened there, (the extension attribute shows 89).

Rklaffo1
New Contributor II

Hello @talkingmoose I wanted to update the script for the Enable Remote Support to launch a web browser with a webex url. I can get the command to work in Terminal specifically but not with the button that you had created within the script. Any help would be greatly appreciated.

I had changed it to the following: /usr/bin/open -a "/Applications/Safari.app" 'https://mercymeetings.webex.com/mw3200/mywebex/default.do?siteurl=mercymeetings'

milesleacy
Valued Contributor

I forked and went in some different directions. For anyone interested, here it is...
https://github.com/themacadmin/Jamf-Scripts/blob/master/Computer%20Information.bash

Happy to answer questions on what I did differently and why.

ammonsc
Contributor II

This script is awesome. I also added in two sections for our Helpdesk.

Here will Display the Asset Tag

## Find asset tag number
##Get MacAddress
MACaddy=$( networksetup -getmacaddress en0 | awk '{print $3}' | sed 's/:/./g' )
echo "${MACaddy}"

##Get Asset Tag
runCommand=$( curl -s -k -u jssapiusername:jssapipassword https://jamfserver:8443/JSSResource/computers/macaddress/$MACaddy | xpath /computer/general/asset_tag | awk -F '[>|<]' '{print toupper($3)}' )
assetTag="Asset Tag: $runCommand"

And a way to display the Mac Model as seen in the "About This Mac" window

##Get MacModel
runCommand=$( curl -s -k -u jssapiusername:yourjssapipassword https://jamfserver:8443/JSSResource/computers/macaddress/$MACaddy | xpath /computer/hardware/model | awk -F '[>|<]' '{print ($3)}' )
macModel="Model: $runCommand"

Make sure to edit the JSS API Username and Password and the JSS Address

milesleacy
Valued Contributor

A couple of general notes...

If you’re going to pull multiple bits of info from the JSS’ computer record, make the API call once, and store the response in a variable or local file, then xpath out the attributes you need from that variable or file. #efficiency

If you’re running modern, supported macOS versions, you don’t have to go to Jamf for the model’s marketing (human-friendly) name. It can be derived locally. See my fork linked above for how (and if anyone can suggest how to simplify my “seds” on that one, please let me know.

mm2270
Legendary Contributor II

@milesleacy You should be able to simplify that line to this

defaults read /System/Library/PrivateFrameworks/ServerInformation.framework/Versions/A/Resources/English.lproj/SIMachineAttributes.plist "$modelIdentifier" | awk -F'= ' '/marketingModel/{print $NF}' | sed 's/;$//;s/^"//;s/"$//;s/\//g'

Just to note though, the names that show up in that plist don't match what shows up in the About This Mac window. They are fine for the purposes of this script, but they'll be different than what appears there in almost all cases.

talkingmoose
Honored Contributor II

@sdunbar, this is for the same user account on the same Mac?

To troubleshoot, you can add an echo statement below each of the lines in the Calculations section. This will show you the results returned for each calculation and we can see where things are not calculating correctly.

For example, change this:

lastPasswordCalc1=$(( $lastPasswordSet / 10000000 - 1644473600 ))

to this:

lastPasswordCalc1=$(( $lastPasswordSet / 10000000 - 1644473600 ))
echo "Last Password Calc 1 = $lastPasswordCalc"

Run the script again from your policy and then look at the policy logs. Are you able to see where the calculations are failing?

milesleacy
Valued Contributor

@mm2270

Thanks, that worked well.

I certainly haven't tested on every model, however, on all of the models I have tested, I get accurate results.

Are you aware of specific models that don't work (on macOS v10.12 or later)?

Reno
New Contributor III

@txhaflaire talk to your Apple reps. They now have a GSX integration just for pulling warranty information without keeping a technician certified. As far as I've gleaned, its for new GSX customers and requires a minimum number of managed devices.

ThijsX
Valued Contributor

@Reno sounds awesome, do you mean by Apple Reps, our authorized repair centre for reparations?

Reno
New Contributor III

@txhaflaire no, Apple has account executives and systems engineers that visit Universities regularly. I heard of this new option through the engineer assigned to my institution. If you don't have a regular contact at Apple, I'd call 1-800-MY-APPLE.

talkingmoose
Honored Contributor II

@Rklaffo1, I tested your line to open Safari with the URL and it works just fine for me when I click the button. I used my Jamf Pro server and ran the script entirely through Self Service.

That leads me to believe your code is correct but that something may be amiss with your test computer. Have you tried another computer?

Also, in your testing, does Safari actually launch? If not, try removing the command to use Safari to open the URL and just open the URL directly. Or does Safari open but not display the URL? Test with a different simple URL like 'https://www.apple.com'. Can your computer reach that site?

mm2270
Legendary Contributor II

@milesleacy Sorry, I need to clarify what I was saying. The method of getting the full model name from the plist works fine. And I don't know of a case where it produces the wrong results. What I meant was, the model names that appear there are not worded the same as what you see from the Apple menu's About this Mac window.

Here's an example.
My Mac is a Mid 2015 15" MBP model. in the "About" window, it displays MacBook Pro (Retina, 15-inch, Mid 2015)
If I get the model name from that plist, it shows 15" MacBook Pro with Retina display (Mid 2015)
So as you can see, it's the same machine and similar full model names, just worded a bit differently, or parts are rearranged, etc. It's not a huge deal. Just something to be aware of when using it.
As an aside, there is a way to get that actual name that shows up in the About This Mac window, but it involves doing a query against one of Apple's pages using part of the machine's serial number. It works, but it's not an offline method.

Anyway, glad the adjustment helped.

milesleacy
Valued Contributor

Thanks @mm2270

That makes sense.

If I were using the “marketing model name” strings as keys in further logic, that would be a concern.

Since I use this dialog simply for human information, the slight difference in syntax shouldn’t be a problem.

Good to be aware of these things though so I don’t later try to execute logic on these strings!