Create directory and file in same command using PowerShell - powershell

I try to create a folder and a file in one PowerShell command:
I tried:
New-Item hello\test\ (New-Item hello\test\file.txt -type file) -type directory -Force
and
New-Item file.txt (New-Item hello\test\ -type direcotry) -type file -Force
But both don't seem to work as expected.
What I want to achieve is one command to create hello\test\file.txt

Just provide the filepath you want, including the directory, and it will work:
New-Item -Path '.\hello\test\file.txt' -ItemType File -Force

If you want to put the c.txt file in the b folder of the a folder, do so. ni a/b/c.text -Force
If you want to put two files y.txt and z.hml in x folder ni x/y.txt, x/z.html -Force

I created the directory and the file with the following code.
New-Item hello\test -type Directory ; Start-Sleep -Milliseconds 500 ; New-Item hello\test\file.txt

It's not case-sensitive in powershell command, so the most convenient and fastest way to create file would be - > new-item -path . -name 'newfile.txt' -itemtype 'file'
And for new directory, it's the same as in Linux-terminal -> mkdir newdirectory

Related

New-Item Creating Extension-less File Instead of Directory

I am trying to automate log copying between multiple remote computers and a shared folder on said remote computer's network. The script is working fine for the most part, but occasionally (I cannot figure out why) an extension-less file is created instead of a file folder, and the logs' contents are copied into it. When I edit it with notepad++, I can see the contents of the log file I was trying to copy into the folder.
I have this script on multiple remote computers, which all transfer the logs to the same shared network folder (but to different sub-directories). On each machine, I have the script executing at the same time (3:00 AM) via a Windows Task.
$sharedFolderPath = "\\xXxXxXx\xXxXxX\xXxXx\"
$yesterdaysDate = (get-date).AddDays(-1).ToString("yyyy-MM-dd")
#Create Daily Directories
if (-Not(Test-Path "$sharedFolderPath$yesterdaysDate")) {
new-item -Path "$sharedFolderPath" -Name $yesterdaysDate -ItemType directory
new-item -Path "$sharedFolderPath\$yesterdaysDate" -Name "BMS" -ItemType directory
new-item -Path "$sharedFolderPath\$yesterdaysDate" -Name "BPS" -ItemType directory
new-item -Path "$sharedFolderPath\$yesterdaysDate" -Name "DDS" -ItemType directory
new-item -Path "$sharedFolderPath\$yesterdaysDate" -Name "POS" -ItemType directory
new-item -Path "$sharedFolderPath\$yesterdaysDate" -Name "SCAPPS" -ItemType directory
new-item -Path "$sharedFolderPath\$yesterdaysDate" -Name "TRCS" -ItemType directory
new-item -Path "$sharedFolderPath\$yesterdaysDate" -Name "Optitrack" -ItemType directory
new-item -Path "$sharedFolderPath\$yesterDaysDate\DDS" -Name "Layer Files" -ItemType directory
new-item -Path "$sharedFolderPath\$yesterDaysDate\TRCS" -Name "Catch-All" -ItemType directory
}
Working correctly, I'd expect a folder called "2019-06-30" (or whatever yesterday's date is) to be made, with folders BMS, BPS, DDS, Optitrack, POS, SCAPPS, and TRCS inside, that have their respective logs stored in them.
After the code I provided, I've added these lines:
#fail-safes
new-item -Path "$sharedFolderPath\$yesterdaysDate" -Name "DDS" -ItemType directory -Force
new-item -Path "$sharedFolderPath\$yesterdaysDate" -Name "BMS" -ItemType directory -Force
Which has seemed to fix the problem. However, for the sake of being robust, I would like to know what's causing this so that I can fix it properly.

How to create symbolic link for non-existing folder?

