Removing software that was originally deployed via Group Policy


Problem: Software that was installed via Group Policy needs to be removed or upgraded and the original policy responsible for deploying said software no longer exists. Furthermore, attempting to remove the software manually via Programs and Features while logged into an account with Administrative privileges results in error messages similar (or identical) to this one:

Even with an "admin" account, the software cannot be removed manually.

Even with an “admin” account, the software cannot be removed manually.

Solution: We need to create a brand new GPO for software removal. Before we do, here’s a quick outline of what needs to be done:

  1. Locate the original MSI package and copy it to an accessible network location.
  2. Create a new unlinked GPO
  3. Use the new GPO to re-deploy the package (or packages — it is possible to remove multiple packages with the same policy.) Make sure that “Uninstall the applications when they fall out of the scope of management.” is checked on either the package, or the entire policy (or both.)
  4. Use security filtering to target the objects that need to have the software uninstalled. Make sure you read this post first, it might save you a bunch of time and frustration.
  5. Allow enough time to pass for Group Policy to refresh. Alternatively, force a refresh via reboots and/or gpupdate /force
  6. Remove the machines targeted in step #3 from Security Filtering.
  7. Repeat step #5

Let’s get to it then…

Step #1: Locate the original MSI package — read this post — and copy it to an accessible network location.

Step #2: Create a new unlinked GPO.

Create a new, unlinked GPO so that we don't accidentally apply it to the wrong OU, Users, Machines, etc.

Create a new, unlinked GPO so that we don’t accidentally apply it to the wrong OU, Users, Machines, etc.

Make sure to give the new GPO an obvious name.

Make sure to give the new GPO a descriptive name.

Step #3: Use the new GPO to re-deploy the package or packages — it is possible to remove multiple packages with the same policy. Make sure that “Uninstall the applications when they fall out of the scope of management.” is checked on either the package, policy, or both.

Configure the new policy to deploy the package

Configure the new policy to deploy the package.

Browse to the original MSI that was located in step #1

Browse to the original MSI that was located in step #1.

If you are only using this policy to remove one package, select "Advanced" in this dialog. Otherwise, select "Assigned".

If you are only using this policy to remove one package, select “Advanced” in this dialog. Otherwise, select “Assigned” and repeat this step for each package that needs to be removed, then skip the next screenshot.

If you selected "Advanced" in the previous dialog, check the box titled "Uninstall this application when it falls out of the scope of management"

If you selected “Advanced” in the previous dialog, check the box titled “Uninstall this application when it falls out of the scope of management”.

If you are using this policy to remove multiple packages, there is no need to specify "Uninstall this application when it falls out of scope of management" for each package, instead, you can apply it to the entire policy. Right click on "Software installation" and select "Properties"

If you are using this policy to remove multiple packages, there is no need to specify “Uninstall this application when it falls out of scope of management” for each package, instead, you can apply it to the entire policy. Right click on “Software installation” and select “Properties”. Check the box “Uninstall the applications when they fall out of the scope of management” in the next screenshot.

Check the box "Uninstall the applications when they fall out of the scope of management".

Check the box “Uninstall the applications when they fall out of the scope of management”, and hit “OK”.

Close the Group Policy Management Editor when you are done configuring your policy

Step #4: Use security filtering to target the objects that need to have the software uninstalled. Make sure you read this post first, it might save you a bunch of time and frustration.

In the next few steps, I’m going to use Security Filtering to target only the machine that needs this policy. In the examples that follow, the machine name is W7PRO64-STAGING. You could just as easily Security Filtering to filter on a Security Group containing users, computers, or both; or you could target a specific user in the same way that I’m going to target the machine in my example. Just remember that the standard rules about OUs still apply: Regardless of whether you use a Security Group or whether you target the object (user or computer) directly, the targeted object needs to exist within the same OU as the policy is linked. Also remember that if your policy is supposed to target User objects, then any settings need to be configured under User Configuration; if it targets Computer objects, then your settings need to be configured under Computer Configuration.

Click the "Add..." button to add the targeted objects (Users, Computers, or Groups)

Click the “Add…” button to add the targeted objects (Users, Computers, or Groups)

We do not wish to target all Authenticated Users in the OU that this policy will eventually be linked , so we need to remove the Authenticated Users group from Security Filtering.

We do not wish to target all Authenticated Users in the OU that this policy will eventually be linked , so we need to remove the Authenticated Users group from Security Filtering.

