Calling Powershell in a batch file issue - powershell

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

Related

Powershell For-Loop throws MissingVariableNameAfterForeach

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.

Batch script to taskkill search by "Command Line" arguments

I need a batch script to taskkill by "Command Line" arguments ("Command Line" from Windows Task Manager). To clarify - these processes are dotnet core applications. They are started via:
dotnet MyDotnetCoreApp.dll xxx yyy
If you examine under Task Managers,
Name = dotnet.exe
Image path name = C:\Program Files\dotnet\dotnet.exe
Command line = dotnet MyDotnetCoreApp.dll xxx yyy
I need a batch script to kill these tasks, probably with taskkill
OPTION 1 is Taskkill by PID but how my script search "Command Line" arguments for MyDotnetCoreApp?
OPTION 2 is taskkill by Image Name? This is no go as my server has many dotnet core applications, if kill my Image Name, all dotnet core processes be killed
I been researching:
https://superuser.com/questions/415360/how-do-i-find-out-command-line-arguments-of-a-running-program
https://www.itprotoday.com/powershell/powershell-contains
I can't get this to work, not good at PowerShell:
Get-WmiObject Win32_Process -Filter "name = 'dotnet.exe'" | Select-Object Handle
Here'd get a list of PIDs with which to kill.
Two challenges:
First Challenge, my WHERE clause dont work:
Get-WmiObject Win32_Process -Filter "name = 'dotnet.exe'" | where {$_.CommandLine -like '*MyDotnetCoreApp*'} | Select-Object Handle
I checked further, found out these "CommandLine" was NOT populated for these WmiObjects (omg!):
Get-WmiObject Win32_Process -Filter "name = 'dotnet.exe'" | Select-Object ProcessId, Name, CSName, Caption, CommandLine, ExecutablePath
I later then found out "CommandLine" would have been populated IF you run Powershell as Administrator!?! (Powershell so cryptic!)
In the end - First challenged was resolved:
Get-WmiObject Win32_Process -Filter "name = 'dotnet.exe'" | where {$_.CommandLine -like '*MyDotnetApp*'} | Select-Object ProcessId, Name, CSName, Caption, CommandLine, ExecutablePath
Second Challenge: How to kill it? Found it!!
(Get-WmiObject Win32_Process -Filter "name = 'dotnet.exe'" | where {$_.CommandLine -like '*MyDotnetCoreApp*'}).Terminate()
So this is actually resolved!
Run Powershell as Administrator! Download psexec from https://learn.microsoft.com/en-us/sysinternals/downloads/psexec
psexec -u Administrator -p SomeSecret powershell
Then from Powershell:
(Get-WmiObject Win32_Process -Filter "name = 'dotnet.exe'" | where {$_.CommandLine -like '*MyDotnetCoreApp*'}).Terminate()
Now as separate question, can you do this one line? Below wont work because -Filter has quotes in it!
psexec -u Administrator -p SomeSecret powershell -Command "(Get-WmiObject Win32_Process -Filter ""name = 'dotnet.exe'"" | where {$_.CommandLine -like '*MyDotnetCoreApp*'}).Terminate() "
As hacky work around, I removed -Filter clause (How unfortunate, not sure how to escape quotes):
psexec -u Administrator -p SomeSecret powershell -Command "(Get-WmiObject Win32_Process | where {$_.CommandLine -like '*MyDotnetCoreApp*'}).Terminate() "
Works for me as a regular user, unless the process is running as administrator?. Unfortunately, the filter syntax is like sql here, where '%' is the wildcard. Piping to where-object would probably work just as well.
get-wmiobject win32_process -filter "commandline like '%dotnet.exe%MyDotnetCoreApp%'" |
remove-wmiobject
get-wmiobject win32_process | where commandline -like '*dotnet.exe*MyDotnetCoreApp*' |
remove-wmiobject

show process's full command line in powershell?

When I run this command
PS C:\> gwmi Win32_Process | select CommandLine
It cuts off the command line. How can I get it to show the full command line?
That being done by the default formatting, which is using Format-Table. Try format-list
gwmi win32_process | select commandline | format-list
Alternatively Format-Table offers the -wrap and -autosize parameters.
gwmi win32_process | select handle, commandline | ft -wrap -autosize
Results
466 %SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,20480,768 Windows=On SubSystemType=Windows ServerDll=bas
esrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=winsrv:ConServerDllInitialization,2 ServerDll=sxssrv,4 ProfileContro
l=Off MaxRequestThreads=16
550 wininit.exe
510 %SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,20480,768 Windows=On SubSystemType=Windows ServerDll=bas
esrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=winsrv:ConServerDllInitialization,2 ServerDll=sxssrv,4 ProfileContro
l=Off MaxRequestThreads=16
546 C:\Windows\system32\services.exe
596 C:\Windows\system32\lsass.exe
3472 "C:\Program Files (x86)\Mozilla Firefox\firefox.exe"
1766 "C:\Windows\system32\notepad.exe"
3384 "C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe"
1780 \??\C:\Windows\system32\conhost.exe
You're better off filtering for specific process which can be done via PID or Process Name, both pieces of information are easily obtained from the task manager if you don't already know.
Once you have the PID this will work great:
$PID=<Your Process ID)
(Get-WmiObject win32_process -Filter ProcessId=$PID -Property CommandLine).CommandLine
Example of getting java.exe by process name:
(Get-WmiObject -Class win32_process -Filter "Name='java.exe'" -Property CommandLine).CommandLine
added by barlop
example with output-
PS C:\Users\User> (Get-WmiObject win32_process -Filter ProcessId=1676 -Property CommandLine).CommandLine <ENTER>
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --type=renderer --field-trial-handle=1108,1777349067310493
8616,10462310811264875730,131072 --lang=en-GB --enable-auto-reload --origin-trial-disabled-features=MeasureMemory --devi
ce-scale-factor=1 --num-raster-threads=2 --enable-main-frame-before-activation --renderer-client-id=1695 --no-v8-untrust
ed-code-mitigations --mojo-platform-channel-handle=11412 /prefetch:1
PS C:\Users\User>
This is a frequently asked question about how powershell formats output. Aside from making the window bigger:
gwmi Win32_Process | % CommandLine
sihost.exe
C:\Windows\system32\svchost.exe -k UnistackSvcGroup
taskhostw.exe {222A245B-E637-4AE9-A93F-A59CA119A75E}

Using the -command PowerShell feature does not executing in CMD

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" }

Disable NetworkAdapter CMD

How can I run this powershell script in cmd?
$adaptor = Get-WmiObject -Class Win32_NetworkAdapter | Where-Object {$_.Name -like "*Wireless*"}
$adaptor.Disable()
Make sure CMD is elevated. You could use WMIC directly from CMD:
wmic nic where "NetConnectionID like '%wireless%'" call disable
you can pass commands to the powershell executeable via the -Command switch and prefixing the script block with &.
powershell -Command "& { $adaptor = Get-WmiObject -Class Win32_NetworkAdapter | Where-Object {$_.Name -like "*Wireless*"}; $adaptor.Disable() }"
You can read more by running the command powershell -?