I'd like to create link to a folder on desktop of remote computer. I do not have permissions to execute scripts on that computer, but I can copy files to that computer.
My idea was to create link to folder on local computer and then copy the link to remote computer.
But, I am getting error New-Item : Cannot find path 'C:\SomeFolder' because it
does not exist.
Here is my command:
New-Item -Path "c:\Users\pocherka\Desktop\link" -ItemType SymbolicLink -Value "c:\SomeFolder" -Force
Any ideas for workaround?
Try adding the -force parameter:
New-Item -Path "c:\Users\pocherka\Desktop\link" -ItemType SymbolicLink -Value "c:\SomeFolder" -force
You can do using mklink also . Make sure that the destination folder is available . You can use the Test-Path to check that :
$destination = "c:\SomeFolder"
if(Test-Path $destination)
{
cmd /c mklink "c:\Users\pocherka\Desktop\link" $destination
# OR you can use the new-item also. Just commented in the below line
# New-Item -Path "c:\Users\pocherka\Desktop\link" -ItemType SymbolicLink -Value $destination
}
else
{
New-Item $destination -ItemType Directory -Force
cmd /c mklink "c:\Users\pocherka\Desktop\link" $destination
}
Hope it helps

Piping out to "New-Items" in PowerShell

I'm trying to output to a file that is created on the fly, but I can't seem to get either to work. Here's that portion of my code-
New-Item -Path $LogPath -Name $InfoLog -Type File -Force
New-Item -Path $LogPath -Name $ErrorLog -Type File -Force
"Script started at: $DateStamp_${TimeStamp}" | $InfoLog
I've also tried just ">>" instead of the pipe. The script runs fine, it just doesn't pipe the output into the file. Instead it pipes it out to a a files called "0" in the directory the script ran from.
Three things.
First, New-Item outputs the item it creates. So unless you do something with the output objects, New-Item will output the new file items to the pipeline. So I think you might want to say:
New-Item -Path $LogPath -Name $InfoLog -Type File -Force | Out-Null
Second, since you're not specifying the path to the file you want to write to, PowerShell will assume the current location.
Finally, if you want to write output to a log file, you probably want to use Out-File. Perhaps something like this:
$infoLogPath = Join-Path $LogPath $InfoLog
"Script started at: $DateStamp_${TimeStamp}" | Out-File $infoLogPath
Join-Path combines the directory and filename into a fully-qualified path name.

Combine Two Commands in PowerShell

I know there has to be a simple answer but how can I run both my commands at the same time? I can run one line to create the new directory and name it, then copy items from one folder to another. But how do I create the folder and copy the files into that created folder?
#Creates new directory and names it current date and time.
New-Item C:\ -type directory -Name ("$(Get-Date -f ddMMyyyy_hhmm)")
#Copies Data from one directory to another, works good.
Copy-Item C:\test\* C:\test2
Thanks for your help.
You could use the FullName property of the object that New-Item returns as the destination for another command. i.e.
Copy-Item C:\somefolder\* -Destination (New-Item -type Directory -name (Get-Date -f ddMMyyyy_hhmmss)).FullName

Should Copy-Item create the destination directory structure?

