Why do I get the error "MissingVariableNameAfterForeach" for the following:
powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "foreach($file in Get-ChildItem C:){((Get-Date)-$file.LastWriteTime).ToString('dd')}"
The command is supposed to print out the day since today of the last file/folder write in C:\
From the help text:
PS C:\> powershell.exe /?
If the value of Command is a script block, the script block must be enclosed
in braces ({}). You can specify a script block only when running PowerShell.exe
in Windows PowerShell.
Try this:
powershell.exe -NoProfile -ExecutionPolicy Bypass -Command {Get-ChildItem C: | ForEach-Object{($_.LastWriteTime).ToString('dd')}}
Your command will work if you enclose the Get-ChildItem in parentheses.
powershell.exe -NoProfile -ExecutionPolicy Bypass -Command ^
"foreach($file in (Get-ChildItem C:)){((Get-Date)-$file.LastWriteTime).ToString('dd')}"
I may have understood your question, because the existing answers do not seem to provide the information I thought you were looking for.
Whilst these examples don't specifically answer the question posed in your title, they are intended to output what I think you were looking for.
Here therefore is my batch-file attempt:
#"%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile -Command^
"Get-ChildItem -Path 'C:\'|Sort-Object -Property LastWriteTime|"^
"Select-Object -Last 1|Format-Table -AutoSize -Property Name,"^
"#{Name='DaysOld';Expression={[Int]$((Get-Date)-$_.LastWriteTime).TotalDays}}"
#Pause
And obviously the cmd version, to be on topic:
"%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile -Command "Get-ChildItem -Path 'C:\'|Sort-Object -Property LastWriteTime|Select-Object -Last 1|Format-Table -AutoSize -Property Name,#{Name='DaysOld';Expression={[Int]$((Get-Date)-$_.LastWriteTime).TotalDays}}"
Just in case it is simply my misunderstanding, perhaps this batch-file may work for you:
#"%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile -Command^
"Get-ChildItem -Path 'C:\'|Sort-Object -Property LastWriteTime -Descending|"^
"Format-Table -AutoSize -Property Name,"^
"#{Name='DayInMonth';Expression={($_.LastWriteTime).ToString('dd')}},"^
"#{Name='DaysOld';Expression={[Int]$((Get-Date)-$_.LastWriteTime).TotalDays}}"
#Pause
cmd version:
"%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile -Command "Get-ChildItem -Path 'C:\'|Sort-Object -Property LastWriteTime -Descending|Format-Table -AutoSize -Property Name,#{Name='DayInMonth';Expression={($_.LastWriteTime).ToString('dd')}},#{Name='DaysOld';Expression={[Int]$((Get-Date)-$_.LastWriteTime).TotalDays}}"
In both cases, you'll note because I'm not running a PowerShell script, there is no need to stipulate an execution policy. Commands should work as if being run directly in the PowerShell window.
Related
I need to see the powershell output when I'm running it from a bat file. The bat file pauses with no problem but the powershell executes and flashes on the screen and closes before I can read the powershell error. How can I pause the powershell output so I can read it.
Bat file RemovePackagesFitBit.bat
#ECHO Off
PowerShell.exe -NoProfile -Command "& {Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""%~dpn0.ps1""' -Verb RunAs} | Wait-Process"
#PAUSE
Powershell file RemovePackagesFitBit.PS1
Get-AppxPackage -allusers *fitbit* | Remove-AppxPackage
Running this in Windows 10
Just insert pause in script where required:
$Package = Get-AppxPackage -allusers -Name fitbit
Pause
$Packasge | Remove-AppxPackage
Pause
I wasn't able to see the errors with a pause so I logged all output to a file this way:
I put this at the begining of the script:
$Logfile = "C:\Temp\Fix-Sysprep.log"
If (Test-Path $Logfile)
{
Remove-item -path $Logfile
}
Start-Transcript -Path $Logfile -Append
I put this at the end of the script:
Stop-Transcript
My powershell command is this:
Get-WmiObject -class Win32_printer | ft name, systemName, shareName >> $PSScriptRoot\printers.txt
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, InstallDate | Format-Table –AutoSize >> $PSScriptRoot\programs.txt
Get-WmiObject -Class Win32_MappedLogicalDisk | select Name, ProviderName >> $PSScriptRoot\drives.txt
My batch is this:
#ECHO OFF
SET Directory=%~dp0
SET PowerShellScriptPath=%Directory%reimage_checklist.ps1
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '%PowerShellScriptPath%'";
If I run the PowerShell script in IDE, it puts out three text documents with the requested information. If I run the batch file, it outputs three batch files, but the network drive text file is blank.
Resolved by adding
Set-ExecutionPolicy -Scope CurrentUser Bypass
To the powershell script and removing
-ExecutionPolicy Bypass
From the batch file
Still new to PowerShell and have been creating automation scripts, checks and balances and anything I can think of to make our jobs easier day to day. The contract we are working on are extremely tight when it comes to applications and forbids opensource\freeware applications. So I have been working on using powershell to do the job.
Here is what I have so far:
1. Created HKCR\Directory\Shell\powershell (default) Reg_sz Search Folder Text & Log files
2. Created HKCR\Directory\Shell\powershell\command (default) Reg_sz
C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe -file c:\temp\RightClickSearch.ps1 -NoExit -Command Set-Location -LiteralPath '%L'
I was able to get the right click to launch and the script opens up and prompts me for my keyword to search. Problem is, I can't seem to figure out how to pass the location to the script properly.
RightClickSearch.ps1 (I know the $path isn't set, before it was hardcoded and I know I have to pass a variable to it from the menu)
$promt = (Read-Host -Prompt "Enter Search Keyword")
Get-ChildItem -Path $Path -Include *.txt, *.log -Recurse | Select-String -Pattern $promt | Format-table -AutoSize -Property LineNumber,Filename,Path
Pause
There are two problems with your call to powershell.exe:
You can't specify both the -File and -Command parameters. You can only specify one of them.
Whichever one you do specify, it has to be the last parameter in the command. In your example, the -NoExit and -Command parameters would be ignored. (Type powershell.exe -? for an explanation.)
The good news is that PowerShell scripts themselves can accept arguments by using the param keyword. Simply declare the parameter at the top of your script:
param ($Path)
$promt = (Read-Host -Prompt "Enter Search Keyword")
Get-ChildItem -Path $Path -Include *.txt, *.log -Recurse | Select-String -Pattern $promt | Format-table -AutoSize -Property LineNumber,Filename,Path
Pause
You call it from the command line like this:
C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe -File c:\temp\RightClickSearch.ps1 -Path '%L'
Since $Path is the one and only parameter, you don't even have to specify its name:
C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe -File c:\temp\RightClickSearch.ps1 '%L'
Ironically, you could use the -Command parameter in exactly the same way. The only difference is that your script file will not be dot-sourced, but that won't matter in the example you gave.
I have to read each file in a folder and determine the length of the first line of each, then do something depending on whether or not that length is what is should be in a table. I can loop through each file in batch and have %%f as the file, but how do I get that length and assign it to a variable?
If there is a way to do this in Powershell using a batch file, that would help, but I would need to know how to call the Powershell from the batch file also.
The simple PowerShell code would look something like this:
param($path)
Get-ChildItem $path -File |
Select FullName,#{Label="1stLineLength";Expression={(Get-Content $_.FullName -First 1).Length}}
So the first argument will be taken as the path of the script. Then to call it from batch I borrow the answer to this SO question.
Powershell.exe -executionpolicy remotesigned -File m:\Scripts\firstlinelength.ps1 "C:\temp"
That will get output like this on console.
FullName 1stLineLength
-------- -------------
C:\Users\mcameron\CleansedBigFile.txt 4
This code assumes that you have at least PowerShell v3.0 for the -First and -File parameter and switch. I would like to think that most batch code can be converted easily to a PowerShell equivalent so if your environment allows you consider converting to the powerful PowerShell.
Some of your question is pretty vague (what table?). But in general, you don't need a batch file at all. PowerShell example:
Get-ChildItem -File | ForEach-Object {
$firstLineLength = (Get-Content $_ | Select-Object -First 1).Length
if ( $firstLineLength -gt $whateverFromTable ) {
...
}
}
Note that the -File parameter of Get-ChildItem doesn't exist before PowerShell v3. For PowerShell v2 and below, you would replace Get-ChildItem -File with Get-ChildItem | Where-Object { -not $_.PSIsContainer }.
I am trying to create a PowerShell command that reads a registy variable and then executes a command. It does this from the command line using CMD and it runs under SYSTEM.
I have the following code:
powershell.exe -ExecutionPolicy ByPass -WindowStyle Minimized -Command
"$ErrorActionPreference = 'silentlycontinue' |`
New-Variable -name UserNameForSapFolderRemoval -Value (get-itemproperty 'HKCU:\Volatile Environment' |`
Select-Object -ExpandProperty UserName) |`
Remove-Item $("C:\Users\"+$UserNameForSapFolderRemoval +"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Sapgui 7.30") -Force -Recurse |`
Remove-Variable -Name UserNameForSapFolderRemoval"
But it returns with:
The string is missing the terminator
I added the " character but without succes.
Any idea how I can get this powershell command to run succesful?
Parsing username from registry is way too complicated, as there already is $env:username. Try something like this,
powershell -command { rm -force -recurse "c:\users\$env:username\appdata\whatever" }