{"id":233,"date":"2018-09-26T21:15:23","date_gmt":"2018-09-26T21:15:23","guid":{"rendered":"http:\/\/michaelschultz.net\/tech\/?p=233"},"modified":"2019-10-17T16:51:25","modified_gmt":"2019-10-17T16:51:25","slug":"configmgr-client-boundary-membership-query","status":"publish","type":"post","link":"https:\/\/michaelschultz.net\/tech\/configmgr-client-boundary-membership-query\/","title":{"rendered":"ConfigMgr Client Boundary Membership Query"},"content":{"rendered":"<p>One thing I dislike about ConfigMgr is that there isn\u2019t a SQL view I can easily reference to determine what boundary or boundaries my clients are part of. IP subnet and AD site boundaries are easy to do, but what about those IP range based boundaries.<!--more--><\/p>\n<p>With the help of our Microsoft PFE, I now have a solution. He sent me a query that used two views\/tables I was not aware of and I was able to modify his query and use it to build out a custom table.<\/p>\n<p>In order to determine if a system falls within a boundary, you need to takes its IP address and see if it falls within the boundary\u2019s range. This is done using numerical value of the IP address and the numerical values of the start and stop IP address of the range. Luckily, this data can be found in the ConfigMgr database so you do not have to manually calculate these values. System_IP_Address_ARR stores the IP address numerical value and BoundaryEx stores the numerical value of the start and stop IP addresses of the IP range.<\/p>\n<p>Again, with the help of our Microsoft PFE, I was able to create a query the lists out all the ResourceIDs and their associated BoundaryIDs regardless of type of boundary. I have taken this query, changed it to dump into a table and then used a schedule job to refresh the data on a daily basis.<\/p>\n<p>SQL file can be grabbed from <a href=\"https:\/\/github.com\/NecroMonkey\/vault\/blob\/master\/SQL\/client_boundary_membership.sql\">https:\/\/github.com\/NecroMonkey\/vault\/blob\/master\/SQL\/client_boundary_membership.sql<\/a><\/p>\n<div class=\"codecolorer-container sql default\" style=\"overflow:auto;white-space:nowrap;width:500px;\"><div class=\"sql codecolorer\"><span class=\"kw1\">SELECT<\/span> <span class=\"kw1\">DISTINCT<\/span><br \/>\nsysr<span class=\"sy0\">.<\/span>ResourceID<span class=\"sy0\">,<\/span><br \/>\nipr<span class=\"sy0\">.<\/span>BoundaryID<br \/>\n<span class=\"kw1\">FROM<\/span> v_R_System sysr<br \/>\n<span class=\"kw1\">JOIN<\/span> System_IP_Address_ARR ip <span class=\"kw1\">ON<\/span> ip<span class=\"sy0\">.<\/span>ItemKey <span class=\"sy0\">=<\/span> sysr<span class=\"sy0\">.<\/span>ResourceID <span class=\"kw1\">AND<\/span> ip<span class=\"sy0\">.<\/span>NumericIPAddressValue &amp;lt;&amp;gt; <span class=\"nu0\">0<\/span><br \/>\n<span class=\"kw1\">JOIN<\/span> v_RA_System_IPSubnets sub <span class=\"kw1\">ON<\/span> sub<span class=\"sy0\">.<\/span>ResourceID <span class=\"sy0\">=<\/span> sysr<span class=\"sy0\">.<\/span>ResourceID<br \/>\n<span class=\"kw1\">LEFT<\/span> <span class=\"kw1\">JOIN<\/span> v_RA_System_IPv6Prefixes v6 <span class=\"kw1\">ON<\/span> v6<span class=\"sy0\">.<\/span>ResourceID <span class=\"sy0\">=<\/span> sysr<span class=\"sy0\">.<\/span>ResourceID<br \/>\n<span class=\"kw1\">JOIN<\/span> BoundaryEx <span class=\"kw1\">AS<\/span> ipr <span class=\"kw1\">ON<\/span><br \/>\n<span class=\"co1\">-- Check BoundaryType 3 (IPRANGE)<\/span><br \/>\n<span class=\"br0\">&#40;<\/span>ipr<span class=\"sy0\">.<\/span>BoundaryType <span class=\"sy0\">=<\/span> <span class=\"nu0\">3<\/span> <span class=\"kw1\">AND<\/span> ip<span class=\"sy0\">.<\/span>NumericIPAddressValue <span class=\"kw1\">BETWEEN<\/span> ipr<span class=\"sy0\">.<\/span>NumericValueLow <span class=\"kw1\">AND<\/span> ipr<span class=\"sy0\">.<\/span>NumericValueHigh<span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"co1\">-- Check BoundaryType 1 (ADSITE)<\/span><br \/>\n<span class=\"kw1\">OR<\/span> <span class=\"br0\">&#40;<\/span>ipr<span class=\"sy0\">.<\/span>BoundaryType <span class=\"sy0\">=<\/span> <span class=\"nu0\">1<\/span> <span class=\"kw1\">AND<\/span> ipr<span class=\"sy0\">.<\/span>Value <span class=\"sy0\">=<\/span> sysr<span class=\"sy0\">.<\/span>AD_Site_Name0<span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"co1\">-- Check BoundaryType 0 (IPSUBNET)<\/span><br \/>\n<span class=\"kw1\">OR<\/span> <span class=\"br0\">&#40;<\/span>ipr<span class=\"sy0\">.<\/span>BoundaryType <span class=\"sy0\">=<\/span> <span class=\"nu0\">0<\/span> <span class=\"kw1\">AND<\/span> ipr<span class=\"sy0\">.<\/span>Value <span class=\"sy0\">=<\/span> sub<span class=\"sy0\">.<\/span>IP_Subnets0<span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"co1\">-- Check BoundaryType 2 (IPv6)<\/span><br \/>\n<span class=\"kw1\">OR<\/span> <span class=\"br0\">&#40;<\/span>ipr<span class=\"sy0\">.<\/span>BoundaryType <span class=\"sy0\">=<\/span> <span class=\"nu0\">2<\/span> <span class=\"kw1\">AND<\/span> ipr<span class=\"sy0\">.<\/span>Value <span class=\"sy0\">=<\/span> v6<span class=\"sy0\">.<\/span>IPv6_Prefixes0<span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"kw1\">ORDER<\/span> <span class=\"kw1\">BY<\/span> sysr<span class=\"sy0\">.<\/span>ResourceID<\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>One thing I dislike about ConfigMgr is that there isn\u2019t a SQL view I can easily reference to determine what boundary or boundaries my clients are part of. IP subnet and AD site boundaries are easy to do, but what about those IP range based boundaries.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"nf_dc_page":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[4,26,17],"tags":[],"class_list":["post-233","post","type-post","status-publish","format-standard","hentry","category-configmgr","category-queries","category-sql"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p98a2r-3L","post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/michaelschultz.net\/tech\/wp-json\/wp\/v2\/posts\/233","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/michaelschultz.net\/tech\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/michaelschultz.net\/tech\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/michaelschultz.net\/tech\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/michaelschultz.net\/tech\/wp-json\/wp\/v2\/comments?post=233"}],"version-history":[{"count":2,"href":"https:\/\/michaelschultz.net\/tech\/wp-json\/wp\/v2\/posts\/233\/revisions"}],"predecessor-version":[{"id":373,"href":"https:\/\/michaelschultz.net\/tech\/wp-json\/wp\/v2\/posts\/233\/revisions\/373"}],"wp:attachment":[{"href":"https:\/\/michaelschultz.net\/tech\/wp-json\/wp\/v2\/media?parent=233"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michaelschultz.net\/tech\/wp-json\/wp\/v2\/categories?post=233"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michaelschultz.net\/tech\/wp-json\/wp\/v2\/tags?post=233"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}