Power shell and .bat file - powershell

Because im not so good in power shell, i wanted to ask how to manage this task. I have created .bat file which doing this:
echo before delete > delete.log
forfiles -p "C:\test1" -s -m *.* -d -0 -c "cmd /c echo #path" >> trace.log
forfiles -p "C:\test1" -s -m *.* -d -1 -c "cmd /c del #path" >> trace.log
echo preserved >> trace.log
forfiles -p "C:\test1" -s -m *.* -d -0 -c "cmd /c echo #path" >> trace.log
And output of that trace.log i send successfully via separate power shell script like this:
$body = Get-Content -Path "C:\test1\trace.log" -Raw
Send-MailMessage -from doNotReply#company.com -to "nobody#company.com" -subject "Trace log delete status test" -body $body -smtpServer smtp.company.com
Because of my limited knowledge in power shell is there a way to merge .bat commands with my current power shell script? Idea is to do action of delete like in above sample, create log and send it by email in one power shell script.

Try like this:
Write-Host "before delete" > delete.log
(Get-ChildItem "C:\test1" -Recurse |
Select-Object -ExpandProperty Fullname) >>trace.log
(Get-ChildItem "C:\test1" -Recurse |
Where-Object {$_.LastWriteTime -ge (Get-Date).addDays(-1)} |
Remove-Item -Force) >>trace.log
Write-Host "preserved" >> trace.log
(Get-ChildItem "C:\test1" -Recurse |
Select-Object -ExpandProperty Fullname) >>trace.log
$body = Get-Content -Path "C:\test1\trace.log" -Raw
Send-MailMessage -from doNotReply#company.com -to "nobody#company.com" -subject "Trace log delete status test" -body $body -smtpServer smtp.company.com

