I have a terraform aws_imagebuilder_component component which creates several directories:
resource "aws_imagebuilder_component" "install_services" {
data = <<-EOT
phases:
- name: build
steps:
- action: ExecutePowerShell
inputs:
commands:
- New-Item -Path 'C:\Downloads\services' -ItemType Directory
- New-Item -Path 'C:\Downloads\service_install_scripts' -ItemType Directory
- New-Item -Path 'C:\temp' -ItemType Directory
- New-Item -Path 'C:\services' -ItemType Directory
- New-Item -Path 'C:\georgiTemp' -ItemType Directory
name: create-needed-folders
- other steps here...
"schemaVersion": 1
EOT
name = "install-services"
description = "Installs needed services"
platform = "Windows"
version = "0.0.16"
}
The image builds successfully with the above component. However, when I use the image on a EC2 instance, the C:\temp folder does not exist. The rest of the above locations do exist.
What am I missing here?
Related
I need to batch copy a sort of file extensions from subfolders to specific folders for each location.
All folders have a 6 digit number
let's say folder Rood folder: BATCH
Subfolder 1: 000000
Subfolder 2: 111111
despite their extensions, most files have the name as the subfolder but some of them may have extra alphanumeric characters, therefore the script should grab only the ones that are not larger than 6 digits.
Example Subfolder1: 000000.pdf 000000.eps the script would need to grab all pdf within subfolders and export them to a PDF exclusive new folder, and the same would apply for eps files.
I know nothing about powershell but I know that something like this would work for an specific subfolder but I'm still missing the parts where it distributes them to a new PDFONLY and EPSONLY folders and the fact the I want to apply this to all the folders whiting the root folder.
Get-ChildItem -Path "C:\BATCH\*" -Include *.pdf,*.eps -Recurse | Copy-Item -Destination D:\
You can use Group-Object to group all the files by their extension and then loop over each group of objects, create a new folder with the desired name and lastly copy all objects of each group to their folders.
$target = 'D:\' # Set destination here
Get-ChildItem -Path C:\BATCH\* -Include *.py, *.ps1 -Recurse |
Group-Object Extension | ForEach-Object {
# Example of `$folderName` would be `PDF ONLY`
$folderName = '{0} ONLY' -f $_.Name.TrimStart('.').ToUpper()
$destination = Join-Path $target -ChildPath $folderName
# If the `$destination` folder doesn't exist
if(-not (Test-Path $destination)) {
# Create it
$null = New-Item $destination -ItemType Directory
}
Copy-Item -LiteralPath $_.Group.FullName -Destination $destination
}
Similar to Santiago's answer but with an extra filter and without grouping you can do this:
$destination = 'X:\somewhere'
Get-ChildItem -Path "C:\BATCH" -Include '*.pdf','*.eps' -File -Recurse |
Where-Object {$_.BaseName -match '^\d{6}$' } | # filter files with a BaseName of just 6 digits
ForEach-Object {
$targetPath = Join-Path -Path $destination -ChildPath ('{0}ONLY' -f $_.Extension.TrimStart(".").ToUpper())
# make sure the target path exists
# for directories, using the -Force switch either creates a new folder
# or returns the DirectoryInfo object of an existing folder.
$null = New-Item -Path $targetPath -ItemType Directory -Force
$_ | Copy-Item -Destination $targetPath
}
I am trying to clean up and group files in a directory by creating subdirectories and then copying the files into the new directories.
Example:
test01.a.jpg
test01.a.txt
test01.b.bak
test01.b.txt
test02.a.txt
test02.a.jpg
test02.a.bak
test03.a.txt
test03.a.bak
test03.b.txt
I wish to create subdirectories like test01, test02, test03 and ideally copy the relevant files over. All groups will have a txt file but more or less of the others.
To create the directories I have got as far as
gci -file *.txt | New-Item -ItemType directory $_.name
which doesn't work as expected.
If your files have names like that, you can simply split the filename on the dot and take only the first part as new folder name.
Then test if a subfolder like that already exists (if not create it) and move the file.
Something like this
$sourcePath = 'D:\Test' # put the real path to the files here
# if you want only the files with extension .txt, use filter '*.*.txt'
(Get-ChildItem -Path $sourcePath -File -Filter '*.*.*') | ForEach-Object {
# use the first part of the file name for subdirectory name
$destinationPath = Join-Path -Path $sourcePath -ChildPath $_.Name.Split(".")[0]
if (!(Test-Path -Path $destinationPath -PathType Container)) {
# if a subdirectory with that name does not already exist, create it
$null = New-Item -Path $destinationPath -ItemType Directory
}
# now move the file to that (new) destination folder
$_ | Move-Item -Destination $destinationPath
}
Actually, algorithm is simple (we don't need to previously compare names of files. All we need is just use a $_.BaseName property)
<#Creating folders and moving files using BaseName property #>
gci *.txt | % { new-item -ItemType Directory -Path ($_.Directory.ToString() + "\" + $_.BaseName.ToString())}
gci -file | % { Move-item $_.Fullname ($_.Directory.ToString() + "\" + $_.BaseName.ToString())}
I have Several zip files that Contain multiple filetypes. The ONLY ones I am interested in are the .txt files. I need to extract the .txt files only and place them in a folder of their own, ignoring all other file types in the zips files.
All the zip files are in the same folder.
Example
-foo.zip
--1.aaa
--2.bbb
--3.ccc
--4.txt
-foo2.zip
--5.aaa
--6.bbb
--7.ccc
--8.txt
I want to have 4.txt and 8.txt extracted to another folder. I can't for the life of my figure it out and spent ages looking, googling and trying. Even managing to delete to zips once in a while :-)
Thanks in advance
Use the ZipArchive type to programmatically inspect the archive before extracting:
Add-Type -AssemblyName System.IO.Compression
$destination = "C:\destination\folder"
# Locate zip file
$zipFile = Get-Item C:\path\to\file.zip
# Open a read-only file stream
$zipFileStream = $zipFile.OpenRead()
# Instantiate ZipArchive
$zipArchive = [System.IO.Compression.ZipArchive]::new($zipFileStream)
# Iterate over all entries and pick the ones you like
foreach($entry in $zipArchive.Entries){
if($entry.Name -like '*.txt'){
# Create new file on disk, open writable stream
$targetFileStream = $(
New-Item -Path $destination -Name $entry.Name -ItemType File
).OpenWrite()
# Open stream to compressed file, copy to new file stream
$entryStream = $entry.Open()
$entryStream.BaseStream.CopyTo($targetFileStream)
# Clean up
$targetFileStream,$entryStream |ForEach-Object Dispose
}
}
# Clean up
$zipArchive,$zipFileStream |ForEach-Object Dispose
Repeat for each zip file.
Note that the code above has very minimal error-handling, and is to be read as an example
Try this:
Set-Location "Extraction path"
#("full path of foo.zip","full path of foo2.zip") | ForEach {
& "Full path of 7z.exe" x '-i!*.txt' $_.FullName
}
Sets location to the path where files will be extracted.
Passes a array of zip files to for loop.
Exexute 7z command to extract only zip files.
Here is one approach:
Go through each .zip file in a folder.
Extract archive into separate folder.
Extract .txt file from folder.
Copy files into destination folder containing all .txt files. This will overwrite files if they already exist in the destination folder.
Cleanup extracted folders once finished.
Demo:
function Copy-ZipArchiveFiles {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[ValidateScript({
if (-not(Test-Path $_ -PathType Container))
{
throw "The source path $_ does not exist. Please enter a valid source path."
}
else
{
$true
}
})]
[string]$Path,
[Parameter(Mandatory=$true)]
[ValidateScript({
if ([string]::IsNullOrEmpty($_.Trim()))
{
throw "The Destination path is null or empty. Please enter a valid destination path."
}
else
{
$true
}
})]
[string]$Destination,
[Parameter(Mandatory=$false)]
[AllowNull()]
[AllowEmptyString()]
[AllowEmptyCollection()]
[string[]]$Include
)
# Create destination folder if it doesn't already exist
if (-not(Test-Path -Path $Destination -PathType Container))
{
try
{
New-Item -Path $Destination -ItemType Directory -ErrorAction Stop
}
catch
{
throw "The destination path $Destination is invalid. Please enter a valid destination path."
}
}
# Go through each .zip file
foreach ($zipFile in Get-ChildItem -Path $Path -Filter *.zip)
{
# Get folder name from zip file w/o .zip at the end
$zipFolder = Split-Path $zipFile -LeafBase
# Get full folder path
$folderPath = Join-Path -Path $Path -ChildPath $zipFolder
# Expand .zip file into folder if it doesn't exist
if (-not(Test-Path -Path $folderPath -PathType Container))
{
Expand-Archive -Path $zipFile.FullName -DestinationPath $folderPath
}
# Copy files into destination folder
foreach ($file in Get-ChildItem $folderPath -Include $Include -Recurse)
{
Copy-Item -Path $file.FullName -Destination $Destination
}
# Delete extracted folders
Remove-Item -Path $folderPath -Recurse -Force
}
}
Usage:
Copy-ZipArchiveFiles `
-Path "C:\path\to\zip\files" `
-Destination "C:\path\to\text\files" `
-Include "*.txt"
Note: Could also use this for multiple extension types as well by passing -Include *.txt, *.pdf. I also went a bit overboard in the parameter error checking, but I believe in writing robust code. Good habit to get into when writing your own cmdlets anyways :)
I want to do the following in PowerShell, but it seems like the curly brackets pose an issue.
Here's how I would do it in Bash:
mkdir -p /path/to/dir/{dir1,dir2,dir3...dir10}
This creates a parent directory, then several directories of which "dir" contains several subfolders.
This should work for you
New-Item -ItemType Directory C:\temp1\dir1,C:\temp1\dir2,C:\temp1\dir3
one more way
$dirs = 1..10
$dirs | % {
New-Item -ItemType Directory ( Join-Path -Path 'c:\temp\dir' -ChildPath ('dir' +$_ ) )
}
If you are after Directories 1 to 10 (or similar) - something like the following will work for you:
1..10 | ForEach {
New-Item -ItemType Directory -Path ("C:\Temp\Dir" + $_)
}
If you are looking to create an array of named subfolders - the something like the following will work (including the ability to create sub-sub-folders:
$subFolderNameArray = #(
"folder1",
"Folder2",
"Folder1\Subfolder3"
)
ForEach ($subFolderName in $subFolderNameArray) {
New-Item -ItemType Directory -Path ("C:\Temp\" + $subFolderName)
}
This relies on creating the folders in teh correct order (you must create parent folders before subfolders). If you want to do things out of order (or can't guarantee the starting array will be tree-wise) - you can use the force switch:
New-Item -ItemType Directory -Path ("C:\Temp\Folder\Subfolder") -Force
I have a folder that contains many rar or zip files. I want put similar files (based on part word in filename if exist) to own folder.by default in parent folder there isn't any folder.maybe in future another part of file added to parent directory so this time it should move file to his own folder instead of create new folder.
For example assume the files are:
Visual_Studio_2015.part1.rar
Visual_Studio_2015.part2.rar
Visual_Studio_2015.part3.rar
SQL-Server-Enterprise-2016-SP1.part1.rar
SQL-Server-Enterprise-2016-SP1.part2.rar
VSCodeSetup x64 1.29.1.rar
Microsoft.Visual.Studio.Ultimate.2012.update.3.part1.rar
Microsoft.Visual.Studio.Ultimate.2012.update.3.part12.rar
after moving,become looks like this:
Parent Directory
├───Visual_Studio_2015
│ ├───Visual_Studio_2015.part1.rar
│ ├───Visual_Studio_2015.part2.rar
│ ├───Visual_Studio_2015.part3.rar
├───VSCodeSetup x64 1.29.1
│ ├───VSCodeSetup x64 1.29.1.rar
├───SQL-Server-Enterprise-2016-SP1
│ ├───SQL-Server-Enterprise-2016-SP1.part1.rar
│ ├───SQL-Server-Enterprise-2016-SP1.part2.rar
├───Microsoft.Visual.Studio.Ultimate.2012.update.3
│ ├───Microsoft.Visual.Studio.Ultimate.2012.update.3.part1.rar
│ ├───Microsoft.Visual.Studio.Ultimate.2012.update.3.part2.rar
i can't use any software or compiled programming language for this problem. sorry for weak English
update:
in powershell somthing like this:
Get-ChildItem -File |
Group-Object { $_.Name -replace '.part.*' } |
ForEach-Object {
$dir = New-Item -Type Directory -Name $_.Name
$_.Group | Move-Item -Destination $dir
}
can separating files that have part in filename but not work for without it, also i must mention that all filename end with .partX (X is a digit) if it is multi parted archives.
If all the files are in one root folder and have the naming convention you specify, then here is one way to move them into appropriate subfolders:
Get-Childitem -path "C:\Test" -File |
ForEach-Object {
if($_.Name -match "^(?<folder>.*)\.part\d+|(?<folder>.*)\.rar$") {
New-Item -Path "$($_.Directory)\$($matches.Folder)" -ItemType Directory -Force | Out-Null
Move-Item -Path $_.FullName -Destination "$($_.Directory)\$($matches.Folder)\$($_.Name)" -Force
}
}
Change the path in Get-Childitem as appropriate. Also, you can modify the paths for New-Item and Move-Item if you want them to be located somewhere else instead of as subfolders of the root directory.
Another way to do it would be this:
$parentFolder = '<THE PARENTFOLDER THAT HOLDS ALL .RAR AND .ZIP FILES>'
# Get all files inside the parent folder with extension '.rar' or '.zip'
# Because '-Filter' only accepts a single string, we need to use a 'Where-Object' clause.
# Another way would be to use the '-Include' parameter on Get-Childitem, but for that to work
# you must either also use '-Recurse' or append '\*' to the $parentfolder like this:
# Get-ChildItem -Path "$parentFolder\*" -File -Include *.rar, *.zip
Get-ChildItem -Path $parentFolder -File | Where-Object { $_.Extension -match '\.(rar|zip)$' } | ForEach-Object {
# create the name of the subfolder by removing the '.partX' from the basename if that exists
$subFolder = Join-Path -Path $parentFolder -ChildPath ($_.BaseName -replace '\.part\d+', '')
# create this subfolder if it does not already exist
if (!(Test-Path -Path $subFolder -PathType Container)) {
New-Item -Path $subFolder -ItemType Directory -Force | Out-Null
}
# move the file to the subfolder
$_ | Move-Item -Destination $subFolder
}