2 Scripts - Doing almost the same thing. Maybe create a Function?

Hello.
I have written 2 logon scripts and 2 logoff scripts that do roughly the same thing.
We work on VMware Horizon Non-presistent desktops, across multiple DEM environments.
In order for users to get their shortcuts in Chrome, profile.pb is exported from %appdata%\Google\Chrome\User Data\Default to a home directory.
With Firefox it’s a bit more advanced, because the Profiles directory for firefox is generated completely randomly, like mine located in %appdata%\Mozilla\Firefox\Profiles\2lmkijxd.default-release-2.
To retrieve this value, the script runs through an INI file located in %appdata%\Mozilla\Firefox\Profiles\profiles.ini.

So the scripts do almost the same, apart from extracting the value in the INI file.
Will assume that creating a function should be able to migrate both scripts to 1 script and do the same job. But I’m a bit too new to PS, and will learn how functions work.
But as of now I don’t have time, so I hope someone here can help me along the way, so I can see for myself what the new script will look like.

The imports are then correspondingly similar, with the exception of the INI file which is used to retrieve the correct firefox profile.

The scripts individually seem to work, and I see that there is a logical flaw, as I have Copy-Item in the nested IF Else statement. But I can’t get the logic to work here.
The files should be exported every time they log off (log off script) and imported every time the user logs on…

Chrome Logon Script - Import:

$COMPANYregkey = 'HKCU:\COMPANY'
$name = 'ChromeImported'
$Value = "0"
$ProfArchPath = @()
$ProfArchPath = (Get-ItemPropertyValue -Path 'HKCU:\Software\Policies\Immidio\Flex Profiles\Arguments' -Name 'ProfileArchivePath')
$File = $ProfArchPath + '\profile.pb'
$Appdata = $env:APPDATA
$FileLocation = $Appdata + '\Google\Chrome\User Data\Default'

If((Get-ItemProperty $COMPANYregkey).PSObject.Properties.Name -contains $name) {
}

Else {
    New-ItemProperty -Path $COMPANYregkey -Name $name -Value $value
}

if($value -eq 1){ 
    }

Else{
    $regKey = Get-ItemProperty -Path $COMPANYregkey -Name $name

    if (($regKey.ChromeImported -eq "1") -and (Test-Path -path $FileLocation)){ 
        Copy-Item $File -Destination $FileLocation
    }
    Else {
        If (Test-Path $FileLocation) {
            Copy-Item $File -Destination $FileLocation 
        }

        Else {
            New-Item $FileLocation -ItemType Directory
            Copy-Item $File -Destination $FileLocation 
        }  

        $value = "1" 
        Set-ItemProperty -Path $COMPANYregkey -Name $name -Value $value
    }
}

Firefox Logon Script - Import

$COMPANYregkey = 'HKCU:\COMPANY'
$name = 'FirefoxImported'
$Value = "0"
$ProfArchPath = @()
$ProfArchPath = (Get-ItemPropertyValue -Path 'HKCU:\Software\Policies\Immidio\Flex Profiles\Arguments' -Name 'ProfileArchivePath')

$File = $ProfArchPath + '\places.sqlite'
$Appdata = $env:APPDATA

$INI_FileLocation = $Appdata + '\Mozilla\Firefox'
$IniFile = $INI_FileLocation + '\profiles.ini'

$AppLine = Get-Content -Path $IniFile | Where-Object { $_ -match 'Default=Profiles/' }
$Profile = $AppLine.Split('/')[1]
$FileLocation = $Appdata + '\Mozilla\Firefox\Profiles\' + $Profile + '\places.sqlite'

If((Get-ItemProperty $COMPANYregkey).PSObject.Properties.Name -contains $name) {
}

Else {
    New-ItemProperty -Path $COMPANYregkey -Name $name -Value $value
}

if($value -eq 1){ 
    }

Else{
    $regKey = Get-ItemProperty -Path $COMPANYregkey -Name $name

    if (($regKey.FirefoxImported -eq "1") -and (Test-Path -path $FileLocation)){ 
        Copy-Item $File -Destination $FileLocation
    }
    Else {
        If (Test-Path $FileLocation) {
            Copy-Item $File -Destination $FileLocation
        }

        Else {
            New-Item $FileLocation -ItemType Directory
            Copy-Item $File -Destination $FileLocation 
        }  

        $value = "1" 
        Set-ItemProperty -Path $COMPANYregkey -Name $name -Value $value

    }
}

