I am looking for a way to create computer records in the JSS before the computers are enrolled. I would like to be able to set it to use the serial number for the computer name. I will have a spreadsheet with the serial numbers once they are ordered. We do use the DEP but discussions I have been reading indicate there is no way to leverage that for this.. It was suggested to me that I could use the API, but I have zero experience using it. Has anyone already done this, or done something like it that they could share? I'm willing to learn I am just on a very tight time table. Any help or suggestions would be appreciated.
The Inventory Preload is different than creating a computer record in Jamf Pro before it is is enrolled.
When you upload a CSV file or update the Inventory Preload data using the API, the data is stored in a different table and does not create a device record.
Once the device record is created after enrollment and the inventory report is sent to Jamf Pro, it does a lookup in this table for a matching serial number (and not the UUID). From there, it then updates the user and/or device information for that device based on what has been uploaded.
Additionally with each subsequent inventory report it will check to see what data is different, and overwrite the device information with what is in the Inventory Preload if it is different.
I hope then helps highlight the differences between the two approaches.
Here's a Feature Req. that addresses this from a different angle: use-serial-numbers-to-identify-macs-instead-of-udid-to-handle-mainboard-replacements
This issue is starting to bite us more and more. When we deploy computers, we need to pre-set various values in a jamf computer record before the machine is enrolled - even more so as we move to DEP-based user-self-enrollment. Our current system is almost painfully complicated because serialnumbers are not used to match existing records with enrolling devices, only udids.
Currently our admins use a homebuilt webapp to create a 'stub' jamf record with the known SN and the desired values. Then when the machine finally enrolls (via DEP or otherwise) there will be two records with that SN. A ComputerAdded webhook is triggered which uses the API to match the newly created 'real' record, with the pre-created 'stub' record by SN. It copies the values from the stub as needed, then marks the stub record for deletion. This has to happen very early in the deployment/configuration process, or things can go south in strange ways.
The whole thing is more complex and fragile than we'd like. If the JSS would just recognize the serialnumber as well as the UDID, our whole adopt-values-from-stub-record process can just go away. That would be wonderful.
Hello @ChrisL, thanks for the information.
For your workflow, what specific fields are you setting on the computer record? We've added Inventory Preload for Computers in 10.10.0 and it would be great to compare your list to new functionality to learn whether that meets your needs and would allow you to move away from your current solution.
Hi @drhoten I just saw your question.
I think the fields available in the CSV are sufficient - most of those we need are Ext Attribs.
The fields available aren't the problem; as it is documented now, the Inv. Preload system enforces the values from the CSV all the time - at every recon. To quote from the docs:
Important: When using Inventory Preload, any manual edits or mass action updates to computer and mobile device inventory details within Jamf Pro will be overwritten by the Inventory Preload data when inventory collection runs.
We need a way to pre-set these values once - just before the machine is deployed, and after that, the record is managed normally, and the values can be changed as desired. Using Inv. Preload, any time after enrollment that we wanted to change one of the pre-set values, we'd have to edit the CSV and re-upload it, rather than just changing the value directly in the computer's record. We would also have to make sure all admins who might make such changes know NOT to do so in the record, but using a custom tool that manipulates the Inv. Preload data via the API.
Even if Inv. Preload records could be told 'apply this only at enrollment' thats still more complex to automate and maintain than simply creating a new computer record with the correct SN and desired values, and waiting for it to enroll.
If the JSS would recognize the serialnumber of an existing record at enrollment, our current tools that pre-create the record would just work. There'd be no need for a webhook to adopt values from the pre-created record into the real record, nor the added complexity/fragility of maintaining the Inv. Preload.
PS: As mentioned in the feature request I linked above, recognizing the SN would also help in situations where a logic board has been replaced, which usually means a new UDID but the SN is retained (if the hardware tech didn't forget to set it, which happens, but is hopefully rare)
I use this python script..
Save CSV to webserver (somewhere)
Then run the script
#!/usr/bin/python ''' Rename computer from remote CSV using Jamf binary Pass in the URL to your remote CSV file using script parameter 4 The remote CSV could live on a web server you control, OR be a Google Sheet specified in the following format: https://docs.google.com/spreadsheets/u/0/d/<document ID>/export?format=csv&id=<document ID>&gid=0 ''' import os import sys import urllib2 import subprocess CSV_PATH = '/var/tmp/computernames.csv' def download_csv(url): '''Downloads a remote CSV file to CSV_PATH''' try: # open the url csv = urllib2.urlopen(url) # ensure the local path exists directory = os.path.dirname(CSV_PATH) if not os.path.exists(directory): os.makedirs(directory) # write the csv data to the local file with open(CSV_PATH, 'w+') as local_file: local_file.write(csv.read()) # return path to local csv file to pass along return CSV_PATH except (urllib2.HTTPError, urllib2.URLError): print 'ERROR: Unable to open URL', url return False except (IOError, OSError): print 'ERROR: Unable to write file at', CSV_PATH return False def rename_computer(path): '''Renames a computer using the Jamf binary and local CSV at <path>''' cmd = ['/usr/local/bin/jamf', 'setComputerName', '-fromFile', path] proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, _ = proc.communicate() if proc.returncode == 0: # on success the jamf binary reports 'Set Computer Name to XXX' # so we split the phrase and return the last element return out.split(' ')[-1] else: return False def main(): '''Main''' try: csv_url = sys.argv except ValueError: print 'ERROR: You must provide the URL of a remote CSV file.' sys.exit(1) computernames = download_csv(csv_url) if computernames: rename = rename_computer(computernames) if rename: print 'SUCCESS: Set computer name to', rename else: print ('ERROR: Unable to set computer name. Is this device in the ' 'remote CSV file?') sys.exit(1) else: print 'ERROR: Unable to set computer name without local CSV file.' sys.exit(1) if __name__ == '__main__': main()