want to see a message on powershell ISE while executing .exe - powershell

I am trying to execute this powershell script
Write-output `n "\\Latest Modified Mobile file is"
$dir = "\\sharepoint.amr.ith.intel.com#SSL\sites\peca\PTA Data Sandbox\Shared Documents\Under_review\Regina\Estimates"
$filter="*EstimateImport_Mobile_*.xlsx"
$latest = Get-ChildItem -Path $dir -Filter $filter | Sort-Object LastAccessTime -Descending | Select-Object -First 1
$latest.Name
if($?)
{
"command succeeded"
}
else
{
"command failed"
}
& "C:\PECA Data Estimates Importer\PECA Estimates Importer.exe" import -i $latest.FullName
if($?)
{
"command succeeded"
}
else
{
"command failed"
}
Start-Sleep -s 5
exit
when I am using the "&" operator, it runs some windows .exe tool but on the screen I don't see any message, I want to see a message like "Running tool" on a powershell ISE so that the user knows that the script is still working.

If you want to see output on the screen, don't use Write-Output.
Use Write-Host to write text that will always be seen. Use Write-Verbose to write text that will only be seen in verbose mode.

Related

Powershell find string in log file

I'm completely new to Powershell and trying to accomplish a small task. I'm trying to find a string in the last two lines of a log file, and if the value doesn't match, take and action. If it matches, end. I think that's the simplest way to explain it. :-) I'm searching for certain words, if not found, open notepad, if found, exit. I've pieced some of it together, but I'm not sure how to handle the If False, run notepad portion. Would love some help. Thanks.
if (Test-Path C:\windows\ccm\logs\CcmEval.log) {
Get-Content 'C:\windows\ccm\logs\CcmEval.log' -Tail 2 | Select-String "Updating MDM_ConfigSetting.ClientHealthStatus with value 7" | % { $_ -notmatch "value 7" }
Start-Process C:\windows\notepad.exe
}
You can do that with that with one more if else condition. If condition not matches it will open notepad otherwise it will execute your command to exit.
if (Test-Path C:\windows\ccm\logs\CcmEval.log) {
$condition = Get-Content 'C:\windows\ccm\logs\CcmEval.log' -Tail 2 | Select-String "Updating MDM_ConfigSetting.ClientHealthStatus with value 7" | % { $_ -notmatch "value 7" }
if (!$condition) {
Start-Process C:\windows\notepad.exe
}
else {
"Do something here"
}
}
You can drop the Test-Path if you add -ErrorAction SilentlyContinue to the Get-Content, so it will quietly return nothing if the file is not found. This means you can use the same code whether or not the file exists.
-match takes a regular expression pattern, which is powerful enough that you can build "not 7" into it in one go using [^7] to mean "any character except 7".
$logFile = 'C:\windows\ccm\logs\CcmEval.log'
$lines = Get-Content -Path $logFile -Tail 2 -ErrorAction SilentlyContinue
if ($lines -match "Updating MDM_ConfigSetting.ClientHealthStatus with value [^7]") {
Start-Process C:\windows\notepad.exe
}

How to write the console output from powershell to a text file

I have tried many solutions to get the output of powershell to a text file so I can read it. I can't get the console output to stop at the end so I can read it and I can't get it to write out a file. With this code a text file isn't written. Windows 10 1903
:: This will Remove all Appxpackages
::
$AppsList = 'Microsoft.3DBuilder',
'Microsoft.BingFinance',
'Microsoft.BingNews',
'Microsoft.BingSports',
'Microsoft.MicrosoftSolitaireCollection',
'Microsoft.People',
'Microsoft.Windows.Photos',
'Microsoft.WindowsCamera',
'microsoft.windowscommunicationsapps',
'Microsoft.WindowsPhone',
'Microsoft.WindowsSoundRecorder',
'Microsoft.XboxApp',
'Microsoft.ZuneMusic',
'Microsoft.ZuneVideo',
'Microsoft.Getstarted',
'Microsoft.WindowsFeedbackHub',
'Microsoft.XboxIdentityProvider',
'Microsoft.MicrosoftOfficeHub',
'Fitbit.FitbitCoach',
'ThumbmunkeysLtd.PhototasticCollage'
C:\Batch\PSEXEC.EXE -s powershell -c
Start-Transscript -Path 'C:\RemoveAllAppxPackages.txt'
ForEach ($App in $AppsList){
$PackageFullName = (Get-AppxPackage -AllUsers $App).PackageFullName
$ProPackageFullName = (Get-AppxProvisionedPackage -AllUsers | where {$_.Displayname -eq $App}).PackageName
write-host $PackageFullName
Write-Host $ProPackageFullName
if ($PackageFullName){
Write-Host "Removing Package: $App"
remove-AppxPackage -package $PackageFullName -AllUsers > C:\RemoveAllAppxPackages.txt
) pause
}
else{
Write-Host "Unable to find package: $App" > C:\RemoveAllAppxPackages.txt
pause
}
if ($ProPackageFullName){
Write-Host "Removing Provisioned Package: $ProPackageFullName"
Remove-AppxProvisionedPackage -online -packagename $ProPackageFullName > C:\RemoveAllAppxPackages.txt
pause
}
else{
Write-Host "Unable to find provisioned package: $App" > C:\RemoveAllAppxPackages.txt
pause
}
}
Pause
Stop-Transcript
Instead of your write-host line, you could just write the bits you need in the file (wrap in quotes) and then pipe to out-file to a txt file. eg.
"Unable to find package: $App" | Out-File -FilePath C:\path\to\file.txt -Append
Note, make sure you add -append otherwise the file will be overwritten each time.
You have a typo in the Start-Transcript command.....
Start-Transscript -Path 'C:\RemoveAllAppxPackages.txt'
Should read
Start-Transcript -Path 'C:\RemoveAllAppxPackages.txt'

Powershell script exits on run time when Invoke-expression is executed

I am trying to execute below code, when the run time hits the first invoke-expression , the script exit with out running the remaining code .ps1 file . This is happening in windows 7 with powershell v3. Any pointers here is appreciated. I have tried using Try{Invoke-expression ""} catch{ $_ }, but the logs show that script exit.
$HardWares=#("abc","def")
Write-Info ("Deleting device driver with $application")
foreach ($HardWare in $HardWares){
Write-Info ("working on hardware $HardWare")
$DriverID = (Get-WmiObject -Class Win32_PnpSignedDriver | Where-Object {$_.hardwareID -eq $HardWare} | Select-Object InfName -ExpandProperty InfName | Select-Object -Unique)
if ($DriverID){
Write-Info ("Removing $HardWare and deleting $DriverID")
$HardwareRemoveCmd = "D:\Users\App.exe remove $HardWare"
Invoke-Expression $HardwareRemoveCmd
$Command= "D:\Users\App.exe dp_delete $DriverID -f"
Invoke-Expression $Command
} else {Write-Info "Could not find $DriverID file for $HardWare"}
}
The issue might be that you've created a variable called $DriverID, yet you're checking if $Driverid returns true. Variable creation is case sensitive so you have two different variables here. This will return false causing the script to skip over into the else statement.
If you want "did not find any $Driverid" to be written to the display, you'll need to put "Write-Host" in front of it.
A tidied up version of your code.
{
$Driverid = (Get-WmiObject -Class Win32_PnpSignedDriver | Where-Object
{$_.hardware -eq $HardWare} | Select-Object InfName -ExpandProperty InfName
| Select-Object -Unique)
if($Driverid)
{
Invoke-Expression "D:\Users\App.exe remove $HardWare"
$Command= "D:\Users\App.exe dp_delete $Driverid -f"
Invoke-Expression $Command
}
else
{
Write-Host "did not find any $Driverid"
}
}
Hope this helps!

writing output file as .txt or .csv to script containing multiple conditions

I have written a script which checks a service status, tests two paths and also tests a registry value. Currently I am getting output on the power shell console (that could be because I am using write-output command).
Is there any way to write the single one page output to a file?
I am struggling to find a way to out-file entire output to a file.
Below is the script.
$testpath = Test-Path "C:\test"
$testpath2 = test-path "C:\test"
$mcshieldk = Get-Service -Name mcshield | select Name
$internet = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\internet explorer").MkEnabled $hostname = hostname Write-Host "hostname of comuter is" $hostname if (Test-Path $Machinetype)
{}
else { Write-Host "internet is" $internet }
if ($testpath -eq $true -and $testpath2 -eq $true)
{ Write-Host "test and test1 folder exists" -ForegroundColor Green }
else{ Write-Host "folder does not exists" -ForegroundColor Red } if($mcshield.Name -eq "mcshield") { Write-Host "mcshield service exists" }
else { Write-Host "mcshield does not exists" }
Below is the console output
hostname of comuter is Server1
internet is Yes
test and test1 folder exists
mcshield does not exists
Swap out your Write-Host cmdlets or add in another line with the following:
"Your output text $YourVariable" | Out-File -FilePath "C:\Log.txt" -Append -Encoding utf8
This will append a string to the end of the log file C:\Log.txt. Note, missing the -Append parameter will cause the file to be overwritten.
You can also use the follow to give the same affect:
"Your output text $YourVariable" >> "C:\Log.txt"
But be carefully not to mix the two methods as you might get encoding errors in the text file. If you wish to overwrite the file with the second method use > instead of >>.

Start-Transcript: This host does not support transcription

I want to start a transcript on a Windows Server 2008 R2
Start-Transcript -path C:\Temp\test.txt
"Hello!"
Stop-Transcript
But PowerShell returns the following error message:
Start-Transcript : This host does not support transcription.
How it is possible to activate transcript?
Windows PowerShell v4 ISE and lower do not support transcription. You must use the command line to run the commandlet.
From PowerShell v5 Start-Transcript is supported natively in ISE.
COMPLETE ANSWER (PowerShell ISE 2.0/4.0)::
Having yet another look at this today on another server, I noticed that the latest PowerShell ISE (which also does not allow Start-Transcript) does not have an Output pane, and instead uses the new ConsolePane. Thus the function now is as follows:
Function Start-iseTranscript
{
Param(
[string]$logname = (Get-logNameFromDate -path "C:\fso" -postfix " $(hostname)" -Create)
)
$transcriptHeader = #"
**************************************
Windows PowerShell ISE Transcript Start
Start Time: $((get-date).ToString('yyyyMMddhhmmss'))
UserName: $env:username
UserDomain: $env:USERDNSDOMAIN
ComputerName: $env:COMPUTERNAME
Windows version: $((Get-WmiObject win32_operatingsystem).version)
**************************************
Transcript started. Output file is $logname
"#
$transcriptHeader >> $logname
$psISE.CurrentPowerShellTab.Output.Text >> $logname
#Keep current Prompt
if ($Global:__promptDef -eq $null)
{
$Global:__promptDef = (gci Function:Prompt).Definition
$promptDef = (gci Function:Prompt).Definition
} else
{
$promptDef = $Global:__promptDef
}
$newPromptDef = #'
if ($Host.Version.Major -eq 2)
{
if ($Global:_LastText -ne $psISE.CurrentPowerShellTab.Output.Text)
{
Compare-Object -ReferenceObject ($Global:_LastText.Split("`n")) -DifferenceObject ($psISE.CurrentPowerShellTab.Output.Text.Split("`n"))|?{$_.SideIndicator -eq "=>"}|%{
$_.InputObject.TrimEnd()}|Out-File -FilePath ($Global:_DSTranscript) -Append
$Global:_LastText = $psISE.CurrentPowerShellTab.Output.Text
}
} elseif ($Host.Version.Major -eq 4)
{
if ($Global:_LastText -ne $psISE.CurrentPowerShellTab.ConsolePane.Text)
{
Compare-Object -ReferenceObject ($Global:_LastText.Split("`n")) -DifferenceObject ($psISE.CurrentPowerShellTab.ConsolePane.Text.Split("`n"))|?{$_.SideIndicator -eq "=>"}|%{
$_.InputObject.TrimEnd()}|Out-File -FilePath ($Global:_DSTranscript) -Append
$Global:_LastText = $psISE.CurrentPowerShellTab.ConsolePane.Text
}
}
'# + $promptDef
$Global:_LastText = $psISE.CurrentPowerShellTab.Output.Text
New-Item -Path Function: -Name "Global:Prompt" -Value ([ScriptBlock]::Create($newPromptDef)) -Force|Out-Null
}
Taking over the prompt is incredibly useful for this, however keeping two copies of the Output buffer is not ideal. I've also added in TrimEnd() as PSISE 2.0 likes to append spaces to fill the entire horizontal line width. Not sure if PSISE 4.0 does this too, but it's no problem now anyway.
NEW ANSWER (PowerShell ISE 2.0)::
I have just recently returned to this problem, and there is a way of forcing every update in PowerShell ISE to log out as a command is executed. This relies on the log path being saved in a Global Variable called _DSTranscript. This variable is passed to the Start-iseTranscript function. I have then Hijacked the Prompt function to execute a compare between _LastText and the hostUI Output Text, and append the differences out to the log. It now works a treat.
Function Start-iseTranscript
{
Param(
[string]$logname = (Get-logNameFromDate -path "C:\fso" -postfix " $(hostname)" -Create)
)
$transcriptHeader = #"
**************************************
Windows PowerShell ISE Transcript Start
Start Time: $(get-date)
UserName: $env:username
UserDomain: $env:USERDNSDOMAIN
ComputerName: $env:COMPUTERNAME
Windows version: $((Get-WmiObject win32_operatingsystem).version)
**************************************
Transcript started. Output file is $logname
"#
$transcriptHeader >> $logname
$psISE.CurrentPowerShellTab.Output.Text >> $logname
#Keep current Prompt
if ($__promptDef -eq $null)
{
$__promptDef = (gci Function:Prompt).Definition
$promptDef = (gci Function:Prompt).Definition
} else
{
$promptDef = $__promptDef
}
$newPromptDef = #'
if ($global:_LastText -ne $psISE.CurrentPowerShellTab.Output.Text)
{
Compare-Object -ReferenceObject $global:_LastText.Split("`n") -DifferenceObject $psISE.CurrentPowerShellTab.Output.Text.Split("`n")|?{$_.SideIndicator -eq "=>"}|%{ $_.InputObject.TrimEnd()}|Out-File -FilePath ($Global:_DSTranscript) -Append
$global:_LastText = $psISE.CurrentPowerShellTab.Output.Text
}
'# + $promptDef
New-Item -Path Function: -Name "Global:Prompt" -Value ([ScriptBlock]::Create($newPromptDef)) -Force|Out-Null
}
ORIGINAL ANSWER::
PowerShell ISE does not natively support Transcription. There is a Scripting Guy blog about how to achieve this. Unfortunately this needs to be the last thing that is run in the script. This means that you need to remember to run it before closing the window. I wish this worked better, or there was a way to force it to run on window closure.
This is the function that produces close to the same result as the Start-Transcript feature:
Function Start-iseTranscript
{
Param(
[string]$logname = (Get-logNameFromDate -path "C:\fso" -name "log" -Create)
)
$transcriptHeader = #"
**************************************
Windows PowerShell ISE Transcript Start
Start Time: $(get-date)
UserName: $env:username
UserDomain: $env:USERDNSDOMAIN
ComputerName: $env:COMPUTERNAME
Windows version: $((Get-WmiObject win32_operatingsystem).version)
**************************************
Transcript started. Output file is $logname
"#
$transcriptHeader >> $logname
$psISE.CurrentPowerShellTab.Output.Text >> $logname
} #end function start-iseTranscript
Either accept you can't, or use a host that does support transcripts (like the console host: PowerShell.exe).
The powershell.exe will also generate this error if there is a problem writing to the log file. For example, if the log file was created by an administrator and the user doesn't have permissions to overwrite the log.
Start-Transcript : The host is not currently transcribing.
At D:\Test1.ps1:9 char:1
+ Start-Transcript -Path "$Source\logs\Test.txt"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Start-Transcript], PSInvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.StartTranscriptCommand
A good solution is to try using -Append or to make the log file unique by generating a date/time stamp.
Start-Transcript -Path "$Source\logs\Test.txt" -Append
This way a proper error message is generated.
Access to the path 'D:\Test\logs\Test.txt' is denied.
-Force has the same effect as -Append and will generate a permissions error.
Following the tip from #richard here I created a snippet that allows usage of Transaction logs where I need them (scheduled tasks), so I ended having in Windows 2008R2 the following code that can be run from powershell ISE or as a standalone script.
When run in ISE, the log information will be printed on screen
When run as a script, the log information will be saved to a file
if ($Host.Name -eq "Windows PowerShell ISE Host") {
$ISE=$true
} else {
$ISE=$false
}
if (-Not $ISE) {
$Date = Get-Date -f HHmmss_ddyyyy
Start-Transcript -Path "C:\Temp\$Date.log"
}
//////////
code here ...
//////////
if (-Not $ISE) {
Stop-Transcript
}
Tagging on to the amazing answer and work by #dwarfsoft:
if ($Host.Name -match 'ISE' -and $Host.version.Major -lt 4)
{
#Start-Transcript will not work here. Use Start-iseTranscript by #dwarfsoft above
Start-iseTranscript
}
else
{
#Start Transcript Will work here
Start-Transcript
}
In addition to the ISE (which I note the original poster LaPhi doesn't even mention), the other thing that can cause this error is if you're trying to use Start-Transcript within an Invoke-Command scriptblock. For instance if you're running the script on your client machine, and then connecting to the Windows Server 2008 R2 box via Invoke-Command so Start-Transcript outputs to the server.
When run in the local session Start-Transcript works as expected, however when using Invoke-Command the script is run within a remote session on that computer, and remote sessions have certain limitations, one of which is not supporting transcription.