IBMs Enrollment Screen Recreated

jtratta
New Contributor III

Hi all,

Like many, I wanted my very own enrollment screen like the one IBM showed at the JNUC. I threw something together that works very similarly. This is a native app written in swift. I did try and make it easily editable for anyone to use and customize without knowing how to code. Here's the repo...I'll be updating and adding things as time goes on and cleaning it up.

You'll need to supply a html based page with your site specific information and then specify where 4 different packages land in the installation so the progress bar can display accurate information.

https://github.com/jason-tratta/ProgressScreen

137 REPLIES 137

jtratta
New Contributor III

@m.gunnarsson I have deployed this two different ways. 1) Creating a package with a post flight script that launches that app. 2) Creating a login agent that launches the app at login. We start with FileVault encryption at enrollment…so the agent comes in handy after the user has to log out.

Making the progress bar follow the polices is tricky...and custom to your environment. In the example on GitHub, it uses 4 "Waypoints" and an estimated time to guess where the progress bar should be. Since I didn't want to use the API for this (which would require embedded credentials, and there’s no good way to get policy completion) it's simply looking at the jamf.log file to gauge progress. I'm our environment, the order in which polices trigger is fairly predictable. I you look at the file AppDelegate.swift you'll see where you can add the waypoints:

 // Determine which installer packages should happen in what order in your installation
//This will update the progress bar for a more accurate time estimate.
    let quarterProgress = "GLOBAL_Cyberduck4.7.2.pkg"
    let halfProgress = "packageName"
    let threeQuartersProgress = "packageName"
    let lastPackage = "packageName"

For quitting, the app will quit its self when the 4th waypoint is reached. Alternatively, I deploy a script in a policy that runs last...I just add a ZZ- to the policy name. The script quits the app, removes the files, and then opens Self-Service. Mine looks something like this.

osascript -e 'quit app "ProgressScreen"'
rm -rf /Applications/ProgressScreen.app 
rm -f /Library/LaunchAgents/com.iu.ProgressScreen.plist
rm -f /Library/LaunchDaemons/com.iu.continueEnrollment.plist

open -a /Applications/Self Service.app/Contents/MacOS/Self Service

Hope that helps.

mbezzo
Contributor III

Hi All,
So I've got a custom HTML page all created, but I'm having a heck of a time figuring out how to move the progress bar. Can anybody give me a couple pointers on where and how to control that?

Thanks!
mbezzo

hkabik
Valued Contributor

I have this working beautifully with both our test DEP deployments and in a Self Service tool I made for incorporating new machines into our environment (growth through acquisition is the name of the game here).
It's really great and I am truly thankful someone took the time to make this.

@mbezzo As stated above, before you build the App edit the ViewController.swift file and put in your estimated time of completion (in seconds) and mark your waypoints.

// Determine which installer packages should happen in what order in your installation
//This will update the progress bar for a more accurate time estimate.
    let quarterProgress = "GLOBAL_Cyberduck4.7.2.pkg"
    let halfProgress = "packageName"
    let threeQuartersProgress = "packageName"
    let lastPackage = "packageName"

So if you have 10 packages installing, you would make the 3rd package to be installed the "quarterProgress", the 5th "halfProgress", the 7th "threeQuartersProgress" and the 10th "lastPackage". When that last package completes installation the app will quit on it's own.

It will look something like:

// Determine which installer packages should happen in what order in your installation
//This will update the progress bar for a more accurate time estimate.
    let quarterProgress = "things.pkg"
    let halfProgress = "stuff.pkg"
    let threeQuartersProgress = "morethings.pkg"
    let lastPackage = "abitmorestuff.pkg"

mbezzo
Contributor III

Sorry! After reading my post again, I definitely wasn't very clear! I meant how to physically change the location of the progress bar when on screen. Currently it's centered at the bottom, but I'd like to be able to move it around a bit.

Thank you!

hkabik
Valued Contributor

Ah, I'm not talented with that stuff at all. Couldn't figure out how to move it so I just swapped our logo in place of the iMac image and changed the wording and called it a day.

