Search code examples
powershellfirefoxwindows-7copy-item

Copying file into folder via system profile


I'm trying to replace the prefs.js file in a Firefox profile, to change the way firefox behaves on about 5k machines.

I kill firefox, remove the file with the script

Remove-Item -Path "C:\Users\*\AppData\Roaming\Mozilla\Firefox\Profiles\*\prefs.js" -Force -Recurse

which works without issue. Then I use copy-item to pull in the desired copy of prefs.js to all firefox profiles on the machine. THIS IS THE SCRIPT I'M ASKING A QUESTION ABOUT.

$Target = Get-ChildItem -path "C:\Users\*\AppData\Roaming\Mozilla\Firefox\Profiles\*"
Copy-Item "C:\DTS\BMC\ReplacePrefsjs\prefs.js" -Destination $Target -Force -Recurse

When I run the script manually on my own (domain admin) account, I get access denied errors for all user profiles that AREN'T mine, but the file is successfully copied to my firefox profile. This seems normal, as it's only running with normal permissions. Here's an excerpt of the log from that execution:

Get-ChildItem : Access is denied
At C:\DTS\BMC\ReplacePrefsjs\PrefsJSReplace.ps1:2 char:11
+ $Target = Get-ChildItem -path "C:\Users\*\AppData\Roaming\Mozilla\Fir ...
+           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : PermissionDenied: (C:\Users\<removed>\AppData:String) [Get-ChildItem], UnauthorizedAccessException
+ FullyQualifiedErrorId : ItemExistsUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
Get-ChildItem : Access is denied
At C:\DTS\BMC\ReplacePrefsjs\PrefsJSReplace.ps1:2 char:11
+ $Target = Get-ChildItem -path "C:\Users\*\AppData\Roaming\Mozilla\Fir ...
+           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : PermissionDenied: (C:\Users\<removed>\AppData:String) [Get-ChildItem], UnauthorizedAccessException
+ FullyQualifiedErrorId : ItemExistsUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand

However, when I send out the script with our deployment solution (like SCCM, etc), I receive the following error:

PS>TerminatingError(Copy-Item): "Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'Destination'. Specified method is not supported."
Copy-Item : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'Destination'. Specified 
method is not supported.
At C:\DTS\BMC\ReplacePrefsjs\PrefsJSReplace.ps1:3 char:61
+ ... tem "C:\DTS\BMC\ReplacePrefsjs\prefs.js" -Destination $Target -Force  ...
+                                                           ~~~~~~~
+ CategoryInfo          : InvalidArgument: (:) [Copy-Item], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.CopyItemCommand
 Copy-Item : Cannot convert 'System.Object[]' to the type 'System.String'
required by parameter 'Destination'. Specified method is not supported.
At C:\DTS\BMC\ReplacePrefsjs\PrefsJSReplace.ps1:3 char:61
+ ... tem "C:\DTS\BMC\ReplacePrefsjs\prefs.js" -Destination $Target -Force  ...
+                                                           ~~~~~~~
+ CategoryInfo          : InvalidArgument: (:) [Copy-Item], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.CopyItemCommand

When I first noticed this, I thought the script needed something like a 'foreach' to address each entry that $Target would pull (running the script for ALL firefox profiles), instead of -recurse.

If that were the case, then it also shouldn't work at all when I run it manually, but when I do it goes through each profile, gives me access denied for the locations I can't edit without elevated permissions, works for my profile, and finishes without the convert error.

Can anyone help me understand why my Copy-Item can't resolve the destination $Target when ran by the system profile?


Solution

  • You are creating a array of objects using $Targets

    $Target = Get-ChildItem -path "C:\Users\*\AppData\Roaming\Mozilla\Firefox\Profiles\*"
    

    You are then not piping the output but instead just putting the array in a new command. Try this

    Get-ChildItem "C:\Users\*\AppData\Roaming\Mozilla\Firefox\Profiles\*" -Directory | foreach-object{Copy-Item "C:\DTS\BMC\ReplacePrefsjs\prefs.js" -Destination $_ -Force -Recurse}