I’ve written before on how great Group Policy Preferences are, and thought I’d write a quick ‘how to’ on a likely common scenario – replacing an older file with a new one, but only if it already exists.
Pushing out a file via Group Policy Preferences is quite easy and has been around for a long time.
When creating a new file rule, you’ll see 4 options under ‘Action’ – Create, Replace, Update and Delete:
Create will only copy the file from the source to the destination if the file doesn’t exist at the destination
Replace will actually remove a file (if one exists), and copy the source to the destination regardless if a file existed or not
Update is the misleading one, it will modify the file attributes of the destination file to match the source – if the files themselves are different, it won’t copy them. If the file doesn’t exist, it will copy the file to the destination though!
Delete will delete the file(s) specified.
None of these provide a solution to ‘Replace file only if it exists’ though. There’s two obvious ways this can be achieved; you can use ‘Replace’ but this will continually replace the file every time Group Policy is run, which in the user context is every 90 minutes. You also can’t use the option ‘Apply once and do not reapply’ because it will run regardless of the file existing or not – which means if the file isn’t there before group policy runs, the file may be replaced by a software install or other mechanism, and with the order out of whack, resulting in the wrong file being left there in the end.
The next logical way to make sure the order is correct is to use Item Level Targeting. Under the ‘Common’ tab, you can tick the box for ‘Item Level Targeting’ and point to the file in question:
This will only run once though, and that is regardless of the ‘Item Level Targeting’ being true or false. That only controls whether the policy does what it’s configured to do, at the client side it’s still ‘run’ the policy, it just had nothing to do.
thommck had the best answer on how to get around this that I’ve found – use a custom WMI query. You’ll need to remove the ‘Apply once and do not reapply’ tick, but the file itself will only be copied over when both targeting rules are true. Please read his post for all the details, but the second item will need to be a WMI query, and have a string similar to this:
SELECT LastModified FROM CIM_DataFile WHERE name=”C:\\windows\regedit.exe” AND LastModified < ‘20160701000000.000000+060’
(Update 20th September 2024)
jszabo_98 in the comments has mentioned that he had to make a few small changes to the above WMI query example to work:
get-wmiobject -query ‘SELECT LastModified FROM CIM_DataFile WHERE name=”C:\\windows\\regedit.exe” AND LastModified < “20160701000000.000000+060″‘
(End of update)
This is checking the date of the file, and will only be ‘true’ if it’s less than that date.
Keep in mind that this is less than ideal, as WMI queries aren’t the most efficient way of processing group policy preferences, but it may be better than copying files around your network to every PC, every 90 minutes.