Copy file to all users currently logged in and for all future users.

Good morning everyone,

I am looking to write a script to allow a file copied to all profiles currently residing on the machine and for all future accounts that are created as well. Problem is the file needs to be created in: c:\users[userid]\appdata\local[folder location]. The .ini file that runs the configuration of the application resides in C:\Program Files (x86)[folder location] and the problem is our users do not have access to this location and instead writes a new .ini in their appdata location. If I copy the file to their appdata during install when they launch the application it does not create a new .ini file and uses the one present. Any thoughts as to how I can begin to create this? Attached below is my Deploy-Application.ps1 Pre/Install/Post steps. If you want the full file let me know and I will load it.(Didn’t include it since I didn’t change anything other than Variable Declaration)


##===============================================
##
PRE-INSTALLATION
##*===============================================
[string]$installPhase = ‘Pre-Installation’

	## Show Welcome Message, close Internet Explorer if required, allow up to 3 deferrals, verify there is enough disk space to complete the install, and persist the prompt
	Show-InstallationWelcome -CloseApps 'mirrorop' -AllowDefer -DeferTimes 3 -CheckDiskSpace -PersistPrompt
	
	## Show Progress Message (with the default message)
	Show-InstallationProgress
	
	## <Perform Pre-Installation tasks here>
	
	Remove-MSIApplications -Name 'MirrorOp'
	
	##*===============================================
	##* INSTALLATION 
	##*===============================================
	[string]$installPhase = 'Installation'
	
	
	## Handle Zero-Config MSI Installations
	If ($useDefaultMsi) { Execute-MSI -Action 'Install' -Path $defaultMsiFile }
	
	## <Perform Installation tasks here>
	
	
	Show-BalloonTip -BalloonTipText 'Installation started' -BalloonTipTitle 'MirrorOp' -BalloonTipTime 2000
	Execute-Msi -Path "$dirFiles\MirrorOp.msi" -Parameters '/passive /norestart'
	Write-Log -Message "Installing MirrorOp 1.0.1.4" -Source 'Add-Patch' -LogType 'CMTrace'
	
	##*===============================================
	##* POST-INSTALLATION
	##*===============================================
	[string]$installPhase = 'Post-Installation'
	
	
	## <Perform Post-Installation tasks here>
	
	Remove-File -Path 'C:\Program Files (x86)\MirrorOp\wps.ini'
	Remove-File -Path 'C:\users\public\desktop\MirrorOp.lnk'
	Copy-File -Path "$dirFiles\wps.ini" -Destination "C:\ProgramData\MirrorOp\wps.ini"
	Copy-File -Path "$dirFiles\favorite.xml" -Destination "C:\ProgramData\MirrorOp\favorite.xml"
	
	## Display a message at the end of the install
	If (-not $useDefaultMsi) { Show-InstallationPrompt -Message 'This software has been sucessfully been installed. If you have any issues please report them to our Ascend Service Desk.' -ButtonRightText 'OK' -Icon Information -NoWait }
}

We have a function in the toolkit called Get-UserProfiles which gets the path to all of the users profiles on the system and also the default profile. The default profile is used to provision the profile for newly created users to changes you make there will be replicated to new users.

Here is one example from the function showing how to use it:

## Returns the user profile path for each user on the system. This information can then be used to make modifications under the user profile on the filesystem.
[string[]]$ProfilePaths = Get-UserProfiles | Select-Object -ExpandProperty 'ProfilePath'

Then just use a loop to cycle through the profile paths and make the appropriate file changes you want to make.

Thank-you for the response Muhammad,

I noticed after you had posted that I was using an older version of the toolkit that did not have that. I have it now and I apologize because my PowerShell skills are still developing. I am just a bit confused on how to follow this up. I am pretty sure it is a syntax issue on my part. Essentially I need to make sure the folder path is created: c:\users[profile]\appdata\roaming\sap\common and then the files copied into that location:

$ProfilePaths = Get-UserProfiles | Select-Object -ExpandProperty ‘ProfilePath’
ForEach-Object {
New-Folder -Path “$ProfilePaths\AppData\Roaming\SAP”
New-Folder -Path “$ProfilePaths\AppData\Roaming\SAP\Common”
Copy-File -Path “$dirFiles\Support\saplogon.ini” -Destination “$ProfilePaths\AppData\Roaming\SAP\Common\saplogon.ini”
Copy-File -Path “$dirFiles\Support\SapLogonTree.xml” -Destination “$ProfilePaths\AppData\Roaming\SAP\Common\SapLogonTree.xml”
Copy-File -Path “$dirFiles\Support\SAPUILandscape.xml” -Destination “$ProfilePaths\AppData\Roaming\SAP\Common\SAPUILandscape.xml”
Copy-File -Path “$dirFiles\Support\SAPUILandscapeGlobal.xml” -Destination “$ProfilePaths\AppData\Roaming\SAP\Common\SAPUILandscapeGlobal.xml”
}
Copy-File -Path “$dirFiles\Support\SAP Logon.lnk” -Destination “C:\Users\Public\Desktop\SAP Logon.lnk”
Remove-File -Path ‘C:\Users\Public\Desktop\NetWeaver Business Client 5.0.lnk’

Any and all assistance is greatly appreciated.

Thank-you,
OHP

Update 10.02.2015:

I found out why it was failing this way. I added:
Write-Log -Message “$ProfilePaths”

And it makes 1 long string with all user profiles:
C:\Users\openilxa C:\Users\openil C:\Users\Administrator C:\Users\Default

Which makes it error out on the loop since it doesn’t split them up:
Failed to create folder [C:\Users\openilxa C:\Users\openil C:\Users\Administrator C:\Users\Default\AppData\Roaming\SAP]

I tried using a split() to get rid of the spaces and separate the usernames:
$ProfilePaths.split()

But it gives me the following error:
Method invocation failed because [System.String[]] doesn’t contain a method named ‘split’

Any idea how I can split these usernames up so I can run a loop on it?

Thank-you,
OHP

$ProfilePaths = Get-UserProfiles | Select-Object -ExpandProperty 'ProfilePath'
ForEach ($Profile in $ProfilePaths) {
	Copy-File -Path "$dirFiles\Support\saplogon.ini" -Destination "$Profile\AppData\Roaming\SAP\Common\saplogon.ini"
}

Beautiful! Thank-you for the assistance Muhammad. That worked perfectly.

Shouldn’t we be checking if the folder exists?

I’ve just done the same filecopy task… saplogon.ini…

My snippet looks like this…:

<code>#copy ini file to all users
		[string[]]$ProfilePaths = Get-UserProfiles | Select-Object -ExpandProperty &#039;ProfilePath&#039;
        Foreach ($path in $ProfilePaths)
        {
        $testPath=test-path &quot;$path\appdata\Roaming\SAP\Common\&quot;
        
        if (!$testpath)
        {
        #Create Folder
        New-Item -ItemType Directory -Force -Path &quot;$path\appdata\Roaming\SAP\Common\&quot;
        Copy-File -path &quot;$dirFiles\saplogon.ini&quot; -destination &quot;$path\appdata\Roaming\SAP\Common\saplogon.ini&quot; -Recurse

        }
        else
        {
        
        Copy-File -path &quot;$dirFiles\saplogon.ini&quot; -destination &quot;$path\appdata\Roaming\SAP\Common\saplogon.ini&quot; -Recurse

        }
        
        
        }</code>
1 Like

I’m sure it can be prettied up…but it works…

That works if you don’t know if the folder exists although in my case this was after I have already installed SAP GUI 7.40 which creates those folders already. All I do after the install is update it with our custom xml and ini files.

My fault - was getting installations confused. The SAP GUI 7.40 install does not create those. I have though added your check for folders to my cheat sheet and will start to utilize it. Thanks for the post :slight_smile:

Found this nice peace in stackoverflow

New-Item -ItemType File -Path $destination -Force