Error when using New-Item / md / mkdir - powershell

I've currently got a script that:
Loops through some files
Checks the name of the file
If there is no directory for the file it will create one
Moves the file into the directory
The moving logic works fine. However if a directory does not exist I am given this error (the path is valid, except it does not exist)
C:\Users\User\Documents\Directory\FileName : The term 'C:\Users\User\Documents\
Directory\FileName' is not recognized as the name of a cmdlet, function, script
file, or operable program. Check the spelling of the name, or if a path was
included, verify that the path is correct and try again.
At line:1 char:1
C:\Users\User\Documents\Directory\FileName
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\Users\User\Documents\Directory\FileName) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
The curious part is that it does actually create the folder - however it crashes my script.
Here's the problem part of the script
function CanCreate($dir) {
return !(Test-Path $dir)
}
if (CanCreate($fullDestinationPath)) {
New-Item $fullDestinationPath -ItemType Directory
}
md/mkdir behave differently to New-Item in that they do crash the script, however New-Item prints the error and continues (script seems to finish its job).
Edit:
The issue seems to stem from the fact that I am calling the script from another script.
$ScriptPath = "C:\Powershell Scripts\script.ps1"
& $ScriptPath | Invoke-Expression

The issue was with the fact that I was using | Invoke-Expression to trigger the script.
Simply calling & $ScriptPath, omitting the | Invoke-Expression, was enough to trigger the script.
Thanks everyone.

Related

Powershell spaces in script path

