2
votes

I have the following Powershell code:

function readConfigData
{
    $workingDir = (Get-Location).Path
    $file = ""

    if ($Global:USE_LOCAL_SERVER)
    {
        $file = $workingDir + '\Configs\Localhost.ini'
    }
    else
    {
        $file = $workingDir + '\Configs\' + $env:COMPUTERNAME + '.ini'
    }

    Write-Host 'INIFILE: ' $file

    if (!$file -or ($file = ""))
    {
        throw [System.Exception] "Ini fil är inte satt."
    }
    if (!(Test-Path -Path $file))
    {
        throw [System.Exception] "Kan inte hitta ini fil."
    }
}

readConfigData

How should I declare the local variable $file that can be passed to the function Test-Path. My local variable $file get populated but then when I place it as argument to other function it's like it is out of scope.

I read the about scopes article but wasn't able to figure it out.

Currently I get the error:

INIFILE: D:\Projects\scripts\Configs\HBOX.ini Test-Path : Cannot bind argument to parameter 'Path' because it is an empty string. At D:\Projects\freelancer.com\nero2000\cmd script to powershell\script.ps1:141 char:27 + if (!(Test-Path -Path $file)) + ~~~~~ + CategoryInfo : InvalidData: (:) [Test-Path], ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.TestPathCommand

3

3 Answers

2
votes
if (!$file -or ($file = ""))

should be replaced by

if (!$file -or ($file -eq ""))

You assign $file to an empty string in the first if clause and therefore your variable is empty in the Test-Path call.

Edit: Also there are some alternatives: How can I check if a string is null or empty in PowerShell?

you could either use

if([string]::IsNullOrEmpty($file))

or even just

if(!$file)
1
votes

As others have mentioned, you are unintentionally assigning a blank string to $file in your first if (!$file ... statement. That is really the root of your problem.

However, instead of:

if (!$file -or ($file = ""))

You could use this forumula, which I find explains itself better:

if([String]::IsNullOrEmpty($file))
1
votes

I would define a function Get-ConfigFile to retrieve the config and add a switch for local server:

function Get-ConfigFile
{
    Param(
        [switch]$UseLocalServer
    )

    $workingDir = (Get-Location).Path
    if ($UseLocalServer.IsPresent)
    {
         Join-Path $workingDir '\Configs\Localhost.ini'
    }
    else
    {
         Join-Path $workingDir ('\Configs\{0}.ini' -f $env:COMPUTERNAME)
    }
}

I would also use the Join-Path cmdlet to join a path instead of string concatenations.

Now you can retrive the config file path using:

$configFile = Get-ConfigFile -UseLocalServer:$Global:USE_LOCAL_SERVER

And if needed, ensure that the file exists:

if (-not(Test-Path -Path $configFile))
{
    throw [System.Exception] "Kan inte hitta ini fil."
}

Note: Get-Location will give you the current powershell path (working location), if you want to get the path where your script is located, use this instead:

$workingDir = split-path -parent $MyInvocation.MyCommand.Definitio