{"id":867,"date":"2020-11-06T02:50:28","date_gmt":"2020-11-06T07:50:28","guid":{"rendered":"https:\/\/www.brunerd.com\/blog\/?p=867"},"modified":"2020-11-10T01:41:01","modified_gmt":"2020-11-10T06:41:01","slug":"jpt-jamf-examples","status":"publish","type":"post","link":"https:\/\/www.brunerd.com\/blog\/2020\/11\/06\/jpt-jamf-examples\/","title":{"rendered":"jpt: jamf examples"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/github.com\/brunerd\/jpt\" target=\"_blank\" rel=\"noreferrer noopener\"><code>jpt<\/code><\/a> has some practical applications for the Jamf admin<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Sanitizing Jamf Reports<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s say you&#8217;ve exported an Advanced Search, it&#8217;s got some interesting data you&#8217;d like to share, however there is personal data in it. Rather than re-running the report, why not blank out or remove those fields?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s a sample file: <a rel=\"noreferrer noopener\" href=\"https:\/\/gist.github.com\/brunerd\/0bdc10e879c68cd71e82f0feba4b4390\" target=\"_blank\">advancedcomputersearch-2-raw.json<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This an excerpt from one of the computer record:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n\"name\": \"Deathquark\",\n\"udid\": \"2ca8977b-05a1-4cf0-9e06-24c4aa8115bc\",\n\"Managed\": \"Managed\",\n\"id\": 2,\n\"Computer_Name\": \"Deathquark\",\n\"Last_Inventory_Update\": \"2020-11-04 22:01:09\",\n\"Total_Number_of_Cores\": \"8\",\n\"Username\": \"Professor Frink\",\n\"FileVault_2_Status\": \"Encrypted\",\n\"JSS_Computer_ID\": \"2\",\n\"Number_of_Available_Updates\": \"1\",\n\"Model_Identifier\": \"MacBookPro16,1\",\n\"Operating_System\": \"Mac OS X 10.15.7\",\n\"Model\": \"MacBook Pro (16-inch, 2019)\",\n\"MAC_Address\": \"12:34:56:78:9A:BC\",\n\"Serial_Number\": \"C02K2ND8CMF1\",\n\"Email_Address\": \"frink@hoyvin-glavin.com\",\n\"IP_Address\": \"10.0.1.42\",\n\"FileVault_Status\": \"1\/1\",\n\"Processor_Type\": \"Intel Core i9\",\n\"Processor_Speed_MHz\": \"2457\",\n\"Total_RAM_MB\": \"65536\"\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now let&#8217;s say the privacy standards for this place is GDPR on steroids and all personally identifiable information must be removed, including  serials, IPs, UUIDs, almost everything (but you don&#8217;t want to run the report again because it took ages to get the output)!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s what that command would look like: <code>jpt -o replace -v '\"REDACTED\"' -p '$[\"advanced_computer_search\"][\"computers\"][*][\"name\",\"udid\",\"Username\",\"Computer_Name\",\"MAC_Address\",\"Serial_Number\",\"Email_Address\",\"IP_Address\"]'<\/code> .\/<a rel=\"noreferrer noopener\" href=\"https:\/\/gist.github.com\/brunerd\/0bdc10e879c68cd71e82f0feba4b4390\" target=\"_blank\">advancedcomputersearch-2-raw.json<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s what that same computer looks like in the resulting output (as well as all others in the document):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  {\n    \"name\": \"REDACTED\",\n    \"udid\": \"REDACTED\",\n    \"Managed\": \"Managed\",\n    \"id\": 2,\n    \"Computer_Name\": \"REDACTED\",\n    \"Architecture_Type\": \"i386\",\n    \"Make\": \"Apple\",\n    \"Service_Pack\": \"\",\n    \"Last_Inventory_Update\": \"2020-11-04 22:01:09\",\n    \"Active_Directory_Status\": \"Not Bound\",\n    \"Total_Number_of_Cores\": \"8\",\n    \"Username\": \"REDACTED\",\n    \"FileVault_2_Status\": \"Encrypted\",\n    \"JSS_Computer_ID\": \"254\",\n    \"Number_of_Available_Updates\": \"1\",\n    \"Model_Identifier\": \"MacBookPro16,1\",\n    \"Operating_System\": \"Mac OS X 10.15.7\",\n    \"Model\": \"MacBook Pro (16-inch, 2019)\",\n    \"MAC_Address\": \"REDACTED\",\n    \"Serial_Number\": \"REDACTED\",\n    \"Email_Address\": \"REDACTED\",\n    \"IP_Address\": \"REDACTED\",\n    \"FileVault_Status\": \"1\/1\",\n    \"Processor_Type\": \"Intel Core i9\",\n    \"Processor_Speed_MHz\": \"2457\",\n    \"Total_RAM_MB\": \"65536\"\n  }<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">What we did was use the <code>-o<\/code> <code>replace<\/code> operation with a <code>-v &lt;value&gt;<\/code> of the JSON string <code>\"REDACTED\"<\/code> to all the paths matched by the JSONPath union expression (the comma separated property names in brackets) of the <code>-p<\/code> option. JSON Pointer can only act on one value at a time, this is where JSONPath can save you time and really shines.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>jpt<\/code> is fast because WebKit&#8217;s JavascriptCore engine is fast, for instance there is a larger version of that search that has 15,999 computers, it took only 11 seconds to redact every record.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>jpt -l $.advanced_computer_search.computers .\/advancedcomputersearch.json\n15999\n\ntime jpt -o replace -v '\"REDACTED\"' -p '$.advanced_computer_search.computers&#91;*]&#91;\"name\",\"udid\",\"Username\",\"Computer_Name\",\"MAC_Address\",\"Serial_Number\",\"Email_Address\",\"IP_Address\"]' .\/advancedcomputersearch.json > \/dev\/null \n\n11.14s user 0.35s system 104% cpu 11.030 total<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Put Smart Computer Groups on a diet<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">When you download Smart Groups via the API, you will also get an array of all the computers objects that match at that moment in time. If you just want to back up the logic or upload to another system, you <em>don&#8217;t<\/em> want all those computers in there.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Sample file: <a rel=\"noreferrer noopener\" href=\"https:\/\/gist.github.com\/brunerd\/378def06cc7661da9ab6226eef7d8e96\" target=\"_blank\">smartgroup-1-raw.json<\/a><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"computer_group\": {\n    \"id\": 12,\n    \"name\": \"All 10.15.x Macs\",\n    \"is_smart\": true,\n    \"site\": {\n      \"id\": -1,\n      \"name\": \"None\"\n    },\n    \"criteria\": &#91;\n      {\n        \"name\": \"Operating System Version\",\n        \"priority\": 0,\n        \"and_or\": \"and\",\n        \"search_type\": \"like\",\n        \"value\": \"10.15\",\n        \"opening_paren\": false,\n        \"closing_paren\": false\n      }\n    ],\n    \"computers\": &#91;\n      {\n        \"id\": 1,\n        \"name\": \"mac1\",\n        \"mac_address\": \"12:34:56:78:9A:BC\",\n        \"alt_mac_address\": \"12:34:56:78:9A:BD\",\n        \"serial_number\": \"Z18D132XJTQD\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"mac2\",\n        \"mac_address\": \"12:34:56:78:9A:BE\",\n        \"alt_mac_address\": \"12:34:56:78:9A:BF\",\n        \"serial_number\": \"Z39VM86X01MZ\"\n      }\n    ]\n  }\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Lets&#8217; remove those computers with <code>jpt<\/code> and the JSON Patch remove operartion:<br><code>jpt -o remove -p '$.computer_group.computers' .\/<a rel=\"noreferrer noopener\" href=\"https:\/\/gist.github.com\/brunerd\/378def06cc7661da9ab6226eef7d8e96\" target=\"_blank\">smartgroup-1-raw.json<\/a><\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Since the target is a single property name, JSON Pointer can also be used:<br><code>jpt -o remove -p \/computer_group\/computers .\/<a rel=\"noreferrer noopener\" href=\"https:\/\/gist.github.com\/brunerd\/378def06cc7661da9ab6226eef7d8e96\" target=\"_blank\">smartgroup-1-raw.json<\/a><\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"computer_group\": {\n    \"id\": 12,\n    \"name\": \"All 10.15.x Macs\",\n    \"is_smart\": true,\n    \"site\": {\n      \"id\": -1,\n      \"name\": \"None\"\n    },\n    \"criteria\": &#91;\n      {\n        \"name\": \"Operating System Version\",\n        \"priority\": 0,\n        \"and_or\": \"and\",\n        \"search_type\": \"like\",\n        \"value\": \"10.15\",\n        \"opening_paren\": false,\n        \"closing_paren\": false\n      }\n    ]\n  }\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Further Uses<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Using only JSON Patch <strong>replace<\/strong> and <strong>remove<\/strong> operations this JSON could have its <code>id<\/code> removed to prep it for an API POST on another JSS to create a new group or the name and value could be modified in a looping script to create multiple JSON files for every macOS version. The <code>jpt<\/code> is flexible enough to handle most anything you throw at it, whether you are using the standalone version or have embedded it in <em>your<\/em> scripts. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Stop by the <a href=\"https:\/\/github.com\/brunerd\/jpt\" target=\"_blank\" rel=\"noreferrer noopener\">jpt GitHub page<\/a> to get your copy<\/p>\n","protected":false},"excerpt":{"rendered":"<p>jpt has some practical applications for the Jamf admin Sanitizing Jamf Reports Let&#8217;s say you&#8217;ve exported an Advanced Search, it&#8217;s got some interesting data you&#8217;d like to share, however there is personal data in it. Rather than re-running the report, why not blank out or remove those fields? Here&#8217;s a sample file: advancedcomputersearch-2-raw.json This an [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[46,37,41,12],"tags":[47,30,34],"class_list":["post-867","post","type-post","status-publish","format-standard","hentry","category-jamf","category-jpt","category-jsonpath","category-scripting","tag-jamf","tag-jpt","tag-json"],"_links":{"self":[{"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/posts\/867","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/comments?post=867"}],"version-history":[{"count":6,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/posts\/867\/revisions"}],"predecessor-version":[{"id":893,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/posts\/867\/revisions\/893"}],"wp:attachment":[{"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/media?parent=867"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/categories?post=867"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/tags?post=867"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}