I am trying to streamline how I execute some scripts I wrote by setting up a function and alias to run them. I currently have functions to change my directory to where the scripts need to be run, but when I try to run the script itself I get the following error:
C:\Users\me\Desktop\BoB : The term 'C:\Users\me\Desktop\BoB' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try
again.
At line:1 char:1
+ C:\Users\me\Desktop\BoB Tools\folderScannerV0.4.ps1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\Users\jteit\Desktop\BoB:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
The function is:
function run-scanner { "& 'C:\Users\me\Desktop\BoB Tools\folderScannerV0.4.ps1'" | Invoke-Expression }
I've tried a few variations based on other answers I've found, but I keep getting the same error. I would prefer to not remove the space on the path because other scripts use it successfully. Running the script from the ISE gives me no problems.
Ideally I would like the function to also allow me to have the script run on the folders I would like without changing the working directory (each script works on a particular set of files that are in a static location but some of them use $PWD to get the folders in the location).
For example in my $profile file I have this function: function go-to-temp {cd "C:\Users\me\Desktop\Bob Tools\To be Formatted\Temp"} which I run before I execute the above script. I would like them rolled into a single command without my working directory changing (which would render the go-to-temp function redundant.
What am I doing wrong?
There is no reason to run your script through Invoke-Expression.
Unless your script relies on $PWD, then you should be able to execute it with the call operator: &. As the other poster mentioned, you can use dot-sourcing (.) if you need the variables the script generates, but this will import all global objects (aliases, variables, functions) to your current scope. If it does rely on $PWD, you can utilize Start-Process with -WorkingDirectory to avoid changing where you're at.
function Start-Scanner {
& "$HOME\Desktop\BoB Tools\folderScannerV0.4.ps1"
}
or
function Start-Scanner {
$startArgs = #{
FilePath = "$PSHOME\powershell.exe"
ArgumentList = '-File', "`"$HOME\Desktop\BoB Tools\folderScannerV0.4.ps1`""
WorkingDirectory = "$HOME\Desktop\BoB Tools"
NoNewWindow = $true
Wait = $true
}
Start-Process #startArgs
}
You can just use dot-sourcing for this:
function run-scanner { . 'C:\Users\me\Desktop\BoB Tools\folderScannerV0.4.ps1' }

Azure Function in PowerShell to untar file

I am trying to convert some a number of files compressed into a .tar.gz archive into a single file. To do so I need to first untar the file.
I have a copy of 7z.exe loaded into the directory, and calling the command locally works
.\7z.exe x *.tar.gz
I've uploaded the exe into the wwwroot/poshUntar directory alongside the run.ps1 file that gets executed, and using the online editor I can execute the powershell script. I would of course expect my function to fail generally since I'm not providing the variable values but I would not expect it to error about finding the 7z.exe file
.\7z.exe : The term '.\7z.exe' is not recognized as the name of a cmdlet,
function, script file, or operable program. Check the spelling of the name, or
if a path was included, verify that the path is correct and try again.
At D:\home\site\wwwroot\poshUntar\run.ps1:10 char:1
+ .\7z.exe x *.tar -o logs
+ ~~~~~~~~
+ CategoryInfo : ObjectNotFound: (.\7z.exe:String) [], CommandNot
FoundException
+ FullyQualifiedErrorId : CommandNotFoundException
What is the correct way to invoke an executable inside a PowerShell Azure Function?
I believe that you also need to upload 7z.dll into the wwwroot directory.
Could you try using the following code-segment in your script?
Set-Location D:\home\site\wwwroot\poshUntar
.\7z.exe x *.tar.gz
.\7z.exe x *.tar -ologs

The term 'X' is not recognized as the name of a cmdlet

I found this script that will loop through .csv files and combine them into one Excel worksheet. I then created a second script to call this one with the following:
echo "Combining .csv files into Excel workbook"
C:\PowerShell\ConvertCSVtoExcel.ps1
Get-ChildItem *.csv | ConvertCSV-ToExcel -output ePortalMontlyReport.xlsx
echo " "
But when I try to run the script, I am getting the following error:
ConvertCSV-ToExcel : The term 'ConvertCSV-ToExcel' is not recognized as the name
of a cmdlet, function, script file, or operable program. Check the spelling of
the name, or if a path was included, verify that the path is correct and try
again.
At C:\PowerShell\Merge.ps1:3 char:23
+ Get-ChildItem *.csv | ConvertCSV-ToExcel -output ePortalMontlyReport. ...
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (ConvertCSV-ToExcel:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Any suggestions on how to resolve this?
You need to dot-source the .ps1 file to get the functions in it imported into your session.
. C:\PowerShell\ConvertCSVtoExcel.ps1

Path SQLSERVER:\7za.exe does not exist?

I have the following code in a powershell script. And I have file 7za.exe in the same directory of the script.
param($sql)
$temp = [System.IO.Path]::GetTempFileName()
Invoke-Sqlcmd -ServerInstance sqlserver1 $sql | ConvertTo-Csv > $temp
.\7za.exe a '$temp.zip' '$temp'
However, it got the following error. What's the right approach to execute an executable in the same folder right after invoke-sqlcmd?
SQL Server PowerShell provider error: Path SQLSERVER:\7za.exe does not exist. Please specify a valid path.
+ CategoryInfo : OperationStopped: (:) [], GenericProviderException
+ FullyQualifiedErrorId : Microsoft.SqlServer.Management.PowerShell.GenericProviderException
+ PSComputerName : localhost
If you look at the path in the error message, it is "SQLSERVER:\7za.exe" -- so the current working directory for the instance of PowerShell running this script (which you can get using the automatic variable $pwd) is SQLSERVER:\, which is the PSDrive created by the SQL module\snap-in that must be loaded to run the Invoke-SqlCmd cmdlet.
PowerShell scripts do NOT use their current location as the current working directory by default. In PowerShell version 3 and later, however, you can get the script's directory using the automatic variable $PSScriptRoot. In earlier versions, you can generate $PSScriptRoot yourself with:
$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Definition
Then you could use this variable in your script like so:
& (Join-Path $PSScriptRoot '7za.exe') "$temp.zip" "$temp"
Note that I used double quotes around the $temp variable, so that PowerShell would automatically expand the variable into the correct name.
#jbsmith is right about what path to use. Contributing to this issue is that the SQLPS module changes the current directory to SQLSERVER: when it is imported.

Running program from fileshare in powershell

What I need to do is execute a program on a remote fileshare inside powershell. An example path would be:
\mycompany\filesharename\folder\program.exe
This program takes a command line arguement, a string, and decrypts it. Problem is I need to decrypt and encrypt literally thousands of lines from different files on different computers. Doing it one at a time through that thing is driving me mad. I've started out with this:
clear-host
([string]$step='this')
$value = Invoke-Command '\\mycompany\fileshare\folder\software\program.exe' $step
write-host $value
This is throwing an error:
The term '\\mycompany\fileshare\folder\software\program.exe' is not re
cognized as the name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is correct and try
again.
At C:\Users\Me\Documents\Scripts\test.ps1:3 char:77
+ $value = \\mycompany\fileshare\folder\software\program.exe <<<< $st
ep
+ CategoryInfo : ObjectNotFound: (\\mycompany\fileshare...\program.exe:String
) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Eventually the plan is to code a gui, have the script grab the strings I need from the files themselves, and print them inside a local folder. Right now I need to figure out how the heck to use that progam inside my script. Any help?
Use Invoke-Expression instead of Invoke-Command:
$step='this'
$value = Invoke-Expression "\\mycompany\fileshare\folder\software\program.exe $step"
write-host $value