locked
How to create a Global Condition based on computers/users Active Directory Group? RRS feed

  • Question

  • Been asking this for a while now everywhere... Can't find the answer. So the problem is, how can I make a SCCM 2012 Global Condition which can be used to determine Active Directory group the User/Computer belongs to?

    I was planning to use this kind of Requirement as Application deployment base, so that certain software would only be deployed to the computers which are in the software group (in the Active Directory)...

    Anyone?

    Sunday, April 22, 2012 7:51 PM

Answers

  • You can do it this way as well using powershell and no need for whoami. Simply set it up as global condition using powershell expecting a boolean return.  Make sure you set it to run as the currently logged on user and like mentioned before dont use this on required software to avoid all the client evaluations although this is happening locally without ldap queries.

    $Group = "domain\groupname"
    $Found = $False
    trap [Exception] {
        continue;
    }
    $Found = ([Security.Principal.WindowsIdentity]::GetCurrent()).Groups | % {
       If ($_.Translate([Security.Principal.NTAccount]) -ieq $Group) {$true;break;} }
    $Found



    Thursday, April 25, 2013 2:33 PM
  • This is absolutely possible and I have created a blog on it.  It is also created for computers but can easily be adapted for users.  Check it out at http://fritschetom.blogspot.com/2012/10/deploy-applications-from-application.html.  I use this for everything I put into the app catalog that is licensed based or restricted.  This allows you to publish everything to the app catalog and not worry about the half baked approval required implementation that was implemented in 2012.



    • Proposed as answer by fritschetom Thursday, March 21, 2013 3:08 PM
    • Edited by fritschetom Thursday, March 21, 2013 3:32 PM
    • Marked as answer by Narcoticoo Saturday, April 11, 2015 5:16 AM
    Thursday, March 21, 2013 3:08 PM

  • #Get Security groups of User

    [Security.Principal.WindowsIdentity]::GetCurrent().Groups | % { $_.Translate([Security.Principal.NTAccount])}

    #Get groups of local computer

    ([adsisearcher]"(&(objectCategory=computer)(cn=$env:COMPUTERNAME))").FindOne().Properties.memberof -replace '^CN=([^,]+).+$','$1' 

    • Marked as answer by Narcoticoo Saturday, April 11, 2015 5:16 AM
    Thursday, April 9, 2015 11:09 PM