I'm sure some folks much more clever than myself can answer that for you, then I will plunder their knowledge as well. ;)

jtratta
New Contributor III

@mbezzo @hkabik I imagine you guys are probably running into problems with auto layout. If you select "MainMenu.xib" in Xcode you'll find a section called "The Window." The Window contains the web view (used to display your HTML), the progress bar, feedback text, and the quit button.

1) Click on the progress bar, it should highlight. 7e4e6196f53b4b9399784fc0e07dab18

2) Move the bar to where ever you like. In this image I'm also moving the feed back text. 7d681e13c1df41168328ce9e18893c8e

3) Now you need to set the constants for Auto Layout. One of the easiest ways is to select "Reset to Suggested Constraints" from the triangle-like menu at the bottom of the screen.

d6f2c8e6b0dd4ef3b4b816bbff4f312d

This isn't full proof. You might need to monkey around with the constraints to get exactly what you want. The other buttons at the bottom of the screen also deal with setting constraints. If you really want to dig into it...just Google Xcode Autolayout. I've also noticed an odd bug with the progress bar that if you make it too long, it vanishes when the app goes full screen.

mbezzo
Contributor III

Thank you! That's exactly what I was looking for and wow - being new to Xcode that just wasn't as obvious to me as I was thinking. :)

Thanks again!
Matt

mbezzo
Contributor III

alright, hopefully one final question. I've got a simple 800x600 html file customized like the above examples. How can I constrain the progress bar to a specific spot in that 800x600 rectangle and just have the blank space "float" to fill the varying screen sizes? Right now the progress bar just floats at the very bottom of the window. I realize this is an Xcode question and not necessarily related to this - feel free to point me somewhere else if you know of a good resource for this.

Thanks!
mbezzo

jtratta
New Contributor III

@mbezzo The "best" way to insure that everything is where you'd like it is probably breaking up the different components even more. Instead of having one giant HTML view, have several views and then use constraints to get the layout you want on any given screen size. The constraints keep UI elements in relative positions to each other, unfortunately there is no easy way constrain to the HTML inside the web view. Think of your final image as several components constraining against each other and then start to break them up that way. As the screen size changes, the layout adapts.

I think IBM likely did something like this, but I think they were using a static Image, web view, and a progress bar. I wanted to keep the example as simple as possible but, just about any book on Cocoa Programming for OS X or Web Tutorial ( I prefer the Big Nerd Ranch Books) should be able to get you comfortable with adding UI elements. It's mostly drag, drop, and connect with almost no code familiarity needed. You're getting into the nuts and bolts of UI design....but hey...when you're done you'll be able to layout UI's for any Apple Device!

Hope that helps.

loceee
Contributor

This is great. I am watching with great interest, and apologies if I am out of line as I haven't had really close look at the code.

I do have a suggestion, rather than hard coding waypoints into the swift code, I'd like to see the jamf.log monitored and the progress waypoints encoded into the policy name. Similar to how iHook and cocoaDialog do progress.

eg. log entry.

jamf: Executing Policy A1 #20 Binding to Directory ... 
jamf: Executing Policy Setting-Computername
jamf: Executing Policy B1 #75 Installing Top Secret Apps ...

Naming your provisioning policies with an excluded preceding code (to actually order the execution) and if then a # numeric code to update progress bar with percentage and a friendly text.

Very rough idea, but it makes it much easier to tweak timings and will provide visibility in the JSS, and will remove the need to hard code things into the app.

mbezzo
Contributor III

weird, I so posted a "thank you" reply last week, but it seems to have disappeared! So, thanks again @jtratta - that was great advice.

After playing around with it for a bit, I decided to just leave it at the bottom and centered. I borrowed heavily from IBM's app, and just put a GIF spinner in place. So I've got two versions of this now - one for our initial "machine level" settings, and then a second for when we customize the user profile. I'm pretty happy with it!

15fca567e3f947b08bc8948a970c5831

McAwesome
Valued Contributor