... But, due to the previously mentioned post, the Authenticated Users group does require Read access to this policy. So click on the "Delegation" tab, click "Add", type "Authenticated Users" into the box titled "Enter the object name to select", click "Check Names", then click "OK".

… But, due to the previously mentioned post, the Authenticated Users group does require Read access to this policy. So click on the “Delegation” tab, click “Add”, type “Authenticated Users” into the box titled “Enter the object name to select”, click “Check Names”, then click “OK”.

Make sure that "Read" is selected in the "Permissions" dropdown box, and then click "OK".

Make sure that “Read” is selected in the “Permissions” dropdown box, and then click “OK”.

You should end up with something like this

You should end up with something like this

If you want to be certain your permissions are correct, click "Advanced", then click "Advanced" on the dialog that appears, and make sure that your targeted Users, Computers, or Group, have "Read" and "Apply" permissions and "Authenticated Users" only have "Read" permissions.

If you want to be certain your permissions are correct, click “Advanced”, then click “Advanced” on the dialog that appears, and make sure that your targeted Users, Computers, or Group, have “Read” and “Apply” permissions and “Authenticated Users” only have “Read” permissions.

Now all that's left to do is link the GPO to the OU

Now all that’s left to do is link the GPO to the OU

Select the GPO to be linked, and click "OK".

Select the GPO to be linked, and click “OK”.

Step #5: Allow enough time to pass for Group Policy to refresh. Alternatively, force a refresh via reboots (at least two reboots) and/or gpupdate /force

One way to tell if the MSI deployed by your “removal policy” was actually re-deployed is by checking the the install date (… found in the “Installed On” column) in Programs and Features — it should be updated to the date that the software was re-deployed.

