Several folders into a zip with PowerShell - powershell

I have several folders dir_01, dir_02, dir_03 that I want to backup in a zip file, say, backup.zip. This has to be saved in a folder with today's date. I need to get a .bat file to do the job; no additional third party executables allowed.
Here I found how to create a folder with today's date, but I am having problems to pass $destination to -DestinationPath. I created a .bat that calls PowerShell. Code giving me problems:
powershell.exe $destination = New-Item -Path 'C:\path\to\destionation' -ItemType Directory -Name ("$(Get-Date -f yyyy-MM-dd)")
powershell.exe -nologo -noprofile -command Compress-Archive -Path 'C:\path\dir_01', 'C:\path\dir_02', 'C:\path\dir_03' -DestinationPath $destination\backup.zip -Force
The error message is the following:
New-Object : Exception calling ".ctor" with "2" argument(s): "Access to the path 'C:\backup.zip' is denied."
At
C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Archive\Microsoft.PowerShell.Archive.psm1:729
char:30
+ ... ileStream = New-Object -TypeName System.IO.FileStream -ArgumentList $ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvocationException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
However, the code works if I hard-code the path to destination, like this:
powershell.exe -nologo -noprofile -command Compress-Archive -Path 'C:\path\dir_01', 'C:\path\dir_02', 'C:\path\dir_03' -DestinationPath 'C:\whole\path\backup.zip' -Force
But doing so, I'm unable to save backup.zip in today's folder.
Question: How can I save backup.zip in the folder that I created with today's date?

You can perform both commands in the same PowerShell session by separating them with a semicolon.
powershell.exe $destination = New-Item -Path 'C:\path\to\destionation' -ItemType Directory -Name ("$(Get-Date -f yyyy-MM-dd)"); Compress-Archive -Path 'C:\path\dir_01', 'C:\path\dir_02', 'C:\path\dir_03' -DestinationPath $destination\backup.zip -Force
That will launch PowerShell and have it create the folder and then zip things into it in the same session, rather than create a session, in that session create a folder, close the session, start a new PowerShell session, zip things up, close the second session.

Related

SSIS Execute process task and Powershell for expand files

I am trying to execute an powershell script (the script is unzipping the folders in source path with the same name as the .zip folder)
powershell script:
param([string] $sourcepath)
$sourcepath = "F:\Worflow\"
function unzip ($file) {
$dirname = $sourcepath +(Get-Item $file).Basename
New-Item -Force -ItemType directory -Path $dirname
expand-archive -path $file -DestinationPath $dirname -F
}
$zipFiles = Get-LongChildItem -Path $sourcepath -Recurse | Where-Object {$_.Name -like "*.zip"}
foreach($file in $zipFiles)
{
unzip ($file)
}
SSIS Executue process task Arguments:
"-ExecutionPolicy Unrestricted -File C:\MyDataFiles\Unzip.ps1"
The powershell script works fine when ran in PS instance. But the code is failing from SSIS task with an error :
Get-LongChildItem : The term 'Get-LongChildItem' 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:\MyDataFiles\Unzip.ps1:17 char:13
+ $zipFiles = Get-LongChildItem -Path $sourcepath -Recurse | Where-Obj ...
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-LongChildItem:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Anyhelp would be appreciated. The goal is using powershell to zip and unzip folders or files.
Looks like you are attempting to use a command without first loading the module.
Get-LongChildItem is part of the open source module PSAlphaFS
Try importing the module in your script first.
Of course it needs to be installed too. ;)

Unable to unzip using powershell

