How to pause the output of Powershell from a bat file - powershell

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

Related

Elevating PowerShell script permissions

I am trying to run script to manage some VHD Disks, but the disk mount is failing due to elevated permissions required. The user the script is run under is a local admin, but UAC is blocking it I think. The error which comes back is: “DiskState=Failed to mount disk - "Access to a CIM resource was not available to the client”
Ideally I need to the script to run under elevated command prompt automatically. Any idea's how I can achieve that programmatically?
The script I am running is this:
$location = "C:\temp"
$name = "downloadfile"
$Author = "FSLogix"
$FilePath = "Filepath here"
$LogFilePath = "Logfilepath here"
# Force to create a zip file
$ZipFile = "$location\$Name.zip"
New-Item $ZipFile -ItemType File -Force
$RepositoryZipUrl = "https://github.com/FSLogix/Invoke-FslShrinkDisk/archive/master.zip"
# download the zip
Write-Host 'Starting downloading the GitHub Repository'
Invoke-RestMethod -Uri $RepositoryZipUrl -OutFile $ZipFile
Write-Host 'Download finished'
#Extract Zip File
Write-Host 'Starting unzipping the GitHub Repository locally'
Expand-Archive -Path $ZipFile -DestinationPath $location -Force
Write-Host 'Unzip finished'
# remove the zip file
Remove-Item -Path $ZipFile -Force
# Run the FSLogix Optimisation
C:\temp\Invoke-FslShrinkDisk-master\Invoke-FslShrinkDisk.ps1 -Path $FilePath -Recurse -PassThru -LogFilePath $LogFilePath\logfile.csv
You can elevate the PS script using the Powershell as a separate process and make it "run as admin" like below:
start-process PowerShell -verb runas
OR
Powershell -Command "Start-Process PowerShell -Verb RunAs"
Apart from that , you can condition it as well. There is a beautiful conditional code shared by PGK which can help as well:
if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{
$arguments = "& '" +$myinvocation.mycommand.definition + "'"
Start-Process powershell -Verb runAs -ArgumentList $arguments
Break
}

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.

NSIS Script Wrap to PS1 into EXE and Run as Admin

I have the following NSIS (.nsi) script that wraps PowerShell script into exe.
In addition, I would like the exe to run as admin because the scripts needs to update registry key.
NSIS Script is:
!include x64.nsh
RequestExecutionLevel admin ;Require admin rights on NT6+ (When UAC is turned on)
OutFile "file.exe"
SilentInstall silent
Section
SetOutPath $EXEDIR
File "file.ps1"
# Run the script to update
ExecWait "powershell -ExecutionPolicy Bypass -WindowStyle Hidden -File .\file.ps1"
SectionEnd
Function .onInstSuccess
Delete "file.ps1"
FunctionEnd
PowerShell script is:
$registryPath = "HKLM:\SOFTWARE\Test"
$Name = "keyName"
$value = "keyValue"
$preRegVer = (Get-ItemProperty $registryPath).Version
#log "Pre registry value: $preRegVer"
If(!(Test-Path $registryPath))
{
# log "Path does not exist"
New-Item -Path $registryPath -Force | Out-Null
# log "Path created"
New-ItemProperty -Path $registryPath -Name $name -Value $value -PropertyType String -Force | Out-Null
# log "Value created"
}
Else {
# log "Path exist"
$val = Get-ItemProperty -Path $registryPath
if($val.Version -eq $null)
{
# log "Value does not exist"
New-ItemProperty -Path $registryPath -Name $name -Value $value -PropertyType String -Force | Out-Null
# log "Value created"
}
Else {
# log "Value exist"
Remove-ItemProperty -path $registryPath -Name Version -Force
# log "Value removed"
New-ItemProperty -Path $registryPath -Name $name -Value $value -PropertyType String -Force | Out-Null
# log "Value created"
}
}
When I run .exe file, it asks for elevated permission, but does not update the key.
I know that powershell script works, because I used PowerGUI to compile it to exe, and it updates the key.
Only problem with PowerGUI is that it does not have an option to run as Admin.
I am suspecting you're running on 64bit machine and there is conflict with bitness.
Haven't tried this, but try this ans see if that works.
${If} ${RunningX64}
${DisableX64FSRedirection}
${EndIf}
ExecWait "powershell -ExecutionPolicy Bypass -WindowStyle Hidden -File .\file.ps1"
${If} ${RunningX64}
${EnableX64FSRedirection}
${EndIf}
Instead of using power shell script, you can perform same task in NSIS itself. You can modify and you can create your own new registry entry using nsis.
for example you can use following commands to write and read the registry
WriteRegStr HKLM SOFTWARE\NSIS_Example2 "Version" "1.0"
ReadRegStr $mm HKLM "SOFTWARE\NSIS_Example2" "Version"
Here's a link!
The end result of our build process calls NSIS to create an executable for the product(s) we're building. We too are trying to call Powershell similar to the example listed above to run at deploy time, the powershell script is called to manage special duties on the server that are related to IIS.
In the NSIS file we've tried the variations below with no success:
nsExec::ExecToStack 'powershell -inputformat none -ExecutionPolicy bypass -File "C:\HardCodedLocation_Instance.ps1" '
nsExec::ExecToStack 'powershell.exe "& "C:\HardCodedLocation_Instance.ps1"' $0
ExecWait 'powershell -ExecutionPolicy Bypass -WindowStyle Hidden -File C:\HardCodedLocation_Instance.ps1' $0
${PowerShellExec} "C:\HardCodedLocation_Instance.ps1"
The "C:\HardCodedLocation_Instance.ps1" is getting run by NSIS at deploy time but the tasks that require administrative permissions in the script are not being completed.
The first two lines in "C:\HardCodedLocation_Instance.ps1":
Set-ExecutionPolicy -ExecutionPolicy Bypass
Import-Module webadministration
I'm running the executable logged onto a server as an administrator. I can then turn around, right click on "C:\HardCodedLocation_Instance.ps1" and "Run with PowerShell" and it works as it should.