#marsze Ok sorry, so i run ISE like admin user and executed this line Set-ExecutionPolicy -Scope LocalMachine Unrestricted. Than i copied all above proposed code in same session and run, and i hit this errors:
Get-ChildItem : Access to the path 'C:\Program Files\Websense\Websense Endpoint\certutil' is denied.
At line:8 char:2
+ (Get-ChildItem "C:\test1" -Recurse |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (C:\Program File...dpoint\certutil:String) [Get-ChildItem], Unauth
orizedAccessException
+ FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
Get-ChildItem : Access to the path 'C:\Windows\CCM\ScriptStore' is denied.
At line:8 char:2
+ (Get-ChildItem "C:\test1" -Recurse |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (C:\Windows\CCM\ScriptStore:String) [Get-ChildItem], UnauthorizedA
ccessException
+ FullyQualifiedErrorId :

Related

Any ideas on why i am receiving this error? Any help appreciated. Thnx

Uninstalling :
The term 'C:\temp\install\Deploy-Application.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.
+ CategoryInfo : ObjectNotFound: (C:\temp\install\Deploy-Application.exe:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
+ PSComputerName : WKPF26YSKX
This is the code ran:
function Install-File {
Invoke-Command `
-Session $global:session `
-ScriptBlock{
if( -not (Test-Path -Path "V:\") ) {
New-PSDrive -Name "V" -PSProvider "FileSystem" -Root "\\lounaswps01\idrive\D907ATS" -Credential (Get-Credential -Credential "slb8031a") -Scope global
}
$Global:certRequestID = $global:objTemp.CRID
# Assign server path and local path variables w/ given CR ID
$serverPath = "v:\" + $Global:certRequestID
$localPath = "C:\temp\" + $Global:certRequestID
dir $serverPath
dir $localPath
#Copy-Item -Path $serverPath -Destination $localPath -Recurse -Force | Out-Host
# Check for atsinst.bat first - run it if it exists. Else offer uninstall/install options
if(Test-Path -LiteralPath "${localPath}\install\atsinst.bat") {
Invoke-Expression -Command " ${localPath}\install\atsinst.bat -DeployMode 'Silent' | Out-Host "
}
Write-Host "`nUninstalling ${certRequestID}: "
Invoke-Expression -Command " ${localPath}install\Deploy-Application.exe -DeployMode 'Silent' -DeploymentType 'Uninstall' | Out-Host"
#Start-process -FilePath "${localPath}\install\Deploy-Application.exe" -argumentList "-DeployMode Silent -DeploymentType Uninstall" -wait -noNewWindow
Write-Host "`nInstalling ${certRequestID}: "
Invoke-Expression -Command " ${localPath}\install\Deploy-Application.exe -DeployMode 'Silent' | Out-Host "
}
# Offer to delete files from host
$prompt = Read-Host -Prompt "`nDelete ${certRequestID} from the user's temp folder? (y/n)"
if($prompt.ToLower() -eq "y") {
Write-Host "`nDeleting files..."
Remove-Item -LiteralPath $localPath -Recurse -Force
}
}
You're missing a backslash in one of the lines for uninstalling?
Invoke-Expression -Command " ${localPath}install\Deploy-Application.exe
Should Read:
Invoke-Expression -Command " ${localPath}\install\Deploy-Application.exe

Get-Content error when passing variable as path - Powershell Script

I have the following script.
#Script publicador
$carpetas = Get-ChildItem -Directory -Path C:\Publicaout | Sort-Object {[int]($_ -replace '(\d+).*', '$1')} | Format-Wide -Column 1 -Property Name | Out-String
foreach ($line in $carpetas.Split([string[]]"`r`n", [StringSplitOptions]::RemoveEmptyEntries))
{
$destino = Get-Content c:\Publicaout\$line\Destino.txt
echo $destino
#Copy-Item -Path C:\Publicaout\$line -Recurse -Destination C:\temp\ -ToSession $session -Force
#Invoke-Command -ComputerName $destino -Credential $cred -ScriptBlock {Invoke-Expression -Command:"cmd.exe /c 'c:\temp\$Using:line\publicador.bat'"}
#Invoke-Command -ComputerName $destino -Credential $cred -ScriptBlock {Remove-Item \\$Using:destino\c$\temp\$Using:line -Recurse -Force}
}
What it does, first it sorts by numerical order subfolders on a folder called Publicaout in C:, then I get the list of those subfolders in order, and I use for each to use each element of the list as a parameter, for each one of those folders, I copy it to a remote server, and then I run a script which is located within that copied folder, after that, i delete that folder so i do not leave any leftovers.
So far so good, but now, within each folder there's a text file that contains the destination server that each specific folder must be copied to. So, I believed that adding a Get-Content + path to the file, using the $line variable that contains the subfolder name would be enough, but each time I run the script i get this error:
Get-Content : Cannot find path 'C:\Publicaout\3000\Destino.txt' because it does not exist.
At C:\Users\elmarichaladmin\Documents\publicador.ps1:18 char:14
+ $destino = Get-Content c:\Publicaout\$line\Destino.txt
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\Publicaout\3... \Destino.txt:String) [Get-Content], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand
This happens with each folder, i have 5 folders, named 1, 99,654,3000, 65404. Its really weird because the Copy command works perfect, but Get-Content does not.
Any ideas? I know that the errors shows an empty line, but as you can see I get rid of each empty line when i run the string split.

How to Invoke-Expression to call a function or script with variables?

I get the an invalid path error with this script:
$buildZIP= 'starmatic'
echo $buildZIP
$command = ”\\XXXXXXXXXX\L$\Gopi_Prod_App\ToZipNew.ps1 $buildZIP”
Invoke-Expression -Command $command
This is ToZipNew.ps1:
Param(
[Parameter(Position=1, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$build
)
echo "$build"
$S = "L:\Gopi_Prod_App\$build\App_Data\*"
$D = "\Gopi_Prod_App\Starmatic_UI.zip"
echo $S
echo $D
Get-ChildItem "$S" | Compress-Archive -DestinationPath "$D" -Verbose
#Compress-Archive -Path "$S" -CompressionLevel Fastest -DestinationPath "$D"
Error I am getting:
Compress-Archive : The path 'L:\Gopi_Prod_App' either does not exist or is not a
valid file system path.
At \\XXXXXXXXXXX\L$\Gopi_Prod_App\ToZipNew.ps1:13 char:45
+ ... t-ChildItem "$S" | Compress-Archive -DestinationPath "$D" -Verbose
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (L:\Gopi_Prod_App:String) [Compress-Archive], InvalidOperationException
+ FullyQualifiedErrorId : ArchiveCmdletPathNotFound,Compress-Archive
Invoke-Expression is almost always the wrong tool for whatever job you have at hand. Also, it looks to me like you actually want to run the script on the remote host. However, your Invoke-Expression statement is reading the script from the remote share and executing it locally.
Change
$command = ”\\XXXXXXXXXX\L$\Gopi_Prod_App\ToZipNew.ps1 $buildZIP”
Invoke-Expression -Command $command
into
Invoke-Command -Computer 'XXXXXXXXXX' -ScriptBlock {
& 'L:\Gopi_Prod_App\ToZipNew.ps1' $using:buildZIP
}
to run the script on the remote host XXXXXXXXXX.
If you do want to run the script locally connect the share \\XXXXXXXXXX\L$ as a network drive L: and call the script from that drive:
New-PSDrive -Name 'L' -PSProvider FileSystem -Root '\\XXXXXXXXXX\L$' -Persist
& 'L:\Gopi_Prod_App\ToZipNew.ps1' $buildZIP
Remove-PSDrive -Name 'L'

Install .msi remotely using Powershell

I have made he following code using the code present on this forum.
cls
$computername = Get-Content 'C:\Users\C201578-db\Documents\server.txt'
$sourcefile = "\\iceopsnas\LNT_SoftwareRep.grp\CORE\COTS\EMC\Avamar\Avamar_7.0\CR06794393\AvamarClient-windows-x86_64-7.0.102-47.msi"
#This section will install the software
foreach ($computer in $computername)
{
$destinationFolder = "\\$computer\C$\Avamar"
#This section will copy the $sourcefile to the $destinationfolder. If the Folder does not exist it will create it.
if (!(Test-Path -path $destinationFolder))
{
New-Item $destinationFolder -Type Directory
}
Copy-Item -Path $sourcefile -Destination $destinationFolder
Write-Host "Copied Successfully"
Invoke-Command -ComputerName $computer -ScriptBlock { & cmd /c "msiexec.exe /i C:\Avamar\AvamarClient-windows-x86_64-7.0.102-47.msi" /qb ADVANCED_OPTIONS=1 CHANNEL=100}
Write-Host "Installed Successfully"
}
I tried all permutations and combinations but no luck. Tried all the suggestions that I got while posting this question but nothing. The copy procedure is successful but the .msi file is not getting installed. Maybe this question gets marked duplicate but still suggest some edits before doing that.
try defining your command as a script block instead:
$command = "msiexec.exe /i C:\Avamar\AvamarClient-windows-x86_64-7.0.102-47.msi"
$scriptblock = [Scriptblock]::Create($command)
Invoke-Command -ComputerName $computer -ScriptBlock $scriptblock
As a workaround (the lack of details doesnt help to daignose the problem), you could use the third party tool psexec.exe to run the installer on the remote host.
Try to replace your invoke-command with
psexec.exe \\$computer -s -u Adminuser -p AdminPassword msiexec /i C:\Avamar\AvamarClient-windows-x86_64-7.0.102-47.msi /qb ADVANCED_OPTIONS=1 CHANNEL=100
It's working fine with psexec.exe, I have installed it on more than 100 user's desktop. Setup your user's ip addresses on clients.txt file. Below is my code :
cls
$computername = Get-Content 'C:\Setup\clients.txt'
$sourcefile = "C:\Setup\MySyncSvcSetup.msi"
$serviceName = "MySyncWinSvc"
$adminUserName = "username"
$adminPassword = "password#123"
#This section will install the software
foreach ($computer in $computername)
{
#First uninstall the existing service, if any
C:\PSTools\psexec.exe \\$computer -s -u $adminUserName -p $adminPassword msiexec.exe /x C:\SetupFiles\MySyncSvcSetup.msi /qb
Write-Host "Uninstalling Service"
$destinationFolder = "\\$computer\C$\SetupFiles"
#This section will copy the $sourcefile to the $destinationfolder. If the Folder does not exist it will create it.
if (!(Test-Path -path $destinationFolder))
{
New-Item $destinationFolder -Type Directory
}
Copy-Item -Path $sourcefile -Destination $destinationFolder
Write-Host "Files Copied Successfully"
C:\PSTools\psexec.exe \\$computer -s -u $adminUserName -p $adminPassword msiexec.exe /i C:\SetupFiles\MySyncSvcSetup.msi /qb /l* out.txt
Write-Host "Installed Successfully"
C:\PSTools\psexec.exe \\$computer -s -u $adminUserName -p $adminPassword sc.exe start $serviceName
Write-Host "Starting the Service"
}

Copy-Item : Cannot bind argument to parameter 'Path' because it is null

I am not sure what is going on. I am very new to Power Shell.
I have a folder structure containing images in them. I am looking to get all the images that are X days old and copy those images to two other locations. The error I am getting is:
Copy-Item : Cannot bind argument to parameter 'Path' because it is null.
At C:\Documents and Settings\Administrator.VDICORP\Desktop\ProcessOSImages.ps1:37 char:24
+ copy-item -path <<<< $TheImage -destination $TestSite
+ CategoryInfo : InvalidData: (:) [Copy-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.CopyItemCommand
My code is as follows:
$TodaysDate = get-date
$FileAgeInDays = "-2"
$ImageLocation = "\\vdifiles\Print-Room\FileSrv\Barcode-Order"
$TestSite = "\\10.0.100.3\www2.varietydistributors.com\catalog\newpictures"
$LiveSite = "\\10.0.100.3\Variety Distributors.com\catalog\newpictures"
$WhenFileWritten = $TodaysDate.AddDays($FileAgeInDays)
$IncludeFileTypes = "*.jpeg,*.jpg"
$ExcludeFileTypes = "*.psd,*.tif,*.pdf"
$LogFile = "C:\Temp\FilesCopied.log"
$EmailServer = "mx1.domain.com"
$EmailFrom = "alerts#domain.com"
$AuthUser = "user"
$AuthPass = "pass"
$XHeaderInfo = "X-Header: This email was sent from Laservault."
$EmailTo = "me#domain.com"
$EmailSubject = "Barcode Images Summary."
$EmailBodySent = "TEST Attached to this email is a log file of what images were copied from $ImageLocation to $TestSite and $LiveSite as well as sent to AS2 to send over to Order Stream."
$EmailBodyNotSent = "TEST There were no files in $ImageLocation that matched $WhenFileWritten days old. So, nothing was sent to $TestSite, $LiveSite or AS2."
$TheImages = get-childitem $ImageLocation -include $IncludeFileTypes -exclude $ExcludeFileTypes -recurse -force | where-object {$_.CreationTime -le "$WhenFileWritten" -and $_.PsIsContainer -ne $true}
foreach ($TheImages in $TheImage) {
$FileCount = ($TheImage).count
if (!($FileCount -eq 0)) {
copy-item -path $TheImage -destination $TestSite
copy-item -path $TheImage -destination $LiveSite
write-host $FilesCount "images were copied."
write-output $TheImage >> $LogFile
\\vdifiles\blat$\blat.exe -attach $LogFile -to $EmailTo -s $EmailSubject -i $EmailFrom -body $EmailBodySent -server $EmailServer -u $AuthUser -pw $AuthPass -f $EmailFrom -x $XHeaderInfo
remove-item $LogFile
} else {
\\vdifiles\blat$\blat.exe -to $EmailTo -s $EmailSubject -i $EmailFrom -body $EmailBodyNotSent -server $EmailServer -u $AuthUser -pw $AuthPass -f $EmailFrom -x $XHeaderInfo
}
}
Where am I going wrong?
It's a simple problem. You flipped your variables in your foreach statement. You have:
foreach ($TheImages in $TheImage) {
You should have:
foreach ($TheImage in $TheImages) {
--- Edit
The other issue is with the Get-ChildItem not returning anything. It's a small problem because of the -include and -exclude parameters you are feeding into it. You are defining the variable like this:
$IncludeFileTypes = "*.jpeg,*.jpg"
$ExcludeFileTypes = "*.psd,*.tif,*.pdf"
The problem is that the -include and -exclude parameters are expecting a string array (String[]) what you are giving them is a straight string.
We can prove this, if you create a file with the name "a.jpeg,a.jpg", the get-childitem cmdlt will return the file.
The solution is to change your $IncludeFileTypes and $ExcludeFileTypes variables to a string array, and it should return the results that you are expecting:
$IncludeFileTypes = "*.jpeg","*.jpg"
$ExcludeFileTypes = "*.psd","*.tif","*.pdf"