This is monitoring the jamf log, right? Would it be possible to tell this how many policies will run through a command? So say I have whatever the first policy is end with a command saying something like "sudo jamf policy -event Enrollment_Screen_20". This would add

Checking for policies triggered by "Enrollment_Screen_20"

into the jamf.log file. We could then parse out the number 20 and then use that to determine how many policies will be run in total. So instead of having four hard coded waypoints, you have X waypoints where X is the number from that event.

This would in theory be a way to tell it how many policies will be run without requiring hardcoding the JSS information or package names into the enrollment screen itself.

I'll poke around and see if I can get it working like that, but I'm so unfamiliar with Swift and rusty with coding in general that I'm not sure I'll get it working in a timely fashion.

jtratta
New Contributor III

@mbezzo That looks great! Glad I could help.

@McAwesome That's a pretty clever idea. You could also have a second event that tells the app the approximate time so the bar moves at about the right pace. I'll see if I can come up with something...that shouldn't be too difficult. Thanks for the idea!

mm2270
Legendary Contributor III

Seems like @loceee made a similar suggestion a few posts up, about getting progress bar indicators from the policy names in the jamf.log.
BTW, I keep coming back here to see what you all are doing in this space, and I'm impressed. This is looking very very nice. If we ever get around to moving to a DEP model here, we'll be sure to check this out. Thanks for the hard work on this.

spotter
New Contributor III

@mbezzo, @rdwhitt, and @jphillips would you be willing to share your code?

I really like the different looks / ideals and would like to try and corporate this into are workflow....

Kumarasinghe
Valued Contributor

@jtratta I would like to ask one 2 more thing as well.
1) Can you make this program stay on top of all other pop-ups, messages and Dock animations. Like jamfHelper?

I can see Notification Center messages and some installation windows make this window to dissapear.

2) Make this program to run on all connected screens (again like jamfHelper)?

Thanks

mbezzo
Contributor III

Hi @spotter,
It's sorta hard to share, but I'll try to go over what I did (and I think others are doing). I used Adobe Muse (wysiwyg html app) to create the html that's placed in the app @jtratta made. It's super simple, basically just drag and drop. So I grabbed our logo, dropped it in. Then figured out what few items I wanted to call out, then did a google image search for icons that I liked. Some of them were only in color, so I brought them into Pixelmator and made them black and white. Then I just arranged them how I liked, and exported the html. Dragged the resulting files into the "htmlFiles" folder in the Xcode project, and you're all set.

Hopefully this will get ya pointed in the right direction.

As for the other progress ideas - sounds great. Hopefully someone can figure out a slick way of dealing with this so we don't have to build a new App everytime the packages change. Looking forward to future updates. :)

Thanks!
mbezzo

jbruno
New Contributor

For those of us that are not very good at this app creation thing. Does anyone have a step by step guide on how to go about getting this done?

ImAMacGuy
Valued Contributor II

@jbruno +1 :)

I downloaded it off git, but am pretty lost, can't find some of the view controller stuff they were talking about..

rdwhitt
Contributor II

Once you have downloaded the project and opened it in Xcode, you'll need to navigate to a couple of areas.

  1. The AppDelegate.swift file is what you will use to edit your estimated time and waypoint packages. This is what currently defines how the progress bar moves.
    796f0ceecbc5462a95de109e7ac45d63

  2. You can replace all of the folders/files under the html folder with your own HTML. @jtratta used Adobe Muse, but pretty much any HTML editor can be used.
    9446f26c9f3d4158a0e1c14d49bee475

Then hit the play button at the top of the Xcode window to build the project and it will open in full screen.

DBrowning
Valued Contributor II

If you wanted this to go full screen on any screen that maybe plugged in...how would you do so? I know nothing about coding in swift

rafemoody
New Contributor

Hello,

First of all, this is a great app and I look forward to customizing it for our environment. One problem we are having is getting it to run in fullscreen mode by default. When I run from the command line locally with ./ProgressScreen it runs fine. When I do the same command remotely as part of a script, it comes up smaller and needs to be made full screen. I checked the code and it looks like it is set to run full screen by default. Is there some modifications I need to make to the code or the HTML to make this work? Or, am I launching this wrong and should be using an open command? Any information would be appreciated.