Chrome logoff Script - Export

$ProfArchPath = @()
$ProfArchPath = (Get-ItemPropertyValue -Path 'HKCU:\Software\Policies\Immidio\Flex Profiles\Arguments' -Name 'ProfileArchivePath')
$Appdata = $env:APPDATA
$FileLocation = $Appdata + '\Google\Chrome\User Data\Default\profile.pb'
Copy-Item $FileLocation -Destination $ProfArchPath

Firefox log off script - Export:

$Appdata = $env:APPDATA
$INI_FileLocation = $Appdata + '\Mozilla\Firefox'
$IniFile = $INI_FileLocation + '\profiles.ini'

$AppLine = Get-Content -Path $IniFile | Where-Object { $_ -match 'Default=Profiles/' }
$Profile = $AppLine.Split('/')[1]

$ProfArchPath = @()
$ProfArchPath = (Get-ItemPropertyValue -Path 'HKCU:\Software\Policies\Immidio\Flex Profiles\Arguments' -Name 'ProfileArchivePath')


$BookmarkFileLocation = $INI_FileLocation + '\profiles\' + $Profile + '\places.sqlite'
Copy-Item $BookmarkFileLocation -Destination $ProfArchPath

All feedback is appreciated.
Greetings newbie

If these scripts do their job why would you need to hurry? :thinking: You have all the time you want?! :man_shrugging:t4:

What’s the opposite of -contains? When you figured that out you can change your condition to that, move your action to the if script block and drop the else script block. :wink:

… the same here …

What’s the opposite of -eq? :wink:

Hi. I have been working and testing this script, re-written it a couple of times. Done some changes to the script.

$Corpregkey = 'HKCU:\Corp'
$name = 'ChromeImported'
$ProfArchPath = @()
$ProfArchPath = (Get-ItemPropertyValue -Path 'HKCU:\Software\Policies\Immidio\Flex Profiles\Arguments' -Name 'ProfileArchivePath')
$File = $ProfArchPath + '\profile.pb'
$Appdata = $env:APPDATA
$FileLocation = $Appdata + '\Google\Chrome\User Data\Default'



If ((Get-ItemProperty $Corpregkey).PSObject.Properties.Name -notcontains $name)
    {
    CreateOrCopyProfile
    New-ItemProperty -Path $Corpregkey -Name $name -Value 1 -PropertyType String
    }

Else
    {
    CreateOrCopyProfile
    Set-ItemProperty -Path $Corpregkey -Name $name -Value 1
    }




function CreateOrCopyProfile
    {
    if (!(Test-Path $FileLocation))
        { 
            New-Item $FileLocation -ItemType Directory
            Copy-Item $File -Destination $FileLocation
        }

    Else
        {
            $ExistingFile = $FileLocation +'\profile.pb'
            $SizeExistingFile = ((Get-Item $ExistingFile).length/1KB)
            $SizeProfArcFile = ((Get-Item $File).length/1KB)

            if ($SizeExistingFile -lt $SizeProfArcFile)
                {
                Copy-Item $File -Destination $FileLocation
                }
        }
    }

We need to import google chrome bookmarks into the new environment, but when i log on to the new desktop, nothing is imported.
When i run this script locally, i get this error message:

CreateOrCopyProfile : The term 'CreateOrCopyProfile' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the nam
e, or if a path was included, verify that the path is correct and try again.
At line:19 char:5
+     CreateOrCopyProfile
+     ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (CreateOrCopyProfile:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

When i Run the script again after this error, it works, the profile.pb file is imported, and my bookmarks are back…
Why does it fail in the first place?

Hmm … I just took a short look to it … is it on purpose that you use your function CreateOrCopyProfile before you declare/define it?

BTW: I’d recommend to use a function name following the usual naming conventions … for example New-Profile or Copy-Profile

1 Like

To follow up on what Olaf mentions. Powershell reads a script from the top down rather than reading the entire file.
So if you call a function before it is defined you will get the error you see. The reason it works the second time you run it is that the function has been loaded into memory in the active session. So on the second run it will grab the function from memory rather than from the script itself.

It is recommended to place all functions at the beginning of scripts so you won’t risk calling a function before it’s defined.

I’d also echo Olaf’s recommendation to follow the PS Verb-Noun way of naming functions. It’s a good habit to get into.

2 Likes

Shoot…
I have only run the testing locally on one machine and it has worked there. Thought the script was compiled when it was run, but learned something new today too. Thanks.