I am trying to unzip using powershell with below command --
powershell.exe -nologo -noprofile -command "& { Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::ExtractToDirectory('E:\test.zip', 'E:\'); }"
I get below log
'E:\test1.txt'
already exists."
At line:1 char:53
+ & { Add-Type -A 'System.IO.Compression.FileSystem';
[IO.Compression.ZipFile]::Ex ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : IOException
===============================
I don't see the archive being unzipped.
Update 1
E:\test1.txt already exists at the destination. How to change the command to overwrite files.
Update 2
The version of powershell available doesn't support Expand-Archive
You can't overwrite files with that method. You need to read the documentation for ZipFileExtensions.ExtractToDirectory(source, destinationDirectoryName):
This method creates the directory specified by
destinationDirectoryName. If the destination directory already exists, this method does not overwrite it; it throws an IOException
exception. The method also creates subdirectories that reflect the
hierarchy in the zip archive. If an error occurs during extraction,
the archive remains partially extracted. Each extracted file has the
same relative path to the directory specified by
destinationDirectoryName as its source entry has to the root of the archive.
If you want to use ZipFileExtensions.ExtractToDirectory() with overwrite, you'll need to extract the files to a temporary folder and then copy/move them to the desired location.
Try something like:
do {
$TempFolder = Join-Path -Path $([System.IO.Path]::GetTempPath()) -ChildPath $([System.IO.Path]::GetRandomFileName());
} while ((Test-Path -Path $TempFolder));
mkdir $TempFolder | Out-Null;
[IO.Compression.ZipFile]::ExtractToDirectory('E:\test.zip',$TempFolder);
Get-ChildItem -Path $TempFolder -Recurse | Move-Item -Destination 'E:\' -Force;
rmdir $TempFolder;
Note that this code is untested.
Below is what solved my problem
md E:\temp
move E:\test.zip E:\temp
powershell.exe -nologo -noprofile -command "& { Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::ExtractToDirectory('E:\temp\test.zip', 'E:\temp\'); }"
del E:\temp\test.zip
move /Y E:\temp\* E:\
rd E:\temp

Powershell Remove-Item Cmdlet error

I'm using powershell to remove a directory with the command:
Remove-Item $pathAsString -Recurse -Force
However, it gives me the following error:
Remove-Item : Cannot remove the item at 'C:\Path' because it is in use.
At line:1 char:1
+ Remove-Item "C:\Path" -Recurse
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Remove-Item], PSInvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.RemoveItemCommand
I thought that was odd, because the directory shouldn't be in use. I can go into file explorer and delete the directory manually. I'm not really sure why this behavior is occurring. I'm fairly new to powershell, so don't understand exactly how it behaves.
My scripts interaction with the program includes:
Creating the folder
Downloading an MSI to the folder
Setting a variable to represent the MSI stored in the folder. Like so:
$MSIVariable = Get-ChildItem $Path | Where {&_.Name -eq "MSIName.msi"}
I'm assuming that something to do with the folder is within a stream of some sort, but don't know how I'd fix this issue.
EDIT:
Here is the code I use involving the folder:
Creating the Folder:
if(!(Test-Path $MSILocation))
{
New-Item $MSILocation -ItemType directory
}
Downloading the MSI:
$webClient = (New-Object System.Net.WebClient)
$downloadLocation = Join-Path $MSILocation $MSIName
$webClient.DownloadFile($downloadURL, $downloadLocation)

Cannot figure out why my Powershell script is getting permission errors

