0

I'm building a tool that will scan my files and a friend's files. We will use this to make sure we have the same files in our databases. The script I have so far has a variable input issue. For some reason, the PowerShell script fails on my drive letter input. Anyone have any ideas?

Here is my script:

{ function Show-Menu { param ( [string] $Title = "Andy's Manual Database Tool" ) Clear-Host Write-Host "" Write-Host "================ $Title ================" Write-Host "" Write-Host -f Green "1. Andys Files listing" Write-Host -f green "2. Reids files listing" Write-Host -f Red "3. Dark Matter Testing" Write-Host "4. Convert .txt to .csv" Write-Host "5. Convert Blank File to .csv" Write-Host "6. Convert .csv to .txt" } Function Body { Show-Menu Write-Host "" $Input = Read-Host "Please make a selection" if ($Input -eq "1") { Clear-Host $root = Read-Host -Prompt 'Specify the location of Database? Example format: C:\*' $y = read-host -Prompt 'Input file types. Format Example: " .jpg,.mp4,.mp3,.pdf .... " Do * for all' $z = Read-Host -Prompt 'Your Save file name will be? Examples: Movies database , Music database , audiobooks.' Get-ChildItem -Path $root -File -Recurse *.$y | Select-Object -Property Name | Export-Csv -NoTypeInformation $z Andy.csv } if ($Input -eq "2") { Clear-Host $root = Read-Host -Prompt 'Specify the location of Database? Example format: C:\*' $y = read-host -Prompt 'Input file types. File Format Examples: " .jpg,.mp4,.mp3,.pdf .... " Do * for all' $z = Read-Host -Prompt 'Your Save file name will be? Examples: Movies database , Music database , audiobooks.' Get-ChildItem -Path $root -File -Recurse *.$y | Select-Object -Property Name | Export-Csv -NoTypeInformation $z' From Reid.csv' } if ($Input -eq "3") { Get-Process | Stop-Process } if ($Input -eq "4") { Clear-Host Get-ChildItem *.txt | rename-item -newname { $_.name -replace ".txt",".csv" } } if ($Input -eq "5") { Clear-Host Get-ChildItem * -Exclude *.ps1,*.CSV,*.TXT | rename-item -newname { "$($_.name).CSV" } } if ($Input -eq "6") { Clear-Host Get-ChildItem *.csv | rename-item -newname { $_.name -replace ".csv",".txt" } } Write-Host 'Complete! ^_^' Start-Sleep -seconds 5 Body } Body } 

This issue is here, from the script above:

$root = Read-Host -Prompt 'Specify the location of Database? Example format: C:\*' $y = read-host -Prompt 'Input file types. Format Example: " .jpg,.mp4,.mp3,.pdf .... " Do * for all' $z = Read-Host -Prompt 'Your Save file name will be? Examples: Movies database , Music database , audiobooks.' Get-ChildItem -Path $root -File -Recurse *.$y | Select-Object -Property Name | Export-Csv -NoTypeInformation $z Andy.csv 

I'm using $root as an input for my drive letter or location path which is the problem.

4
  • What are you typing in? Commented May 11, 2018 at 14:50
  • 2
    With proper formatting, immediately noticed your issue. Never use automatic variables as your variable names. In this case: $Input Commented May 11, 2018 at 14:59
  • Hi Jacob Colvin, Im inputting the drive letter. So it could be c:\ or c:\temp\ or d , g or f:\ Commented May 11, 2018 at 15:02
  • @rogerwilcolta The code you said was "the problem" worked fine for me? Commented May 11, 2018 at 15:22

1 Answer 1

1

There a few minor issues.

  1. $z Andy.csv Needs to be changed to "$z Andy.csv". You will notice when you ran this before you would of received the following message:

Export-Csv : Cannot bind parameter 'Delimiter'. Cannot convert value "Andy.csv" to type "System.Char". Error: "String must be exactly one character long."

  1. Get-ChildItem -Path $root -File -Recurse *.$y Needs to be changed to Get-ChildItem -Path "$root" -Recurse -Include "*$y" - You are prompting the user to put in file extension with .<extension> (assigned to $y) then you are trying to filter with $y

    Ex:$y = read-host -Prompt 'Input file types. Format Example: " .jpg,.mp4,.mp3,.pdf .... " Do * for all'

    Issue: "*.$y" this would equal "..extension". Your results would then be 0 (unless you had a file with ..jpg or something like that)

Corrected:

if ($Input -eq "1") { Clear-Host $root = Read-Host -Prompt 'Specify the location of Database? Example format: C:\*' $y = read-host -Prompt 'Input file types. Format Example: " .jpg,.mp4,.mp3,.pdf .... " Do * for all' $z = Read-Host -Prompt 'Your Save file name will be? Examples: Movies database , Music database , audiobooks.' Get-ChildItem -Path "$root" -Recurse -Include "*$y" | Select Name | Export-Csv -NoTypeInformation "$z Andy.csv" } 

You should be able to correct the rest of your script following the "Corrected" example.

EDIT:

Credit to TheIncredible1

There are automatic variables that should never be used other than for their intended purpose. In your case $Input:

Contains an enumerator that enumerates all input that is passed to a function. The $input variable is available only to functions and script blocks (which are unnamed functions). In the Process block of a function, the $input variable enumerates the object that is currently in the pipeline. When the Process block completes, there are no objects left in the pipeline, so the $input variable enumerates an empty collection. If the function does not have a Process block, then in the End block, the $input variable enumerates the collection of all input to the function.

However, in this case it should not effect your outcome. But, it is a very bad habit to get into and is best to be avoided.

Sign up to request clarification or add additional context in comments.

8 Comments

You failed to address the most glaring issue which is the use of the variable name $Input
@TheIncorrigible1 in this case $Input is always 0, correct? Since the function is not parameterized.
@TheIncorrigible1 I will address the issue with $Input being used as a variable. However, this does not effect the current functionality of the script.
It absolutely affects the script. $Input has very special functionality with functions which he is chaining together
@TheIncorrigible1 I realize the mistake but do not think it actually breaks anything in this case. function Show-Menu { $Input }; 1..3 | Show-Menu; function Show-Menu { $Input = 2; $Input; $Input = 3; $Input }; 1..3 | Show-Menu
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.