I found my more detailed notes on the package flags. A couple of corrections:
The flag “524288” specifically tells whether an app is published or assigned – it’s set for assigned, unset for published.
8 is typically set for published apps and cleared for assigned.
I promised code.
private void SearchAD(string target, string policy, string policyname)
{
DirectoryEntry entry = null;
try
{
entry = new DirectoryEntry(policy);
}
catch (COMException Ex)
{
toolStripStatusLabel1.Text = "Couldn't connect to the specified Active Directory Path - Error = " + Ex.Message + Ex.InnerException;
return;
}
DirectorySearcher mySearcher = new DirectorySearcher(entry);
TimeSpan waitTime;
try
{
waitTime = new TimeSpan(0, 0, 60); //hh--mm-ss
mySearcher.ClientTimeout = waitTime; //wait this much time to display results
}
catch (Exception Ex)
{
toolStripStatusLabel1.Text = "Error = " + Ex.Message + Ex.InnerException;
return;
}
try
{
SearchResult result = mySearcher.FindOne();
//if exception was not thrown, means it connected successfuly
if (result != null)
{
// Get the 'DirectoryEntry' that corresponds to 'mySearchResult'.
DirectoryEntry myDirectoryEntry = result.GetDirectoryEntry();
// Get the properties of the 'mySearchResult'.
ResultPropertyCollection myResultPropColl;
myResultPropColl = result.Properties;
if (myDirectoryEntry.Properties["msiscriptname"].Value != null)
{
int flags = Int32.Parse(myDirectoryEntry.Properties["packageflags"].Value.ToString());
if ((myDirectoryEntry.Properties["msiscriptname"].Value.ToString() != "R") || (cbRemoved.Checked))
{
if ((rbDisplayName.Checked == true) && (myDirectoryEntry.Properties["displayname"].Value.ToString().ToUpper().Contains(target)))
{
textBox1.Text += "\nInitial Flags: " + flags + "\n";
if (checkBox1.Checked)
textBox1.Text += "Path: " + myDirectoryEntry.Path + "\n";
textBox1.Text += "App name: " + myDirectoryEntry.Properties["displayname"].Value + "\n";
textBox1.Text += "\tFound in policy " + policyname + "\n";
if (myDirectoryEntry.Properties["gPCFileSysPath"].Value != null)
{
textBox1.Text += "\tPolicy Path: " + myDirectoryEntry.Properties["gPCFileSysPath"].Value + "\n";
}
if (myDirectoryEntry.Properties["msifilelist"].Value != null)
{
textBox1.Text += "\tMSI Path: " + myDirectoryEntry.Properties["msifilelist"].Value + "\n";
}
if (myDirectoryEntry.Properties["whenchanged"].Value != null)
{
textBox1.Text += "\tWhen changed: " + myDirectoryEntry.Properties["whenchanged"].Value + "\n";
}
if (myDirectoryEntry.Properties["msiscriptname"].Value.ToString() == "A")
textBox1.Text += "Currently assigned.\n";
else if (myDirectoryEntry.Properties["msiscriptname"].Value.ToString() == "P")
textBox1.Text += "Currently published.\n";
else if (myDirectoryEntry.Properties["msiscriptname"].Value.ToString() == "R")
{
if ((flags & 128) != 0)
textBox1.Text += "Removed from policy with allow users\n";
else
textBox1.Text += "Removed from policy with Immediately Remove!\n";
}
textBox1.Text += "Flags:";
(snipped a bunch of checking flags)
textBox1.Text += "\n\n";
}
}
}
foreach (DirectoryEntry child in myDirectoryEntry.Children)
{
SearchAD(target, child.Path, policyname);
}
}
}
catch
{
return;
}
}
It’s relatively self-explanatory; target is a string that contains part of the app’s displayname; policyname is just a friendly description of the policy name – such as “My-App-Deployment-Policy” or whatever. Policy is the LDAP string for the policy – something like "LDAP://CN=Packages,CN=Class Store,CN=Machine,CN={BDA90329-B1C6-4E09-A60B-2BA6B19C54D6},CN=Policies,CN=System,DC=MY,DC=COMPANY,DC=com" or similar.
Oh, and a teaser for the next post: Yes, you can un-remove and un-redeploy apps in AD.
(oh, and pasting everything into Word before copying/pasting here seems to make it all pretty)
Print | posted on Sunday, February 25, 2007 3:28 AM