I cannot figure out why im getting permission errors, even though im running the script as a Domain Admin, which is in the full control group on the files/folders im trying to delete. UAC is not enabled on the pc the script is running from. I get the same errors no matter if i use enter-PSsession to the file server itself.
Its got to be how i approached the solution...ive tried other scripts that im not experienced enough to edit, they used a try/catch method with get-wmiobject and then .delete() command, and that script worked great...with no permission problems, it deletes profiles like a charm...and thats with the same credentials as my homemade script...So i really feel its not a true credential problem, and more to do with a shortcoming of the way im using the remove-item cmdlet.
here is my script...its my first homemade, not copy/pasted script, so feel free to point out the obvious bad practices... here is the script, and the errors will be below. The way i wrote this script is to try each individual command separately, then tie them together, that may be why some of it may be redundant.
##This process deletes ntuser.dat files and user profile folders
$users = (Read-Host "Enter each user (separate with comma)").split(',') | % {$_.trim()}
foreach ($user in $users) {
$datfile = "ntuser.dat"
$servers = Get-Content C:\servers.txt
$path1 = "\\fileserver\d$\TSEProfiles\$user.DOMAIN"
$path2 = "\\fileserver\d$\TSEProfiles\$user.DOMAIN.V2"
## Checks for ntuser.dat file in specified folders, if true, delete.
## Checking 4 locations on fileserver
If (Test-Path \\fileserver\d$\TSEProfiles\$user.DOMAIN\$datfile){
Remove-Item $path1\$datfile -recurse -force
}
if (Test-Path \\fileserver\d$\TSEProfiles\$user.DOMAIN.V2\$datfile){
Remove-Item $path2\$datfile -recurse -force
}
If (Test-Path \\fileserver\d$\roamingprofiles\$user.DOMAIN\$datfile){
Remove-Item $path1\$datfile -recurse -force
}
If (Test-Path \\fileserver\d$\roamingprofiles\$user.DOMAIN.V2\$datfile){
Remove-Item $path2\$datfile -recurse -force
}
## Checking 8 locations, if true, delete.
foreach ($server in $servers) {
If (Test-Path \\$server\c$\users\$user -PathType Container){
Remove-Item \\$server\c$\users\$user -recurse -force
}
}
}
Remove-Item : Access to the path '\\APPS3\c$\users\realdomainuser\AppData\Local\Application Data' is denied.
At C:\Users\admin\Documents\zoink.ps1:35 char:2
+ Remove-Item \\$server\c$\users\$user -recurse -force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (\\APPS3\c$\users\realdomainuser:String) [Remove-Item], UnauthorizedAccessException
+ FullyQualifiedErrorId : RemoveItemUnauthorizedAccessError,Microsoft.PowerShell.Commands.RemoveItemCommand
Remove-Item : Access to the path '\\APPS4\c$\users\realdomainuser\AppData\Local\Application Data' is denied.
At C:\Users\admin\Documents\zoink.ps1:35 char:2
+ Remove-Item \\$server\c$\users\$user -recurse -force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (\\APPS4\c$\users\realdomainuser:String) [Remove-Item], UnauthorizedAccessException
+ FullyQualifiedErrorId : RemoveItemUnauthorizedAccessError,Microsoft.PowerShell.Commands.RemoveItemCommand
django - THis is the delete profile output after running the local machine policy script. still getting auth errors.
Remove-Item : Access to the path '\\APPS7\c$\users\someuser\AppData\Local\Application Data' is denied.
At C:\Users\admin\Documents\zoink.ps1:35 char:2
+ Remove-Item \\$server\c$\users\$user -recurse -force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (\\APPS7\c$\users\someuser:String) [Remove-Item], UnauthorizedAccessException
+ FullyQualifiedErrorId : RemoveItemUnauthorizedAccessError,Microsoft.PowerShell.Commands.RemoveItemCommand
I once was having issues running scripts due to permissions on some of our Citrix VM's that didn't have powershell scripts running, however I was able to run bat files so I created a PS scripted wrapped inside a bat file.
echo "Killing IE"
powershell -Command "stop-process -processname iexplore"
While it is nowhere near an elegant solution it is an easy hack that serves it's purpose.
Try running this script. This is an example of permanently setting your local machine policy for scripts:
# SetExecutionPolicyToRemoteSigned.ps1
Write-Output "Setting local Powershell policy to RemoteSigned"
Write-Output ""
Set-ExecutionPolicy -scope CurrentUser Undefined -Force
#Set-ExecutionPolicy -scope Process Undefined -Force
Set-ExecutionPolicy -scope LocalMachine Undefined -Force
Set-ExecutionPolicy -scope CurrentUser RemoteSigned -Force
#Set-ExecutionPolicy -scope Process RemoteSigned -Force
Set-ExecutionPolicy -scope LocalMachine RemoteSigned -Force
Write-Output "Finished."
Get-ExecutionPolicy -list
Start-Sleep -s 10
It will result in the following output:
PS C:\Users\qa> Get-ExecutionPolicy -list
Scope ExecutionPolicy
----- ---------------
MachinePolicy Undefined
UserPolicy Undefined
Process RemoteSigned
CurrentUser RemoteSigned
LocalMachine RemoteSigned
Then, you can just run a script like this one without a policy prompt. Best of all, the policy should survive rebooting your system :
# Filename: Hello.ps1
Write-Host
Write-Host 'Hello World!'
Write-Host "Good-bye World! `n"
# end of script
And another example of running a script:
powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile
-WindowStyle Hidden -File script_name

Delete broken link

I need to delete all the content of a folder which may include broken links among others. The folder path is provided by a variable. Problem is that PowerShell fails to remove the broken links.
$folderPath = "C:\folder\"
Attempt 1:
Remove-Item -Force -Recurse -Path $folderPath
Fails with error:
Remove-Item : Could not find a part of the path 'C:\folder\brokenLink'.
At line:1 char:1
+ Remove-Item -Force -Recurse -Path $folderPath
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (C:\folder\brokenLink:String) [Remove-Item], DirectoryNot
FoundException
+ FullyQualifiedErrorId : RemoveItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
Attempt 2:
Start-Job { cmd /c rmdir $folderPath }
Fails because $folderPath gets passed as is instead of its value:
Start-Job { cmd /c rmdir $folderPath } | select command
Command
-------
cmd /c rmdir $folderPath
Any suggestion besides using the .NET framework?
EDIT
By broken link I'm referring to a folder which points to a previously mounted partition, that doesn't exist anymore. The folder is still available but when attempting to navigate into it this error occurs because the destination doesn't exist anymore:
Error:
C:\folder\brokenLink refers to a location that is unavailable. It
could be on a hard drive on this computer, or on a network. Check to
make sure that the disk is properly inserted, or that you are
connected to the Internet or your network, and then try again. If it
still cannot be located, the information might have been moved to a
different location.
This will work:
$folderPath = "C:\folderContaingBrokenSymlinks\";
$items = ls $folderPath -Recurse -ea 0;
foreach($item in $items){
if($item.Attributes.ToString().contains("ReparsePoint")){
cmd /c rmdir $item.PSPath.replace("Microsoft.PowerShell.Core\FileSystem::","");
}
else{
rm -Force -Recurse $item;
}
}