I'm trying to copy a file to a new location, maintaining directory structure.
$source = "c:\some\path\to\a\file.txt"
destination = "c:\a\more\different\path\to\the\file.txt"
Copy-Item $source $destination -Force -Recurse
But I get a DirectoryNotFoundException:
Copy-Item : Could not find a part of the path 'c:\a\more\different\path\to\the\file.txt'
The -recurse option only creates a destination folder structure if the source is a directory. When the source is a file, Copy-Item expects the destination to be a file or directory that already exists. Here are a couple ways you can work around that.
Option 1: Copy directories instead of files
$source = "c:\some\path\to\a\dir"; $destination = "c:\a\different\dir"
# No -force is required here, -recurse alone will do
Copy-Item $source $destination -Recurse
Option 2: 'Touch' the file first and then overwrite it
$source = "c:\some\path\to\a\file.txt"; $destination = "c:\a\different\file.txt"
# Create the folder structure and empty destination file, similar to
# the Unix 'touch' command
New-Item -ItemType File -Path $destination -Force
Copy-Item $source $destination -Force
Alternatively, with PS3.0 onwards, you can simply use the New-Item to create the target folder directly, without having to create a "dummy" file, e.g. ...
New-Item -Type dir \\target\1\2\3\4\5
...will happily create the \\target\1\2\3\4\5 structure irrespective of how much of it already exists.
Here's a oneliner to do this. Split-Path retrieves the parent folder, New-Item creates it and then Copy-Item copies the file. Please note that the destination file will have the same filename as the source file. Also, this won't work if you need to copy multiple files to the same folder as with the second file you'll get An item with the specified name <destination direcory name> already exists error.
Copy-Item $source -Destination (New-Item -Path (Split-Path -Path $destination) -Type Directory)
I had files in a single folder in Windows 7 that I wanted to rename and copy to nonexistent folders.
I used the following PowerShell script, which defines a Copy-New-Item function as a wrapper for the Test-Item, New-Item, and Copy-Item cmdlets:
function Copy-New-Item {
$SourceFilePath = $args[0]
$DestinationFilePath = $args[1]
If (-not (Test-Path $DestinationFilePath)) {
New-Item -ItemType File -Path $DestinationFilePath -Force
}
Copy-Item -Path $SourceFilePath -Destination $DestinationFilePath
}
Copy-New-Item schema_mml3_mathml3_rnc schema\mml3\mathml3.rnc
# More of the same...
Copy-New-Item schema_svg11_svg_animation_rnc schema\svg11\svg-animation.rnc
# More of the same...
Copy-New-Item schema_html5_assertions_sch schema\html5\assertions.sch
# More of the same...
(Note that, in this case, the source file names have no file extension.)
If the destination file path does not exist, the function creates an empty file in that path, forcing the creation of any nonexistent directories in the file path. (If Copy-Item can do all that by itself, I could not see how to do it from the documentation.)
It is coming late, but as I stumbled upon this question looking for a solution to a similar problem, the cleanest one I found elsewhere is using robocopy instead of Copy-Item. I needed to copy the whole file structure together with the files, that's easily achieved via
robocopy "sourcefolder" "destinationfolder" "file.txt" /s
Detail about robocopy: https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/robocopy
None of the current answers worked for me to fix the Could not find a part of the path error raised by Copy-Item. After some research and testing, I discovered this error can be raised if the Destination path goes over the 260 character Windows path length limit.
What I mean by that is: if you supply a path to the Destination argument of Copy-Item and any of the files you are copying would exceed the 260 character limit when copied to the Destination folder, Copy-Item will raise the Could not find a part of the path error.
The fix is to shorten your Destination path, or to shorten/flatten the folder structure in the source directory that you are trying to copy.
May be Helpfull:
$source = 'c:\some\path\to\a\file.txt'
$dest = 'c:\a\more\different\path\to\the\file.txt'
$dest_dir = 'c:\a\more\different\path\to\the\'
[System.IO.Directory]::CreateDirectory($dest_dir);
if(-not [System.IO.File]::Exists($dest))
{
[System.IO.File]::Copy($source,$dest);
}
I have been digging around and found a lot of solutions to this issue, all being some alteration not just a straight copy-item command. Grant it some of these questions predate PS 3.0 so the answers are not wrong but using powershell 3.0 I was finally able to accomplish this using the -Container switch for copy-item.
Copy-Item $from $to -Recurse -Container
this was the test i ran, no errors and destination folder represented the same folder structure.
New-Item -ItemType dir -Name test_copy
New-Item -ItemType dir -Name test_copy\folder1
New-Item -ItemType file -Name test_copy\folder1\test.txt
#NOTE: with no \ at the end of the destination the file is created in the root of the destination, does not create the folder1 container
#Copy-Item D:\tmp\test_copy\* D:\tmp\test_copy2 -Recurse -Container
#if the destination does not exists this created the matching folder structure and file with no errors
Copy-Item D:\tmp\test_copy\* D:\tmp\test_copy2\ -Recurse -Container