├── README.md ├── cw_deactivate.py ├── cw_rename_computer.py └── cw_bulk_new_enrollment.py /README.md: -------------------------------------------------------------------------------- 1 | # jamf_connectwise 2 | ## An integration between ConnectWise and Jamf Pro 3 | 4 | This project currently consists of 3 python scripts that automate the integration between Connectwise and Jamf Pro. These are provided as-is. They worked as of March, 2019 and are meant to get an organization started with automating workflows between ConnectWise and Jamf Pro. But APIs drift and we will not be maintaining the codebase. However, PRs are gladly accepted! 5 | 6 | # cw_bulk_new_enrollment.py 7 | This script allows syncing of information from Jamf Pro to ConnectWise. 8 | For instance, this script can run once a night for newly enrolled machines in Jamf and port them to the ConnectWise database. This can be based on a group membership for newly enrolled machines into Jamf Pro. 9 | 10 | ## REQUIREMENTS: 11 | - Requests python module on server/host machine 12 | - Jamf Pro with Smart Group of computers to port 13 | - A valid ConnectWise API Key 14 | 15 | # cw_deactivate.py 16 | This script can be attached to a policy in Jamf Pro that will update a field in ConnectWise. 17 | For instance, this script, when attached to a policy that is set to remove licensed 18 | software/framework from a client machine, can trigger settings of that device found in 19 | the ConnectWise database entry for that client machine to be adjusted. In this case, 20 | sets the ConnectWise configuration to "inactive" and changes the SLA to "No SLA" 21 | 22 | ## REQUIREMENTS: 23 | - Jamf Pro 24 | - ConnectWise 25 | 26 | # cw_rename_computer.py 27 | This script can be attached to a policy in Jamf Pro that will update a field in ConnectWise. 28 | For instance, this script, when attached to a policy that is set to remove licensed 29 | software/framework from a client machine, can trigger settings of that device found in 30 | the ConnectWise database entry for that client machine to be adjusted. In this case, 31 | sets the ConnectWise configuration to "inactive" and changes the SLA to "No SLA" 32 | 33 | ## REQUIREMENTS: 34 | - Jamf Pro 35 | - ConnectWise 36 | -------------------------------------------------------------------------------- /cw_deactivate.py: -------------------------------------------------------------------------------- 1 | #! /usr/local/bin/python 2 | 3 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 4 | # 5 | # Copyright (c) 2017 Jamf. All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions are met: 9 | # * Redistributions of source code must retain the above copyright 10 | # notice, this list of conditions and the following disclaimer. 11 | # * Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # * Neither the name of the Jamf nor the names of its contributors may be 15 | # used to endorse or promote products derived from this software without 16 | # specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY 19 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY 22 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 30 | 31 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 32 | # 33 | # This script can be attached to a policy in Jamf Pro that will update a field in 34 | # ConnectWise. 35 | # For instance, this script, when attached to a policy that is set to remove licensed 36 | # software/framework from a client machine, can trigger settings of that device found in 37 | # the ConnectWise database entry for that client machine to be adjusted. In this case, 38 | # sets the ConnectWise configuration to "inactive" and changes the SLA to "No SLA" 39 | # 40 | # REQUIREMENTS: 41 | # - Jamf Pro 42 | # - ConnectWise 43 | # 44 | # 45 | # Written by: Jonathan Yuresko | Professional Services Engineer | Jamf 46 | # 47 | # Created On: June 8, 2017 48 | # 49 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 50 | 51 | import urllib 52 | import urllib2 53 | import json 54 | from time import sleep 55 | import codecs 56 | import subprocess 57 | import os 58 | 59 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 60 | # VARIABLES 61 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 62 | 63 | # Your ConnectWise URL 64 | cw_url = "na.myconnectwise.net" 65 | 66 | # Your ConnectWise API Key 67 | cw_api_key = "" 68 | 69 | ############################################### 70 | ############################################### 71 | 72 | # Finds serial number of client computer 73 | get_serial = subprocess.check_output("system_profiler SPHardwareDataType | awk '/Serial/ {print $4}'", shell=True) 74 | serial_number = get_serial.rstrip() 75 | 76 | # Determines if client comptuer is "Server" or "Workstation" 77 | computer_type = os.path.isdir('/Applications/Server.app') 78 | if computer_type is True: 79 | machine = "Server" 80 | else: 81 | machine = "Workstation" 82 | 83 | # Prints computer data 84 | print 'Serial Number = {}'.format(serial_number) 85 | print 'Computer Type = {}'.format(machine) 86 | 87 | # Begins finding ConnectWise ID 88 | full_cw_url = "https://api-" + cw_url + "/v4_6_release/apis/3.0/company/configurations/?conditions=type/name='BTITS%20-%20" + machine + "'%20and%20SerialNumber='" + serial_number + "'" 89 | request = urllib2.Request(full_cw_url) 90 | request.add_header('Content-Type', 'application/json') 91 | request.add_header('Authorization', 'Basic ' + cw_api_key) 92 | 93 | response = urllib2.urlopen(request) 94 | response_json = json.load(response) 95 | cw_id = response_json[0]['id'] 96 | 97 | # ConnectWise ID 98 | print "ConnectWise ID = {}".format(cw_id) 99 | 100 | # Begins the deactivation (set to "Inactive", and "No SLA") 101 | update_cw_url = "https://api-" + cw_url + "/v4_6_release/apis/3.0/company/configurations/{}".format(cw_id) 102 | 103 | # Updating parameters 104 | post_params=[{ 105 | "op": "replace", 106 | "path": "sla", 107 | "value": {"name": "No SLA"} 108 | }, 109 | { 110 | "op": "replace", 111 | "path": "status", 112 | "value": {"name": "Inactive"} 113 | }] 114 | 115 | params = json.dumps(post_params) 116 | 117 | request = urllib2.Request(update_cw_url) 118 | request.get_method = lambda: 'PATCH' 119 | request.add_header('Content-Type', 'application/json') 120 | request.add_header('Authorization', 'Basic ' + cw_api_key) 121 | resp = urllib2.urlopen(request, params) 122 | 123 | print resp 124 | -------------------------------------------------------------------------------- /cw_rename_computer.py: -------------------------------------------------------------------------------- 1 | #! /usr/local/bin/python 2 | 3 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 4 | # 5 | # Copyright (c) 2017 Jamf. All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions are met: 9 | # * Redistributions of source code must retain the above copyright 10 | # notice, this list of conditions and the following disclaimer. 11 | # * Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # * Neither the name of the Jamf nor the names of its contributors may be 15 | # used to endorse or promote products derived from this software without 16 | # specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY 19 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY 22 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 30 | 31 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 32 | # 33 | # This script can be attached to a policy in Jamf Pro that will update a field in 34 | # ConnectWise. 35 | # For instance, this script, when attached to a policy that is set to remove licensed 36 | # software/framework from a client machine, can trigger settings of that device found in 37 | # the ConnectWise database entry for that client machine to be adjusted. In this case, 38 | # sets the ConnectWise configuration to "inactive" and changes the SLA to "No SLA" 39 | # 40 | # REQUIREMENTS: 41 | # - Jamf Pro 42 | # - ConnectWise 43 | # 44 | # 45 | # Written by: Jonathan Yuresko | Professional Services Engineer | Jamf 46 | # 47 | # Created On: June 8, 2017 48 | # 49 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 50 | 51 | import urllib 52 | import urllib2 53 | import json 54 | from time import sleep 55 | import codecs 56 | import subprocess 57 | import os 58 | 59 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 60 | # VARIABLES 61 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 62 | 63 | # Your ConnectWise URL 64 | cw_url = "na.myconnectwise.net" 65 | 66 | # Your ConnectWise API Key 67 | cw_api_key = "" 68 | 69 | ############################################### 70 | ############################################### 71 | 72 | # Finds serial number of client computer 73 | get_serial = subprocess.check_output("system_profiler SPHardwareDataType | awk '/Serial/ {print $4}'", shell=True) 74 | serial_number = get_serial.rstrip() 75 | 76 | # Finds computer name of client computer 77 | get_computer_name = subprocess.check_output("scutil --get ComputerName", shell=True) 78 | computer_name = get_computer_name.rstrip() 79 | 80 | # Determines if client comptuer is "Server" or "Workstation" 81 | computer_type = os.path.isdir('/Applications/Server.app') 82 | if computer_type is True: 83 | machine = "Server" 84 | else: 85 | machine = "Workstation" 86 | 87 | # Prints computer data 88 | print 'New computer name = {}'.format(computer_name) 89 | print 'Serial Number = {}'.format(serial_number) 90 | print 'Computer Type = {}'.format(machine) 91 | 92 | # Begins finding ConnectWise ID 93 | full_cw_url = "https://api-" + cw_url + "/v4_6_release/apis/3.0/company/configurations/?conditions=type/name='BTITS%20-%20" + machine + "'%20and%20SerialNumber='" + serial_number + "'" 94 | request = urllib2.Request(full_cw_url) 95 | request.add_header('Content-Type', 'application/json') 96 | request.add_header('Authorization', 'Basic ' + cw_api_key) 97 | 98 | response = urllib2.urlopen(request) 99 | response_json = json.load(response) 100 | cw_id = response_json[0]['id'] 101 | 102 | # ConnectWise ID 103 | print "ConnectWise ID = {}".format(cw_id) 104 | 105 | # Begins the deactivation (set to "Inactive", and "No SLA") 106 | update_cw_url = "https://api-" + cw_url + "/v4_6_release/apis/3.0/company/configurations/{}".format(cw_id) 107 | 108 | # Updating parameters 109 | post_params=[{ 110 | "op": "replace", 111 | "path": "name", 112 | "value": "{}".format(computer_name) 113 | }] 114 | 115 | params = json.dumps(post_params) 116 | 117 | request = urllib2.Request(update_cw_url) 118 | request.get_method = lambda: 'PATCH' 119 | request.add_header('Content-Type', 'application/json') 120 | request.add_header('Authorization', 'Basic ' + cw_api_key) 121 | resp = urllib2.urlopen(request, params) 122 | 123 | print resp 124 | -------------------------------------------------------------------------------- /cw_bulk_new_enrollment.py: -------------------------------------------------------------------------------- 1 | #! /usr/local/bin/python 2 | 3 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 4 | # 5 | # Copyright (c) 2017 Jamf. All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions are met: 9 | # * Redistributions of source code must retain the above copyright 10 | # notice, this list of conditions and the following disclaimer. 11 | # * Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # * Neither the name of the Jamf nor the names of its contributors may be 15 | # used to endorse or promote products derived from this software without 16 | # specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY 19 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY 22 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 30 | 31 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 32 | # 33 | # This script allows syncing of information from Jamf Pro to ConnectWise. 34 | # For instance, this script can run once a night for newly enrolled machines in Jamf and 35 | # port them to the ConnectWise database. This can be based on a group membership for newly 36 | # enrolled machines into Jamf Pro. 37 | # 38 | # REQUIREMENTS: 39 | # - Requests python module on server/host machine 40 | # - Jamf Pro with Smart Group of computers to port 41 | # - ConnectWise 42 | # 43 | # 44 | # Written by: Jonathan Yuresko | Professional Services Engineer | Jamf 45 | # 46 | # Created On: June 8, 2017 47 | # 48 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 49 | 50 | import json 51 | from time import sleep 52 | import requests 53 | import codecs 54 | 55 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 56 | # VARIABLES 57 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 58 | 59 | # Your JSS information, Fill it in 60 | # Full JSS url: https://jss.yourcompany.com/JSSResource 61 | jss_url = '' 62 | jss_username = '' 63 | jss_password = '