How to Create Powershell Script Remove-appxpackage Windows Built-in App Executed by Batch Command?

Can someone confirm that this script are correct.
Batch cmd Execute.bat :
#echo off
color d
echo Execute Powershell Script With Administrative Privileges
echo.
PowerShell.exe -NoProfile -Command "& {Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""%~dpn0.ps1""' -Verb RunAs}"
echo.
timeout /t 5
And for Powerhsell.ps1 :
Remove-appxpackage Microsoft.XboxApp_5.6.17000.0_x64__8wekyb3d8bbwe
Remove-appxpackage Microsoft.XboxGameCallableUI_1000.10240.16384.0_neutral_neutral_cw5n1h2txyewy
Remove-appxpackage Microsoft.XboxIdentityProvider_1000.10240.16384.0_neutral_neutral_cw5n1h2txyewy
Remove-appxpackage Windows.ContactSupport_10.0.10240.16384_neutral_neutral_cw5n1h2txyewy
Remove-appxpackage Microsoft.BingNews_4.3.193.0_x86__8wekyb3d8bbwe
Remove-appxpackage Microsoft.BingFinance_4.3.193.0_x86__8wekyb3d8bbwe
Remove-appxpackage Microsoft.BingWeather_4.3.193.0_x86__8wekyb3d8bbwe
Remove-appxpackage Microsoft.Getstarted_2.1.9.0_x64__8wekyb3d8bbwe
Remove-appxpackage Microsoft.SkypeApp_3.2.1.0_x86__kzf8qxf38zg5c
Remove-appxpackage Microsoft.WindowsPhone_10.1506.20010.0_x64__8wekyb3d8bbwe
Remove-appxpackage Microsoft.WindowsMaps_4.1505.50619.0_x64__8wekyb3d8bbwe
Remove-appxpackage Microsoft.People_1.10159.0.0_x64__8wekyb3d8bbwe
Remove-appxpackage Microsoft.Office.OneNote_17.4201.10091.0_x64__8wekyb3d8bbwe
Remove-appxpackage Microsoft.MicrosoftSolitaireCollection_3.1.6103.0_x64__8wekyb3d8bbwe
Remove-appxpackage Microsoft.MicrosoftOfficeHub_17.4218.23751.0_x64__8wekyb3d8bbwe
Remove-appxpackage Microsoft.BingSports_4.3.193.0_x86__8wekyb3d8bbwe
Remove-appxpackage Microsoft.Appconnector_1.3.3.0_neutral__8wekyb3d8bbwe
Remove-appxpackage Microsoft.3DBuilder_10.0.0.0_x64__8wekyb3d8bbwe
Remove-appxpackage microsoft.windowscommunicationsapps_17.6002.42251.0_x64__8wekyb3d8bbwe
And how to add wait time in powershell?
Yes that should work given that the script and is in the exact location and has the same name as the batch file. I'm not sure why you are wanting to add a wait time in PowerShell, but the cmdlet that you are looking for is start-sleep
You could put the packages in a text file and do this:
$packages = Get-Content c:\scripts\packages.txt
Foreach ($package in $packages){
Remove-appxpackage $package
Start-Sleep -Seconds 15 #change this as needed
}

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