Some things can go wrong here:

  • Group Policy might not refresh for a long time, or not at all. Try enabling the following two items on the policy (if it is being applied to a Computer). These settings need to be applied to the Computer, so you may need to create a new policy and link it to the OU containing your targeted Computer objects.
    1. Navigate to Computer Configuration\Policies\Administrative Templates\System\Logon and set Always wait for the network at computer startup and logon to Enabled
    2. Navigate to Computer Configuration\Policies\Administrative Templates\System\Group Policy and set Configure software installation policy processing to Enabled and check both Allow processing across a slow network connection and Process even if the Group Policy objects have not changed
  • The MSI you thought was the “original” turns out not to be, and you end up with something like this in Programs and Features:
    The software contained in the MSI deployed by your "removal" policy may have been the same version, but the MSI was not identical to the original. In this case, you need to try to retrieve the original MSI (... for the software that you were trying to remove in the first place) from a machine that still has the software installed.

    The software contained in the MSI deployed by your “removal” policy may have been the same version, but the MSI was not identical to the original. In this case, you need to try to retrieve the original MSI (… for the software that you were trying to remove in the first place) from a machine that still has the software installed.

    This happened to me once when I tried to use this technique to remove Google Apps Sync. Instead of retrieving the original MSI (as per my instructions, linked above in step #1) I downloaded an MSI from Google that was the same version of the software I was trying to remove, taking a gamble that the downloaded MSI might be identical to the originally installed one. You see the result. If this happens to you, don’t panic. Just proceed to step #6 as if it never happened. Once the duplicate copy has been removed, you can repeat step #1 (or actually do step #1 in case you skipped it the first time, which may be the reason you’re in this mess), skip step #2 (because you already have a policy that can be re-used) and then complete the rest of the instructions, starting from step #3.

Step #6: Remove the objects targeted in step #3 from Security Filtering and/or unlink the policy.

Do either (or both) of the following:

Navigate to the OU in which the policy is linked, right click on the policy, and select "Delete". When prompted with the following: "Do you want to delete this link? This will not delete the GPO itself." Click "OK".

Navigate to the OU in which the policy is linked, right click on the policy, and select “Delete”. When prompted with the following: “Do you want to delete this link? This will not delete the GPO itself.” Click “OK”.

Remove the targeted group from Security Filtering. When asked "Do you want to remove this delegation privilege?" Click "OK".

Remove the targeted group from Security Filtering. When asked “Do you want to remove this delegation privilege?” Click “OK”.

This will force an “out of scope” status, and the software should be uninstalled after Group Policy refreshes.

Deploying Adobe Acrobat DC via Group Policy

This post assumes that you’ve already downloaded the Adobe Acrobat DC package from Adobe LWS and you’ve downloaded and installed the Acrobat Customization Wizard DC if not, go do those first.


  1. Once you’ve downloaded the package, double click it to extract its contents — do not run the installer after the package has been extracted.15-07-2015_000115-07-2015_0002
  2. Assuming you’ve extracted the package contents to C:\Users\Administrator\Desktop\Adobe Acrobat, you’ll have a directory within that directory, titled Adobe Acrobat, in addition to some other files that we won’t concern ourselves with for the purposes of this post:15-07-2015_0003
  3. Now start the Acrobat Customization Wizard DC:15-07-2015_0004
  4. Navigate to File -> Open Package and select the AcroPro.msi file.15-07-2015_0005
  5. Configure your deployment options. For example, enter the package’s serial number in the Serial Number field, under the Personalization Options category. Please refer to Adobe’s documentation for details on all of the available configuration options and their uses. One particularly frustrating issue I ran into had to do with the installer looking for Visual C++ x64 2013 Runtime (VC); if this package wasn’t installed, the installation would fail and the only thing logged in event viewer would be a group policy failure. The total lack of useful error messages made this issue a pain to overcome, but after reading every single option and description (more or less) on this page I eventually figured it out. I needed to set an attribute in the Property table via the Direct Editor function in the Customization Wizard.Add AttributeI had to add this attribute manually (just right-click anywhere in the attributes pane), as it does not exist in the Property table by default. The attribute name needed to be IGNOREVCRT64 and it’s value needed to be 1.IGNOREVCRT64You can probably guess at what this does but for the official explanation, refer to Adobe’s Documentation on Property attributes and values. The short explanation is that I needed this installation to succeed regardless of whether the target machine already had the Visual C++ x64 2013 Runtime package installed. As of this writing, here is the explanation, for posterity:

    Since Acrobat looks for Visual C++ x64 2013 Runtime (VC) by default, set IGNOREVCRT64 to 1 if it is not present AND not needed. IGNOREVCRT64 need only be used when all of the following are true:

    • During Acrobat installs on 64-bit machines
    • When Visual C++ x64 2010 SP1 Runtime is not installed
    • Installation is NOT done via setup.exe.
    • The following functionality is NOT needed:
      • Acrobat PDF Creation add-on (PDFMaker plugin) for Microsoft Office 64-bit applications (viz. Word, Excel, PowerPoint & Outlook) and
      • sending emails or resolving addresses via 64-bit Microsoft Outlook.

    Since Acrobat looks for Visual C++ x64 2013 Runtime (VC) by default, set to 1 if it is not present AND not needed. During non-setup.exe installs when VC is not present, installation behavior is as follows:

    • Command line installs abort if IGNOREVCRT64=1 is not passed.
    • UI installs display a dialog asking the user whether they would like to continue or cancel.
    • Setup.exe installs succeed. Installs never abort as the property is passed while spawning the MSI.

    For MSI installs, use Require64BitVC10RT in the Setup.ini file under the Startup section.

  6. Once you’ve configured all of your desired options, navigate to File -> Save Package. This will create a transform (.mst) file (… in addition to doing a few other things): 15-07-2015_0007
  7. To deploy this package, it will need to be accessible from the network. Create a network-accessible directory — something like:
    \\fileserver.domain.local\Deployed Files

    and copy the entire Adobe Acrobat directory — the one containing the transform file created in the previous step — to that directory.

  8. Open GPMC and create a GPO (or modify an existing GPO):
    15-07-2015_00102
  9. Right click on any blank space in the right panel and create a new package: 15-07-2015_0010
  10. Select Advanced deployment method:15-07-2015_0009
  11. Navigate to the network accessible location of the package and select it (note: it might take a while for any dialogs to appear after selecting the file … just be patient): 15-07-2015_0011
  12. Then add your transform (.mst) file in the Modifications tab of the package properties (the transform file will be in the same directory as the package file.) Then click OK: 15-07-2015_0012
  13. Bonus! Configure some administrative templates.
    1. First, download the templates from Adobe.
    2. Save them somewhere on your computer and unzip them.
    3. Open GPMC and edit the GPO you’d like to use with the templates.
    4. In the policy editor, navigate to Administrative Templates in either Computer or User configuration
    5. Right click on the Administrative Templates folder and select Add/Remove Templates Add/Remove Templates
    6. Navigate to the directory where you unzipped the templates and select the file named AcrobatDC.adm Select the .adm file AcrobatDC
    7. Then configure your options:Adobe "Computer Configuration" optionsAdobe "User Configuration" options

apcupsd pcnet and different subnets

Scenario:

  • Subnet A: 192.168.0.0/24
  • Subnet B: 10.10.10.0/24
  • No firewalls blocking communication between them

Problem: An apcupsd instance running on a machine residing on subnet “B” cannot communicate with the APC NMC that resides on subnet “A”

Solution (probably): Make sure to specify the port in your DEVICE declaration in /etc/apcupsd/apcupsd.conf:

DEVICE 192.168.0.5:username:password:3052

Snippet from the default apcupsd.conf:

# pcnet ipaddr:username:passphrase:port
# PowerChute Network Shutdown protocol which can be
# used as an alternative to SNMP with the AP9617
# family of smart slot cards. ipaddr is the IP
# address of the UPS management card. username and
# passphrase are the credentials for which the card
# has been configured. port is the port number on
# which to listen for messages from the UPS, normally
# 3052. If this parameter is empty or missing, the
# default of 3052 will be used.

The question is: Why does explicitly defining something that is supposed to be the default (even when left undefined), change the behavior of the program? I do not have an answer at present. Good luck though!

Event ID 4098 / 0x80070005 Access is denied when Copying files via Group Policy

Event ID 4098 logged in Event Viewer "Application" log.

Event ID 4098 logged in Event Viewer “Application” log.

This scenario is common enough — you’d like to copy a file to each user’s Desktop/My Documents/etc. without having to do it manually for each user. So you use Group Policy. You’ve done everything correctly (or so you think):

  • The file you’re trying to deploy has been shared and the GP preference item’s “Source file(s)” input box has been pointed to the file via the UNC path (not the local filesystem path) to the file.
  • If your GP Preference that copies the file resides in the “User Configuration” branch, you’ve ensured that the “Domain Users” group has read access to the directory that contains the file (NTFS permissions) and the Share.
  • If your GP Preference that copies the file resides in the “Computer Configuration” branch, you’ve ensured that the “Domain Computers” group has read access to the directory that contains the file (NTFS permissions) and the Share.
  • You’ve ensured that the policy has been linked to the correct OU (i.e., the OU that contains the “target” users or computers.)

But did you remember to specify the full path — including the filename in the “Destination File” input box?

You must include the destination filename, specifying the target directory by itself is not sufficient.

You must include the destination filename, specifying the target directory by itself is not sufficient.

Yeah… it happens to the best of us. But don’t beat yourself up over it. This is a problem that shouldn’t exist; it’s counter-intuitive and different from the way “copy” commands (which is basically what this is) normally work.

Problems configuring hylafax server on Ubuntu 12.04, 14.04

It feels wrong, writing an article about faxing in 2014 but here goes…

Getting HylaFAX to work on Ubuntu always seems to be a pain in the ass and today I’ve finally found out why. See the following bug reports:

https://bugs.launchpad.net/ubuntu/+source/uucp/+bug/255200

https://bugs.launchpad.net/ubuntu/+source/uucp/+bug/584787

All of my past attempts at getting HylaFAX to work with Ubuntu have always failed, causing me to have to switch to a different distro (usually CentOS) for HylaFAX servers. These two bug reports contain the answers.

The problem is twofold:

  1. First, permissions on /dev/ttyS* are incorrect by default (as far as HylaFAX is concerned, anyway — see the first bug report above.)
  2. Second, cu doesn’t seem to work correctly when trying to troubleshoot the problems caused by #1 (see the second bug report above.)

So here’s what you need to do in order to get a functioning HylaFAX installation [n1]:

  1. Install the necessary software:
    apt-get install cu hylafax-server
    
  2. Figure out which device node your modem is on:
    [email protected]:~# dmesg | grep ttyS
    [    0.684804] 0000:02:00.0: ttyS4 at I/O 0xda00 (irq = 21, base_baud = 115200) is a 16550A
    

You can see from the above that my modem is on /dev/ttyS4. Now before configuring HylaFAX you will need to know the class capabilities of your modem. To find that out, do the following [n2]:

  1. Create a new file: /etc/uucp/port that contains the following lines:
    #
    # Description for the TCP port - pretty trivial. DON'T DELETE.
    #
    port TCP
    type tcp
    
  2. Change the permissions on that file:
    chmod 644 /etc/uucp/port
    chown root.uucp /etc/uucp/port
    
  3. Make sure that the modem has the correct permissions on it’s device node [n3]:
    chmod 666 /dev/ttyS4
    
  4. Connect to your modem and query its capabilities [n4]:
    [email protected]:~# cu -l /dev/ttyS4
    Connected.
    at+fclass=?
    0,1,1.0,2,2.0,2.1
    OK
    ~[localhost].
    Disconnected.
    

    We see from the above output our modem supports all available classes, 0 – 2.1.

  5. Now all you need to do is run faxsetup and then faxaddmodem. I won’t cover that here (see links below) [r1] but a word of advice: when faxaddmodem asks for the “class” of your modem, make sure you have read, and you understand the characteristics of each available class before choosing [r3].

After you’ve run faxsetup and faxaddmodem [r1], you may want to configure HylaFAX to send all incoming faxes to an e-mail address as PDF attachments. You’ll need to install an MTA for this (I use postfix) and configure it as a satellite system so that your fax server will route mail through your mail server (did I mention that this assumes you already have access to a production mail server?) This is pretty trivial on Ubuntu; after running apt-get install postfix you are prompted for the type of configuration you want — satellite in this case, and once you’ve selected that option, you are prompted for the hostname/IP address of the mail server you plan on using to relay your faxes (i.e., the IP address of your production mail server.) You’ll need to ensure that that mail server is configured to relay mail coming from your fax server [r2]. Then, there are some HylaFAX specific things you’ll need to configure after you have a functioning MTA:

  1. Find out where your aliases are stored:
    [email protected]:~# postconf alias_database
    alias_database = hash:/etc/aliases
    
  2. Add the following line to that file:
    FaxDispatch:	[email protected]
    
  3. Update the aliases hash:
    [email protected]:~# newaliases
    
  4. Create a file; /var/spool/hylafax/etc/FaxDispatch, that contains the following lines:
    FILETYPE=pdf;
    TEMPLATE=en;
    SENDTO="[email protected]";
    
  5. Restart hylafax [n5]:
    [email protected]:~# /etc/init.d/hylafax restart
     * Stopping HylaFAX faxq                                                                                                [ OK ] 
     * Starting HylaFAX syncing directories...
    

Now go cable up your fax server and send some faxes to it!

Notes:

[1.]Installing cu is optional; you should only need it if you do not know the capabilities of your modem.

[2.] This also involves addressing the problems caused by the two bug reports mentioned at the beginning of this article.

[3.]If these permissions do not seem to work, try rebooting. If that does not work, try the following permissions:

chmod 600 /dev/ttyS4
chown uucp.dialout /dev/ttyS4

[4.] You may not see your typing echo back to the terminal; just continue typing -or- copy and paste the following in its entirety:

cu -l /dev/ttyS4
at+fclass=?
~~

Then at the [hostname] prompt, just hit the period “.” key and wait a second or two.

Make sure you are not in /var/spool/hylafax/etc when you restart HylaFAX! Part of the start/stop/restart process involves unmounting /etc/hylafax from /var/spool/hylafax/etc and then remounting it. You’ll know if you mess this up because you’ll see the following output, repeated until you hit CTRL+C:

umount: /var/spool/hylafax/etc: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /var/spool/hylafax/etc: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /var/spool/hylafax/etc: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /var/spool/hylafax/etc: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /var/spool/hylafax/etc: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /var/spool/hylafax/etc: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /var/spool/hylafax/etc: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /var/spool/hylafax/etc: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /var/spool/hylafax/etc: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /var/spool/hylafax/etc: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /var/spool/hylafax/etc: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /var/spool/hylafax/etc: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /var/spool/hylafax/etc: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /var/spool/hylafax/etc: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /var/spool/hylafax/etc: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /var/spool/hylafax/etc: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /var/spool/hylafax/etc: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /var/spool/hylafax/etc: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /var/spool/hylafax/etc: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /var/spool/hylafax/etc: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
umount: /var/spool/hylafax/etc: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))

Resources:

[1.] Using faxsetup and faxaddmodem:
http://www.hylafax.org/content/Handbook:Basic_Server_Configuration:Faxsetup
http://www.hylafax.org/content/Handbook:Basic_Server_Configuration:Faxaddmodem

[2.] Configure postfix to relay mail from other clients:
http://www.postfix.org/BASIC_CONFIGURATION_README.html#relay_from

[3.] Fax Classes:
http://en.wikipedia.org/wiki/Fax#Class