All replies

  • You can't...

    Global conditions are not a targeting mechanism. A Global condition is a requirement rule that is evaluated in real time by the
    client. Like memory, free disk space, operating system, primary user etc.

    In this case you should probably create a collection with members of the AD Group (query based), and use that for target instead.



    Ronni Pedersen | Configuration Manager MVP | Blog: http://www.ronnipedersen.com/ | Twitter @ronnipedersen





    Sunday, April 22, 2012 8:10 PM
  • If it can query AD Site and OU (Built-in global conditions), why it wouldn't do a query for group membership?!

    I know I could create collections but I don't want to do 100 collections for this...

    And yes, I know it's a requirement rule thats how I would use it, if computer / user is a member of a specific group the software would be installed, simply as that.

    Monday, April 23, 2012 7:33 AM
  • It's not so much that it can't, it's that it's not a good idea. As Ronni mentioned, you shouldn't use Global Conditions as targeting rules -- that's what collections are for. Non-local data on client systems is best not queried using a global condition; it simply isn't the intent of global conditions and can cause performance degradation on client systems.

    Jason | http://blog.configmgrftw.com | Twitter @JasonSandys

    Monday, April 23, 2012 1:47 PM
  • If it's possible how to do it?

    I wasn't asking was it a good idea or not.

    Monday, April 23, 2012 4:11 PM
  • That'll take some research (on your part) but I'm pretty sure that you can query WMI (or the registry) to do it or at least use a script to do so. If you run gpresult on a system this info is readily available.

    Part of asking questions on forums though is receieving advice and information that directly relates to your question even if you did not solicit it. Our role in answering questions is to guide you to the best possible answer and path to accomplish your tasks.

    Just because you can do something -- like drive the wrong way on a freeway -- doesn't mean you should do it and we would be remiss in not pointing this out.


    Jason | http://blog.configmgrftw.com | Twitter @JasonSandys

    Monday, April 23, 2012 6:11 PM
  • Thanks, I know it'll take some research on my part, thats why I'm asking it here :D

    I thought that at least someone had experience with the Active Directory Query seen in the Global Conditions wizard, maybe I was wrong. I don't think you can query Active Directory Groups from the WMI or local registry. And yes, I could do a script, parse the gpresult output etc.. But what's the point if ConfigMgr2012 already has a wizard for this kind of query? My main question is, what to inject in that wizards boxes to get this thing work...


    Tuesday, April 24, 2012 4:15 AM
  • That's the point of Ronni's reply above -- it's not a directly accomplishable task because its not part of the design goals to do this and hence the discussion of why its not a good idea. The built-in wizard has no way to insert variable information based upon the identity of the currently logged in user on the system where the condition is evaluated -- queries must be statically defined at runtime. I've seen some folks try to get creative with the queries to try to accomplish this but none have succeeded.

    My point about gpresult is not to directly use it, but as an example that it is possible to query the info without connecting to the domain (based strictly on memory, gpresult returns group membership info even if disconnected from the network for the current user). I don't know exactly where it gets the info from, but it makes sense that it would be cached somewhere locally that is also accessible.

    I'm really not trying to be obtuse about this -- I'm simply trying to discourage you from this path. Direct information from the product group is the source of my information including the fact that this is not a good idea, not within the design, and that collections are the prefered targeting mechanism.


    Jason | http://blog.configmgrftw.com | Twitter @JasonSandys


    Tuesday, April 24, 2012 5:35 AM
  • Ive been listening to the MMS webcasts and I cannot remember which one it was, but the statement was made that we do not need anywhere near the number of collections in 2012 as it is more efficiently handled using requirement rules. They mentioned things like collection evaluation and incremental updates etc etc.

    Cheers

    David Z

    Tuesday, May 8, 2012 4:06 AM
  • Ive been listening to the MMS webcasts and I cannot remember which one it was, but the statement was made that we do not need anywhere near the number of collections in 2012 as it is more efficiently handled using requirement rules. They mentioned things like collection evaluation and incremental updates etc etc.

    Cheers

    David Z


    I was also thinking the same thing... that's why I'm asking this.. So anyone? How to create this??
    Tuesday, May 8, 2012 5:28 PM
  • Are you targeting users or computers?

    The answer is different for each.


    Jason | http://blog.configmgrftw.com | Twitter @JasonSandys

    Tuesday, May 8, 2012 5:38 PM
  • Ive been listening to the MMS webcasts and I cannot remember which one it was, but the statement was made that we do not need anywhere near the number of collections in 2012 as it is more efficiently handled using requirement rules. They mentioned things like collection evaluation and incremental updates etc etc.

    Cheers

    David Z


    I was also thinking the same thing... that's why I'm asking this.. So anyone? How to create this??
    I am testing a script at present. Will let you know the result. Its taking time as there is no documentation on what type of values and how they are returned from a powershell script using a global condition.
    Tuesday, May 8, 2012 9:42 PM
  • I am testing a script at present. Will let you know the result. Its taking time as there is no documentation on what type of values and how they are returned from a powershell script using a global condition.
    Any progress on this one David?
    Sunday, May 13, 2012 9:20 AM
  • I havent had time to test this. Problem is lack of documentation. Maybe someone else can help?

    What I need to work out is how to get a test the output of a powershell script in a requirement rule.

    I have a test powershell script that has one line - Write-Host "yes".

    I add this as a requirement rule and test for the string "yes" and it says the requirement rule has not been met????? The only doco refers to vbscript. Maybe write-host is not the command to send output to the requirement rule???

    btw My script only works when the package is user targeted and the user is logged on - also, it wont work for XP.

    Cheers

    David Z

    Sunday, May 13, 2012 10:07 PM
  • Got it to work - just a simple matter of using write-output instead of write-host.

    This script will check if a user is a member of a group. It only works when the user is logged on and they must have the WHOAMI command (i.e. wont be on XP).

    The beauty is that it does not bother the network or access AD. It simply inspects the local Token.

    $groupmatch = "domainname\groupname"
    $Raw = whoami /groups /fo csv /nh
    $isgroup = $Raw |  %{$_.Split(",")[0] } | %{ $_ -replace "`"",""}| ?{$_ -eq $groupmatch}
    if ($isgroup.length -gt 0) {
      Write-Output "yes"
      }
    else
      { Write-Output "no"}

    Create the above as a global condition with a data-type of string.

    Then in the app requirement rule add this and check for a value equal to yes.

    Wednesday, May 16, 2012 2:40 AM
  • Nice work David, I knew it could be done. I'm going to pass this on to the product team for comment.

    Jason | http://blog.configmgrftw.com | Twitter @JasonSandys

    Wednesday, May 16, 2012 7:10 PM
  • So basicly you would have to do a separate global condition for every group if you want to use this... ?

    Isn't it possible to use Global Condition data-type string check value to be pointed as DOMAIN\Group? Then the script would be universal.. Also any thoughts how to do this for computers instead of users?

    Wednesday, May 16, 2012 8:13 PM
  • This would require a separate global condition for each group.I just whipped this script up to see how powershell requirement rules work.

    What I would do next is extract every group from the token string, concatenate them and "write-output" that whole string. Then in the requirement rule you could simple use the operator "contains" to specify the group you were after. This means you would only need one global condition. Ill get to that if I have time or anyone else can :-)

    As to computer accounts - I dont know of how to get a hold of the local token. I also need to work out how to get this to work without anyone logging on.

    The answer I suspect to both the above is to write a script which does check AD - a bit of network overhead involved but could be very useful - its on my to do list...

    Cheers

    David Z

    Wednesday, May 16, 2012 9:26 PM
  • Here is a script that produces a big string with all the group names.

    So you can write a requirement rule that uses the keyword 'contains' and specify the group name. Havent had time to test it yet though...

    $Raw = whoami /groups /fo csv /nh
    $glist = $Raw |  %{$_.Split(",")[0] } | %{ $_ -replace "`"",""}
    $sg = $glist -join ' '
    write-output $sg

    Thursday, May 17, 2012 9:44 PM
  • I would have thought that using scripts as requirement rules introduced a powerful feature which we would all love.

    Why then did the designers of this feature impose a stupid limit of 79 characters?

    Thats right - If your script outputs a string longer than 79 characters, it is truncated.

    So my script above will not work and you have to go back to the one global condition per group.

    I would hope the developers when issuing the next fix or service pack for 2012 will make sure that a script can generate an unlimited number of characters for us to use the "contains" operator.

    sooooo short sited....

    Cheers

    David Z

    p.s. there are a heap of problems regarding trouleshooting scripts for requirement rules that I have listed them in the other 2012 beta forum.


    • Edited by David Zemdegs Friday, May 18, 2012 1:50 AM extra info
    Friday, May 18, 2012 1:29 AM
  • Hi David,

    As many of us pointed out already, there are some severe challenges with this approach.

    The most important one is scale.

    I'll start off by answering the original answerer's first remark. If I can do it for an OU, than why can't I for a group.

    The short answer here is that the ConfigMgr client cheats when querying for the OU, as the client actually caches its OU membership locally in WMI.

    As OU membership doesn't change that often, this approach works fine for OU's.

    This tiny little cheat brings us back to the advice I gave during the MMS session I co-hosted with Jason in regards to global conditions. You only use global conditions to test on locally available data. Ldap queries even though available to build global conditions from are a very bad fit.

    Before you throw me another question, if they are such a bad fit, than why are they in there?

    Well, there a left-over imho from the given that Global Conditions are DCM in disguise, and ldap queries imho only exist to be targetted at domain controllers.

    Just as the SQL query global condition type is only designed to run against SQL servers as targets.

    David's script neatly solves that part of the equation by querying for local data using WMI.

    David script does leave 2 things unhandled though. Depending on the number of apps you risk having severe client impact by targetting all your applications this way.

    The amount of policy stored and required to re-evaluate at global condition re-evaluation time would be painful. Secondly your compliance statistics from the Admin UI would be completely skewed as these are based on the number of objects in your collection without taking into account who got "filtered" by the global conditions.


    "Everyone is an expert at something" Kim Oppalfens Configmgr expert for lack of any other expertise. http://www.scug.be/blogs/sccm

    Monday, May 21, 2012 7:40 PM
  • Thanks Kim,

    There are two separate issues here.

    One is scale and I agree that there is a potential issue if the client has to run a thousand powershell scripts during every user policy evaluation. I am yet to test this one. The alternative is a very messy thousand AD group based collections which also have a cost due to delta discovery.

    Perhaps you might suggest the cheapest cost solution? The requirement is that every app is targeted based on AD group membership. There are potentially  a thousand or more apps. It seems any solution is either costly performance wise or just plain messy. (btw, and dont laugh, all apps are currently delivered via GPO using AD group filtering - we will be migrating these to CM12).

    The second issue is just a no brainer IMHO. Why on earth limit the size of an output string when scripting requirement rules. Imagine all the poor administrators out there who are unaware of this 79 character limit who are wondering why their requirement rule doesnt work. There should be no limit.

    Cheers

    David Z

    Tuesday, May 22, 2012 10:04 PM
  • Actually, delta discovery for collections is pretty cheap as its based on USNs which are ADs built in way to track changes and notify consumers of those changes.

    It's a tight-rope for sure and similar to a few other things in the past, teases us with "advanced" functionality and then falls short mainly because they simply didn't have enough time to finish everything they wanted to add.


    Jason | http://blog.configmgrftw.com | Twitter @JasonSandys

    Tuesday, May 22, 2012 10:50 PM
  • So if we go down the loads of group based collections route then we run into the following problem:

    http://technet.microsoft.com/en-us/library/gg699372.aspx

    Why on earth does this limitation exist when delta discovery is supposed to be relatively painless?

    Cheers

    David Z

    Wednesday, May 30, 2012 1:35 AM
  • So this is still an open question... if somebody had an example how to parse the groups out of gpresult, i'd be more than happy...

    Tuesday, July 3, 2012 7:51 AM
  • Kind of off topic but I thought I would share a few of the Global Conditions I have created which I find very beneficial:

    I limit Dell specific apps like OMCI to just Dells using Manufacturer and model

    I limit model specific driver apps to the model

    Thursday, July 19, 2012 2:17 PM
  • I know this is old but it appears to still be something that is needed.  I too am looking for a way to create a requirement that is computer ad group based as I do not want to have to maintain 20 different office apps, is this not why there are deployment types inside applications?  You create a single point of entry for your users, lets call it office 2010 std then depending on what ad group or os language is required it will evaluate your deployment types and install as required.  The fact that this is not in CM12 SP1 saddens me.  I was sooo looking forward to utilizing this.
    Tuesday, February 12, 2013 2:13 PM
  • No, using deployment types is not for targeting simplification or for targeting at all, neither are global conditions. Targeting is still the job of collections.

    What's the difference between creating 20 Applications and 20 deployment types for a single application?

    To achieve what you've listed, you would create a collection for each OU and then target the App at the OU.


    Jason | http://blog.configmgrftw.com

    Tuesday, February 12, 2013 10:17 PM
  • well ok then just for fun what would an ldap global condition look like to target an AD group?
    Wednesday, February 13, 2013 2:34 PM
  • I'd like to hear that also rtruss, so if anyone knows how to do that, please share...

    Thursday, February 14, 2013 12:50 PM
  • When I run the vbscript above I am getting an error (16,17 Microsoft Vbscript runtime error:  mismatch any ideas?
    Monday, March 11, 2013 4:28 PM
  • This is absolutely possible and I have created a blog on it.  It is also created for computers but can easily be adapted for users.  Check it out at http://fritschetom.blogspot.com/2012/10/deploy-applications-from-application.html.  I use this for everything I put into the app catalog that is licensed based or restricted.  This allows you to publish everything to the app catalog and not worry about the half baked approval required implementation that was implemented in 2012.



    • Proposed as answer by fritschetom Thursday, March 21, 2013 3:08 PM
    • Edited by fritschetom Thursday, March 21, 2013 3:32 PM
    • Marked as answer by Narcoticoo Saturday, April 11, 2015 5:16 AM
    Thursday, March 21, 2013 3:08 PM
  • Not saying you should or shouldn't do this, but generally just because you can do something doesn't mean you should. The product wasn't designed for this and there are potentially serious performance implications.

    I'm glad you posted this though and the fact that it seems to be working well for you. I'm going to forward this to the product group to see if they have any comments.


    Jason | http://blog.configmgrftw.com

    Thursday, March 21, 2013 3:56 PM
  • From my findings it has little to no performance impact.  The script runs local on the PC and returns a list of all groups it is a part of either explicit or implicit via nested groups.  If it has the group contained in the output that is hidden it either accepts the installed package or it will prompt with a message with the softwareapproval notice if it doesn't contain the group.  I have not seen any performance degradation at all on the SCCM site and the only impact would be an ad call which I don't see how that would be an issue with all the calls going to ad anyway.  I love the 2012 product especially the application catalog but the approval process just was not up to where it should be in my opinion so I ended up coming up with this.  I have yet to see someone else have a way of doing this that works and if someone has a better way I would love to hear it as I too am unsure if this is the best way but as of now is the only way I know :).  Hope it helps someone and if it gives Microsoft an idea on how to fix the application approvals then I am glad it helps.  BTW...sorry for the ramble
    Thursday, March 21, 2013 10:53 PM
  • Very interesting read, but as I expressed my concerns earlier, I still have them. However, I don't have a better solution that addresses your needs.

    That being said, I am interested in

    a) How many applications do you have that have a requirement set like this? As it is only software requiring approval I am going to assume its not in the 1.000+ range

    b) What is your deployment re-evaluation schedule?

    c) How many clients are there in your environment?

    You mention that this is just an ldap query but your script executes multiple ldap queries, so just wondering.

    Other than that there's othter challenges i can see

    1) Your compliance rate is going to be off, as that is based on all machines that receive the policy

    2) My second performance worry would be around the amount of policies the client would need to store.

    Wednesday, April 3, 2013 9:38 PM
  • Ill try to answer these in order

    a.  you are correct it is only set for apps that need approval for either licensing or other reason and no it is not in the 1000+

    b.  Our client re-evaluation schedule is currently set to the default of 7 days

    c. We have 3000 clients

    the ldap script looks to see what machine is running so it can pass the correct machine name to the rest of the script which looks for its group memberships.  it is very light weight and doesn't require any editing as you specify the rules when you set the global condition on each application.  This also runs local to the machine.

    1. Not sure why you think the compliance rate will be off.  We deploy all of our apps as available to the all application users collection and if they are needed as a push then  by machine we deploy using some collection rules based on whether it is installed or not and if it is a member of the group.

    2.  I guess I don't understand why there would need to be many policies that the machine stores.


    I think what might be getting lost is I am not saying use this in conjunction with the approval is required checkbox but instead of.  The only problem I have found with this is the apps in the application catalog still says approval no instead of yes.  but I have my details specifying there is additional approval required and also the script that runs as the software approval notice if the globlal condition is false.
    • Edited by fritschetom Thursday, April 4, 2013 8:10 PM
    Thursday, April 4, 2013 7:52 PM
  • That's more or less what I anticipated.

    Your situation is nicely handled by your solution, however it is no blueprint to start using groups as global conditions.

    I am fully convinced that it works out for you, and there's a couple of reasons for that.

    The most obvious ones are that you do this for a limited set of applications, you don't have a very aggressive reevaluation schedule and although you have a decent amount of clients 3.000 isn't outrageous neither.

    Additionally, on the not so obvious side, you target users in an available setting.

    That means policies are only stored and evaluated when someone actually goes to the portal and clicks to install. That's another reason why this works out for you. Anyone trying this with required deployments or available deployments targetted at computers would download and evaluate the policies. Depending on the number of apps that could be problematic.

    So, long story short, keep doing what your doing as it is a nice solution. For anyone trying to do this as a general targetting solution the warning still stands, make sure you do your homework before doing this on a large scale.

    Thursday, April 4, 2013 10:18 PM
  • You can do it this way as well using powershell and no need for whoami. Simply set it up as global condition using powershell expecting a boolean return.  Make sure you set it to run as the currently logged on user and like mentioned before dont use this on required software to avoid all the client evaluations although this is happening locally without ldap queries.

    $Group = "domain\groupname"
    $Found = $False
    trap [Exception] {
        continue;
    }
    $Found = ([Security.Principal.WindowsIdentity]::GetCurrent()).Groups | % {
       If ($_.Translate([Security.Principal.NTAccount]) -ieq $Group) {$true;break;} }
    $Found



    Thursday, April 25, 2013 2:33 PM
  • Hey David,

    Where did you get the information regarding a 79 character limit in requirement script output?

    Thanks

    Thursday, January 22, 2015 4:11 PM

  • #Get Security groups of User

    [Security.Principal.WindowsIdentity]::GetCurrent().Groups | % { $_.Translate([Security.Principal.NTAccount])}

    #Get groups of local computer

    ([adsisearcher]"(&(objectCategory=computer)(cn=$env:COMPUTERNAME))").FindOne().Properties.memberof -replace '^CN=([^,]+).+$','$1' 

    • Marked as answer by Narcoticoo Saturday, April 11, 2015 5:16 AM
    Thursday, April 9, 2015 11:09 PM
  • That's just great snippet of code there! Thanks a lot snowstorm_ for contributing!

    Saturday, April 11, 2015 5:15 AM
  • Tried using this and didnt work for me .Followed the below.Any help is much appreciated in this 

    1. Created the Global Condition based on the script above

    $Group = "mydomain\mysg"
    $Found = $False
    trap [Exception] {
        continue;
    }
    $Found = ([Security.Principal.WindowsIdentity]::GetCurrent()).Groups | % {
       If ($_.Translate([Security.Principal.NTAccount]) -ieq $Group) {$true;break;} }
    $Found

    2. Enabled the check box " Run scripts using the logged on user credentials"

    3. Targetted to the Application deployment types and got the error below

    +++ Did not detect app deployment type Commercial Apps v3 - OPS(ScopeId_7578DC98-0401-479D-ACB9-C94905EA3931/DeploymentType_80b48593-adfe-4cc9-9487-2fbc8a6f8229, revision 15) for S-1-5-21-1275210071-1897051121-1417001333-100680.

     


    • Edited by sonrobin Tuesday, July 7, 2015 11:53 AM modified
    Tuesday, July 7, 2015 11:52 AM
  • Hi Narcoticoo,

    I am not able to make this work .Can you help me out on this please?

    1. Created the Global Condition based on the below script

    [Security.Principal.WindowsIdentity]::GetCurrent().Groups | % {$_.Translate([Security.Principal.NTAccount])}

    2. Running this as "Run Scripts by using logged on user credentials"

    Device Type - Windows

    Condition Type - String

    Setting Type - Script

    Data type - String

    3.Created the Deployment Type Requirement with Custom condition ,

    Rule Type -Value

    Operator - Contains

    Value - Mydomain\MySG

    Am I missing something here?


    • Edited by sonrobin Tuesday, July 7, 2015 12:05 PM added more details
    Tuesday, July 7, 2015 11:54 AM
  • Your earlier post indicated that the application wasn't detected, so check your DETECTION method of the application.

    I haven't personally used this method as a requirement, but I can confirm that those codesnippest snowstorm_ posted earlier are indeed working as expected.

    Tuesday, July 7, 2015 12:54 PM
  • Thanks for your response

    Actually I am trying this for the Virtual application deployment.

    Where this code was used if it is not used in Requirement section?I am trying to use in the requirements section to deploy the different shortcuts to different user groups

    Tuesday, July 7, 2015 6:58 PM
  • You need to create a global condition where you use the script and use that global condition as your requirement on the deployment type of the application.


    Check this example: http://www.kraftkennedy.com/creating-global-conditions-in-configuration-manager-2012/
    • Edited by Narcoticoo Wednesday, July 8, 2015 4:40 AM
    Wednesday, July 8, 2015 4:39 AM