0

I am creating an automation script that should take a user's input for version, package new, and new package path, then compress it into a zip folder. Unfortunately, I can't hardcode the paths, so I'm struggling with how to use relative paths and user inputs that I have to validate before using.

$env = Read-Host -Prompt "Version Number"

if ($env.length -ne 7) {
    $env = Read-Host "Re-enter version number"
}

$packageName = Read-Host -Prompt "Package Name"

$newPackage = Write-Output $packageName"."$env

$newDirectory = Read-Host -Prompt "Path to new directory"
$deployPath = Read-Host -Prompt "Path to Deploy.ps1 file"
$zipFile = Read-Host -Prompt "Path for new zip file"

$newItem = $newDirectory"/"$newPackage
Write-Host $newItem

new-item $newItem -type directory 
Copy-Item $deployPath -Destination $zipFile

Microsoft.PowerShell.Archive\Compress-Archive -Path /Users/SG/projects/$newPackage -DestinationPath /Users/SG/$newPackage.zip

I need the $zipFile to be input from the user, and the -Path/-DestinationPath should be relative paths since they can't be hardcoded.

iRon
  • 20,463
  • 10
  • 53
  • 79

2 Answers2

0

You could use windows forms to prompt for directory paths. A function to do so might look something like

Function Get-filePath() {

    [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null

    $OpenFolderDialog = New-Object System.Windows.Forms.FolderBrowserDialog
    $OpenFolderDialog.rootfolder = 'MyComputer'
    $OpenFolderDialog.ShowDialog() | Out-Null
    $OpenFolderDialog.SelectedPath
}

Then use it like

Write-Host "Please enter your path for X/Y/Z"
$newDirectory = Get-filePath

for each of your needed paths, or however you'd care to integrate. You can play with initial directory a bit too.

updated example:

Function Get-filePath() {

    [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null

    $OpenFolderDialog = New-Object System.Windows.Forms.FolderBrowserDialog
    $OpenFolderDialog.rootfolder = 'MyComputer'
    $OpenFolderDialog.ShowDialog() | Out-Null
    $OpenFolderDialog.SelectedPath
}

Write-Host "Path to new directory:"
$newDirectory = Get-filePath
$newDirectory
Write-Host "Path to deploy the ps1 file:"
$deployPath = Get-filePath
$deployPath
Write-Host "Path for new zip file:"
$zipFile = Get-filePath
$zipFile
cptcmdlet
  • 1
  • 2
  • How would you get it to run? I'm getting a couple of errors about InvalidOperation and type not founds. – Sabrina Grosse Mar 08 '23 at 18:38
  • Sorry I may have made a few errors I updated my answer to hopefully be cleaner and tested it in ps5/7 – cptcmdlet Mar 08 '23 at 20:23
  • I'm trying this on a Mac instead of a PC. Would that make this harder to execute? Do I have to call something before the function when I run it? – Sabrina Grosse Mar 08 '23 at 21:53
  • Ah yes I'm sorry - I wrote from a Windows perspective. I think you can still accomplish what you want though. If what you need is to validate the path the user gives, you could use Test-Path on the path they give you and if it's invalid ask them for a valid one. `do{ $path = Read-Host "Enter a path" $pathCheck = Test-Path $path if(!$pathCheck){ write-host "that path is invalid." } } until($pathCheck)` then execute what you need after the validation check passes. – cptcmdlet Mar 09 '23 at 00:06
  • @Sabrina Grosse, adding more details and clarity to your question, might avoid that someone spends time on an answer that misses your point. Please read: [how to ask](https://stackoverflow.com/help/how-to-ask) – iRon Mar 09 '23 at 08:23
  • Got it. I'm sorry for the confusion; thanks for the help. – Sabrina Grosse Mar 09 '23 at 13:33
0

You might simply add mandatory parameters to your script.
I would simply use a [String] type for this as a [System.Io.FileInfo] type would default any relative path to the C:\WINDOWS\system32 directory. See: PowerShell issue Introduce a PowerShell-aware path-information class for convenient .NET interoperability #14745.
You might further describe in the comment base help

<#
.SYNOPSIS
    Compress Files
.DESCRIPTION
    I am creating an automation script that should take a user's input for
    version, package new, and new package path, then compress it into a zip
    folder. Unfortunately, I can't hardcode the paths, so I'm struggling with 
    how to use relative paths and user inputs that I have to validate before 
    using.
.PARAMETER ZipFile
    (Relative) path for new zip file
#>
Param(
    [Parameter(Mandatory=$true)]
    [string]
    $zipFile
)
Join-Path (Get-Location) $ZipFile

If you put this in a ZipFile.ps1 script, the following happens:

PS C:\CurrentDirectory> .\ZipFile.ps1 -?

Returns

NAME
    C:\CurrentDirectory\ZipFile.ps1

SYNOPSIS
    Compress Files

SYNTAX
    C:\CurrentDirectory\ZipFile.ps1 [-zipFile] <String> [<CommonParameters>]

DESCRIPTION
    I am creating an automation script that should take a user's input for
    version, package new, and new package path, then compress it into a zip
    folder. Unfortunately, I can't hardcode the paths, so I'm struggling with
    how to use relative paths and user inputs that I have to validate before
    using.

RELATED LINKS

REMARKS
    To see the examples, type: "Get-Help C:\CurrentDirectory\ZipFile.ps1 -Examples"
    For more information, type: "Get-Help C:\CurrentDirectory\ZipFile.ps1 -Detailed"
    For technical information, type: "Get-Help C:\CurrentDirectory\ZipFile.ps1 -Full"

If you than invoke your script (.\ZipFile.ps1) without arguments the script will automatically ask for the mandatory parameters:

PS C:\CurrentDirectory> .\ZipFile.ps1

Returns

cmdlet ZipFile.ps1 at command pipeline position 1
Supply values for the following parameters:
zipFile: Test.Zip
C:\CurrentDirectory\Test.Zip

And you might also consider to invoke you script directly with the required arguments:

PS C:\CurrentDirectory\ZipFile.ps1 My.Zip

Returns

C:\CurrentDirectory\My.Zip
iRon
  • 20,463
  • 10
  • 53
  • 79
  • thank you for this. I'm trying the script right now and have a few questions: Where would the user be prompted to add the version number - could it be added to parameters, and then how does it know to compress the file/ do it? – Sabrina Grosse Mar 09 '23 at 14:15
  • Also, if I require the version number as a parameter, would it be able to be used in another command that requires a set variable? `octo create-release --project single-hole-gaming --version <$env> --server "https://puttshack.octopus.app" --apiKey="API-ABCDEF"` – Sabrina Grosse Mar 09 '23 at 14:28
  • You might indeed also add a `$Version` parameter to your script. Depending on the expected format you might even use the [`[Version]` class](https://learn.microsoft.com/dotnet/api/system.version) for this. As an aside, [`$env`](https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_environment_variables) is a predefined variable (provider) and shouldn't be used. It might also be used in another command, see: [How can I execute an external program with parameters in PowerShell?](https://stackoverflow.com/q/12478535/1701026). – iRon Mar 09 '23 at 18:07
  • If this doesn't work out for you, I recommend you to create a new question with specific details and an [mcve] what you are trying to accomplish. – iRon Mar 09 '23 at 18:07