1

I am fairly new to PowerShell and am having challenges trying to get a PS1 executable file to work. Running the script in a PowerShell console works completely fine and copy's items and creates the correct log filename.

The expectation would be to Right-click the PS1 file containing the script, run the script with "Run with PowerShell", and then allow the script to finish with a log file populated and files copied when user prompt selects yes.

At this point, there are no errors messages, other than the PS1 file script gets replaced by ton of unrecognizable symbols/characters and creates the log file as "Box Project Files.ps1JobFileLocations.log" instead of "JobFileLocations.log".


The PowerShell version being used is 5.1. Windows 10 OS. Set-ExecutionPolicy was set to Unrestricted and confirmed as Unrestricted for CurrentUser and LocalMachine. Unblock-File was also tried.

Below is the script that works in a PowerShell Console but not as a PS1 executable file.

# Drawing Tag Searches
$MechDWGFilterList = @('*IFC*','*mech*', '*permit*', '*final*')
$DatabaseFilterList = @('*field*','*software*')

# Root folder and destination folder
$JobNumber = '*'+(Read-Host -Prompt 'Enter in job number')+'*'
$srcRoot = 'C:\Users\username\Box\'
$JobRoot = (Get-ChildItem -Path $srcRoot -Filter "*Active Projects*" -Recurse -Directory -Depth 1).Fullname
$dstRoot = $MyInvocation.MyCommand.Path
# Find job numer pdf file
$JobFolder = (Get-ChildItem -Path $JobRoot -Filter "$JobNumber" -Recurse -Directory -Depth 0).Fullname
$Logfile = $dstRoot+"JobFileLocations.log"

$reply = Read-Host -Prompt "Make a copy of relevant project files to local drive?[y/n]"


# Find sub-folder from job folder
$ProposalFolder = (Get-ChildItem -Path $JobFolder -Filter "*Proposals*" -Recurse -Directory).Fullname
$MechDWGFolder = (Get-ChildItem -Path $JobFolder -Filter "*Plans*" -Recurse -Directory).Fullname
$SubmittalFolder = (Get-ChildItem -Path $JobFolder -Filter "*Submittal*" -Recurse -Directory).Fullname
$DatabaseFolder = (Get-ChildItem -Path $JobFolder -Filter "*Backup*" -Recurse -Directory).Fullname
$EstimateFolder = (Get-ChildItem -Path $JobFolder -Filter "*Estimate*" -Recurse -Directory).Fullname
# Find files from list
$ProposalList = Get-ChildItem -Path $ProposalFolder -Filter '*proposal*.pdf' -r | Sort-Object -Descending -Property LastWriteTime | Select -First 1
$MechDWGList = Get-ChildItem -Path $MechDWGFolder -Filter *.pdf -r | Sort-Object -Descending -Property LastWriteTime 
$SubmittalList = Get-ChildItem $SubmittalFolder -Filter '*submittal*.pdf' -r | Sort-Object -Descending -Property LastWriteTime | Select -First 1
$DatabaseList = Get-ChildItem $DatabaseFolder -Filter *.zip -r | Sort-Object -Descending -Property LastWriteTime | Select -First 1
$EstimateList = Get-ChildItem -Path $EstimateFolder -Filter *.xl* -r | Sort-Object -Descending -Property LastWriteTime
# Log file path location and copy file to local directory

# Function to add items to a log text file
Function LogWrite
{
   Param ([string]$logstring)
   Add-content $Logfile -value $logstring
}

# Log file path location and copy file to local directory
LogWrite "::==========================================::`n||           Project Document Paths         ||`n::==========================================::"
LogWrite "`nNote: If a section has more than one file path, files are listed from most recent to oldest.`n"

LogWrite "----------Scope Document/Proposal(s)----------"
foreach ($file in $ProposalList)
{
    LogWrite $file.FullName
    if ( $reply -match "[yY]" ) 
    { 
        Copy-Item -Path $($file.FullName) -Destination $dstRoot
    }

}

LogWrite "`n-------------Mechanical Drawing(s)------------"
foreach ($file in $MechDWGList)
{
    # Where the file name contains one of these filters
    foreach($filter in $MechDWGFilterList)
    {
        if($file.Name -like $filter)
        {
            LogWrite $file.FullName
            if ( $reply -match "[yY]" ) 
            { 
                Copy-Item -Path $($file.FullName) -Destination $dstRoot
            }
        }
    }
}

LogWrite "`n-------------Controls Submittal(s)------------"
foreach ($file in $SubmittalList)
{
    LogWrite $file.FullName
    if ( $reply -match "[yY]" ) 
    { 
        Copy-Item -Path $($file.FullName) -Destination $dstRoot
    }
}

LogWrite "`n-------------------Database-------------------"
foreach ($file in $DatabaseList)
{
    LogWrite $file.FullName
    if ( $reply -match "[yY]" ) 
    { 
        Copy-Item -Path $($file.FullName) -Destination $dstRoot
    }
}

LogWrite "`n------------------Estimate(s)-----------------"
foreach ($file in $EstimateList)
{
    LogWrite $file.FullName
    if ( $reply -match "[yY]" ) 
    { 
        Copy-Item -Path $($file.FullName) -Destination $dstRoot
    }
}

# If running in the console, wait for input before closing.
if ($Host.Name -eq "ConsoleHost")
{
    Write-Host "Press any key to continue..."
    $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyUp") > $null
}

Could someone help me understand what is wrong with running the script as a PS1 file?

3
  • 2
    Change $dstRoot = $MyInvocation.MyCommand.Path to $dstRoot = Split-Path $MyInvocation.MyCommand.Path -Parent, otherwise you're supplying the path of the script itself as the destination (I assume you wanted the path of the parent folder). Alternatively $dstRoot = $PSScriptRoot Commented Jan 26, 2022 at 18:25
  • 1
    @MathiasR.Jessen thank you so much for clearing this up. The $dstRoot = Split-Path $MyInvocation.MyCommand.Path -Parent totally makes sense. Now the next thing to learn and understand is the performance difference between that and $dstRoot = $PSScriptRoot Commented Jan 26, 2022 at 18:52
  • 1
    The latter is definitely going to be faster, but I wouldn't recommend getting caught up in that level of performance nitpicking - you should choose the latter if you find it easier to read :) Commented Jan 26, 2022 at 19:13

1 Answer 1

2

The problem with your script is this particular line:

$dstRoot = $MyInvocation.MyCommand.Path

$MyInvocation.MyCommand.Path resolves the rooted filesystem path to the script itself - which is why you get Box Project Files.ps1 (presumably the name of the script) in the log path.

The get the path of the parent directory of any file path, you can use Split-Path -Parent:

$dstRoot = Split-Path -LiteralPath $MyInvocation.MyCommand.Path -Parent

That being said, since Windows PowerShell 3.0, both the directory and script file paths have been available via the $PSCommandPath and $PSScriptRoot automatic variables, so you can simplify the code to just:

$dstRoot = $PSScriptRoot
Sign up to request clarification or add additional context in comments.

1 Comment

Will keep both in mind. Thanks for the lesson and help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.