Thank you,

Rafe Moody

chris_kemp
Contributor III

Got a problem, maybe someone can help...I built a page in Muse, and it looks fine in a normal browser; so I did an "export as HTML" and got the files & folders. Page still looks fine in a browser.

However, when I copy the files & folders to the Xcode project & run it, the build succeeds but the page loads no graphics at all, so all I have is a bunch of blue ? on a blank page. The image files are in the folder, though... any thoughts where I may be going wrong?

kstrick
Contributor III

it's the file references... you have to alter the HTML, so that any references to 'images/image.png" would be "image.png", and the same with .css files and scripts (.js) files...

chris_kemp
Contributor III

Ah, gotcha - thanks! :) <--- more comfortable with BASH than CSS...but I'll get there.

hdsst3
New Contributor

There are many files here.

https://github.com/jason-tratta/ProgressScreen

Can't tell which file is for what.

Documentation extremely lacking.

And This is a poor readme.

" This is my recreation of the Casper Enrollment screen IBM showed at JAMFs user conference.

About: Simply, this is a full screen application that uses a Webview to display information to the user. This can either be an embedded html file or a website. The application monitors the jamf.log and in conjunction with waypoints and estimated time displays a progessbar to the user. When the last package is installed, the application quits. The user can quit the screen any time with Command-Q.

Usage: The application uses waypoints you set and monitors the jamf.log to give the user feedback. In the ViewController.swift file simply edit the esitmatedCompletionTime and the package waypoints.

You can replace the files in "htmlFiles" with your own index.html, or, edit the url path in the "loadWebPage()" method

franton
Valued Contributor III

It's an open source project, it takes contributions. If you think you can improve something, go for it like I'm attempting to do. Whining about it isn't doing you any favours.

gavin_pardoe
New Contributor III

As franton has stated above, Jason has been posted this freely as open source for the purposes of helping other admins out, its not something he had to do at all. If you read though the post you will find plenty more information about its creation and usage.

That fact there is limited information can be seen as a good thing. It gives you the opportunity to work out how this works and what each file is used for. You learn more from working things out then you do from hand holding.

you might want to read up on Swift and Xcode a little before playing with something like this:

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/
https://developer.apple.com/swift/
https://developer.apple.com/library/tvos/documentation/ToolsLanguages/Conceptual/Xcode_Overview/index.html

jtratta
New Contributor III

I have created a new version that allows for configuration through scripting, no more coding / compiling needed. You can download the compiled application from the release section. This is still an early version, so do please keep that in mind. Feedback is most welcome. Thanks!

mbezzo
Contributor III

Very nice! Really appreciate the continued work on this!

Thanks,
mbezzo

franton
Valued Contributor III

I like the idea of what you've done with your new version. Question: wouldn't it have been easier for you to implement this as a plist instead of via applescript?

jtratta
New Contributor III

@franton Scripting is relatively easy to pull off in OSX apps. It's something I wanted to try...so this seemed like a good fit. I also liked the idea of being able to change things from the JSS without much hassle. Scripting seemed like the most accessible way for anyone to configure. By defualt, you could use either Apple or JavaScript now.

There's always another way...I'm sure I'll be adding other configuration methods down the road. The original hard coding option is still there as well.

Maximilian
New Contributor
New Contributor

Hey guys,

I am struggling around for some days with the progress screen.

In our environment we need it to come up for the first time when the login windows appears.

I played around with the loginlog of MagerValp which works as a privileged helper. But as this project is not a Swift project I am unable to find the missing link...

Maybe one of you has the missing link for me?

Thanks in advance.
BR,

Max

sgoetz
Contributor

Hey All and @jtratta

Im working on building the DEP Progress Screen. I downloaded it from Github today and built it as is. No changes to any code at all. Installed the ProgressScreen.app on my test machine. I than used Apple Script to set the way points like this:

tell application "ProgressScreen" set useWayPointMethod of every configuration to true set wayPointOne of every configuration to "Parallels AutoDeploy 11.0.2" set wayPointTwo of every configuration to "ALL - Adobe Flash Player 21.0.0.213" set wayPointThree of every configuration to "Enterprise Connect 1.5.3" set wayPointFour of every configuration to "Firefox v44"
end tell

When I ran the AppleScript it automatically launches ProgressScreen.app for me. I than go to terminal and run my test policy with sudo jamf policy -id 535. And watch the progress screen.

The progress bar is not updating at the waypoints. PS. I also tried running the the Apple Script with the filename instead of the Display name(as shown above) as well. That didn't make a difference.

Am I doing something wrong?

Thanks

Shawn G

jtratta
New Contributor III

@sgoetz

Shawn,

If you are running the script from the JSS, you may need to target the logged in user in order for the scripting to work. Try something like this. If that does not work you may have found a bug.

#!/bin/sh


user=`stat -f%Su /dev/console`
sudo -u $user /usr/bin/osascript <<TimeComplete

tell application "ProgressScreen"
set buildTime of every configuration to 840
end tell 

TimeComplete

sgoetz
Contributor

Hey @jtratta

Thank you for the quick response. I used the Apple Script Editor app on the test machine to make the changes while I was logged in the machine. Im trying to use way points cause that makes more sense to me than trying to figure out average time. Especially since people will be all over the world and there is no way for me to judge their internet speed connection. Or am I suppose to use both the time and waypoints.

Thank you!

Shawn G

jtratta
New Contributor III

@sgoetz

Shawn,

Let me see if I can explain this better....

Waypoints are triggered by the "Successfully installed..." line in the jamf.log. So if you set a waypoint to, word.app, when it sees "Successfully installed word.app" it triggers that waypoint.

The waypoints sub divide the estimatedCompletion time (this is buildTime in the scripting dictionary). Since the progress bar needs a time set to make forward motion, something needs to be set here. Be default, it's set to 1800 seconds. You could just set a really high number here, and let the waypoints make the jumps.

The waypoint intervals in order are 1/4, 1/2, 3/4, and Terminate. So...when wayPointTwo is triggered, the progressBar will jump to the 1/2 way point.

If you're finding that the waypoints aren't granular enough, you could setup a script or two to adjust the currentTime and buildTime to maneuver the bar anyway you'd like.

Hopefully that helps!

-Jason

sgoetz
Contributor

Hey @jtratta or anyone that has gotten this to work using way points

So the below AppleScript im running is below. I am running this on the test machine using AppleScript Editor.

tell application "ProgressScreen"
     set useWayPointMethod of every configuration to true
     set buildTime of every configuration to 2000
     set wayPointOne of every configuration to "Parallels Desktop Autodeploy 11.0.2."
     set wayPointTwo of every configuration to "ALL - Adobe Flash Player 21.0.0.213."
     set wayPointThree of every configuration to "Enterprise Connect 1.5.3."
     set wayPointFour of every configuration to "Firefox v44.0.2_IWA.pkg."
end tell

So first I run the above script, than i go to terminal and do sudo jamf policy -id 700, which is my test policy to test progress bar function. It only installs those 4 apps on the machine. However the progress bar is not jumping to 1/4, 1/2, 3/4, Full as they install successfully. I know its reading the log okay cause you can see the messages below the bar.

I tried first building the xCode project as 10.9 in debug mode. Than I tried 10.10 in debug mode. Than I tried just downloading the Scriptable version from the release section on Github. But they all have the same affect. Also Im not sure if this makes a difference, but the test machine is 10.11.4 El Cap.

Im not sure if Im doing the coding above wrong or if Im simply missing something, that probably obvious lmao.

Anyways, at this point Im stuck. Any help would be greatly appreciated.

Thanks All!!

Shawn G

jtratta
New Contributor III

@sgoetz

Shawn,

You've found a bug. I will get that fixed here shortly.

-Jason

sgoetz
Contributor

Hey @jtratta

Oh yay!! At least I know im not crazy!!

Thank you for all your work Jason on this.

Shawn