PowerShell New-Item Positional Parameter Oddities - powershell

Given the Microsoft documentation for PowerShell, I can see no reason why the following code should fail with the given error. Then again, PowerShell can fail when a script just gets too long. All the paths are double-quote strings.
##### ALGORITHM Take in keystore path, make a backup in an adjacent directory
$ksPath = $java_store_path.Substring(0, $java_store_path.LastIndexOf('\') + 1)
$backupPath = $ksPath + "backups"
New-Item $backupPath PowerShell -type directory -force
New-Item : A positional parameter cannot be found that accepts argument 'PowerShell'.
https://technet.microsoft.com/en-us/library/ee176914.aspx
New-Item c:\scripts\Windows PowerShell -type directory
If that's valid, mine should be too. I'm running on Server 2012 R2.

The example on that page is just plain wrong. It seems they meant to refer to the path C:\Scripts\WindowsPowerShell or they forgot to quote the directory with spaces in it.
So it should have been one of these:
New-Item c:\scripts\WindowsPowerShell -type directory
New-Item 'c:\scripts\Windows PowerShell' -type directory
New-Item "c:\scripts\Windows PowerShell" -type directory
Ask yourself, what would PowerShell alone have been referring to? What parameter would it have corresponded to?
Edit: as the commenters have pointed out, the example was supposed to show the nameSet parameters, where a separate -Path and -Name are specified, and purportedly PowerShell was supposed to be a value to the -Name parameter. That does look correct. The reason the example didn't work (and yours as well), is because the -Name parameter cannot be specified positionally, which you can see in the MSDN article I linked to below, and in the built-in help:
Type: String
Parameter Sets: nameSet
Aliases:
Required: True
Position: Named
Default value: None
Accept pipeline input: True (ByPropertyName)
Accept wildcard characters: False
In that case, their example should have been something like these:
New-Item c:\scripts\Windows -Name PowerShell -type directory
New-Item -Path c:\scripts\Windows -Name PowerShell -type directory
So reiterating, named parameters would have worked here, and would have avoided confusion.
Generally, you shouldn't be using positional parameters in scripts, unless they're extremely clear (and even then, I'd recommend avoiding).
Using named parameters would have made this easier to figure out. And tab-completion helps with filling in the parameter names and in completing paths (usually with proper quoting too).
I think you should change yours to:
New-Item -Path $backupPath -Type Directory -Force
And looking over that technet article, it's really not so good. The MSDN article on New-Item is better, and this is the information you should see when running Get-Help New-Item as well.
Side question:
Then again, PowerShell can fail when a script just gets too long.
What?

Related

Need PowerShell alias for cargo commands [duplicate]

I want to create an alias in Windows PowerShell to delete multiple folders from the command line.
To remove more than one item I call:
Remove-Item '.\Documents\*\Bin\' ,'.\Documents\*\Inter\' -Force -Recurse
I have tried to create the alias like this:
New-Alias -Name 'Clean-RCD' Remove-Item '.\Documents\*\Bin\' ,'.\Documents\*\Inter\' -Force -Recurse
Output:
New-Alias: A positional parameter cannot be found that accepts argument 'System.Object[]'.
Any idea how to define this alias correctly?
Unlike in bash, aliases in PowerShell are strict 1-to-1 command name mappings - no extra parameter arguments allowed.
You'll want to create a function instead:
function Clean-RCD {
Remove-Item -Path '~\Documents\*\Bin', '~\Documents\*\Inter\' -Force -Recurse
}
Use of ~ (which resolves to your home folder) over . is intentional - this way it'll still work if you've navigated to a different path

How to transfer files (folders) from one server to another with PowerShell?

I just started working with PowerShell and I want to know how to transfer files between a local server and a remote server.
Currently I do not have Administrator access to either server (I know I'm going to need it), how do I target the Get cmdlt? Do I use a URL?
It's vital that you get up to speed on the topic. Take the time to jump over to MS Virtual academy
or MS Channel9
or YouTube and take a quick training course on the topic.
What you are asking for is covered in them as well as in the PowerShell Help files, which include examples on how to do this.
# get function / cmdlet details
(Get-Command -Name Copy-Item).Parameters
Get-help -Name Copy-Item -Full
Get-help -Name Copy-Item -Online
Get-help -Name Copy-Item -Examples
NAME
Copy-Item
SYNOPSIS
Copies an item from one location to another.
Example 1: Copy a file to the specified directory
PS C:\>Copy-Item "C:\Wabash\Logfiles\mar1604.log.txt" -Destination "C:\Presentation"
This command copies the mar1604.log.txt file to the C:\Presentation directory. The command does not delete the original
file.
Example 2: Copy the contents of a directory to another directory
PS C:\>Copy-Item "C:\Logfiles" -Destination "C:\Drawings" -Recurse
This command copies the entire contents of the Logfiles directory into the Drawings directory. If the LogFiles directory contains files
in
subdirectories, those subdirectories will be copied with their file trees intact. The Container parameter is set to true by default.
This preserves
# Get parameter that accepts pipeline input
Get-Help Copy-Item -Parameter * |
Where-Object {$_.pipelineInput -match 'true'} |
Select *
# Get cmdlet / function parameter aliases
(Get-Command Copy-Item).Parameters.Values |
where aliases |
select Name, Aliases | Out-GridView -PassThru -Title 'Alias results for a given cmdlet or function.'

mkdir vs New-Item , is it the same cmdlets?

I found that there are two different cmdlets : New-Item and mkdir, firstly I was thinking that mkdir is one of aliases of New-Item, but it is not:
Try to get aliases of it, it is md for mkdir and ni for New-Item :
So I am a little bit confused, what the difference between that cmdlets, because powershell reference gives me almost the same pages: mkdir, New-Item
But New-Item is in Microsoft.PowerShell.Management and mkdir in Microsoft.PowerShell.Core , but the do the same(or not?)! Why there are two same cmdlets in powershell?
New-Item is a cmdlet, defined in an assembly, which creates new objects - both files and directories. mkdir is a function which calls New-Item to create directories specifically. It is provided for convenience to shell users who are familiar with Windows CMD or unix shell command mkdir
To see the definition of mkdir use Get-Content Function:\mkdir. You can see that it calls New-Item under the covers, after some parameter and pipeline management. Using PS 5.0:
$wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('New-Item', [System.Management.Automation.CommandTypes]::Cmdlet)
$scriptCmd = {& $wrappedCmd -Type Directory #PSBoundParameters }
Both of the following commands will create a new directory named foo in the root of C:\. The second form is familiar to people coming from other shells (and shorter to type). The first form is idiomatic PowerShell.
PS> New-Item -Path C:\foo -Type Directory
PS> mkdir C:\foo
Because mkdir hardcodes the -Type Directory parameter, it can only be used to create directories. There is no equivalent mkfile built-in function. To create files, use New-Item -Type File, or another cmdlet such as Out-File.

path as parameter powershell

I have problem with path. I need to copy all files from directory I add as 1st parameter in Powershell command.
Now I have:
Copy-Item -Path "$args[0]/" -Filter*.*
So it will copy to location I am now (and it's ok, I don't want other location) but it doesn't copy anything. Please help.
Pretty sure the issue is that the 0 element in $args is not expanding in the string creating an invalid path. Wrap the variable in $() to allow it to expand inside a double quoted string. Else you would end up trying to copy the folder C:\TEST[0]/ which obviously is not correct.
Copy-Item -Path "$($args[0])/" -Filter *.* -Recurse
Not yet sure why you have a forward slash in there since Windows pathing uses backslashes.
function Copy-Something(){
test-Path "$($args[0])/"
test-path "$($args[0])"
}
Copy-Something C:\temp
With what little you have provided the output shows that it might be redundant to have the slash there. Would also recommend calling Test-Path on the argument anyway as it might have caught this for you.
True
True
From Question Comment
You are looking for the -Recurse parameter if you also want folder contents.
From Answer Comment
If you want the contents and not the folder you should be able to do something like this:
Copy-Item -Path "$($args[0])\*" -Filter *.* -Recurse
When in doubt, Get-Help Command.
PS C:\> Get-Help Copy-Item -ShowWindow
-------------------------- EXAMPLE 3 --------------------------
This command copies the contents of the C:\Logfiles directory
to the C:\Drawings\Logs directory. It creates the \Logs
subdirectory if it does not already exist.
Windows PowerShell
PS C:\> Copy-Item C:\Logfiles -Destination C:\Drawings\Logs -Recurse

Powershell New-Item: How to Accept Confirmation Automatically

I'm trying to create a new directory on a network drive using a powershell script but it keeps prompting me
"Confirm: Are you sure you want to perform this action ...."
Is there a way to override this so it doesn't ask me since I'm running this script from a web interface.
Here is my call:
New-Item $rollbackDirectory -type Directory -Force
It does the same thing, with or without the -Force parameter
I've also tried this format with no luck
New-Item -name $rollbackName -itemtype directory -path $rollbackdrive -Debug -Force
-confirm need only be specified when you want the cmdlet to prompt you for confirmation. Whether the cmdlet by itself would prompt for confirmation or not depends on the developer of the cmdlet who can set a high, medium, low for the cmdlet based on its effect. Based on the value of $ConfirmPreference you will get the confirmation automatically for a cmdlet. The default value for $ConfirmPreference is high and the level set for New-Item is medium. So if the New-Item is prompting for confirmation, the $ConfirmPreference value must have been changed to medium or low.
Change it using $ConfirmPreference="high" or even $ConfirmPreference="none" to make New-Item not prompt, or your solution of -confirm:$false works as well by overriding the $ConfirmPreference.
Explained perfectly here: http://blogs.msdn.com/b/powershell/archive/2006/12/15/confirmpreference.aspx
Hope this clears it up.
I ended up trying this (even though I read on another SO post that it is not correct):
New-Item $rollbackDirectory -type Directory -Force -Confirm:$false
And it worked! Hope this helps others with the same issue