I have a .one OneNote section file that I would like to automatically export to PDF at regular intervals. In Powershell 7, I discovered this command:
Start-Process "C:\path\to\ONENOTE.EXE" -ArgumentList "/print `"C:\path\to\my_section.one`""
This opens OneNote and the save location dialog for the PDF, but I can't figure out how to provide input to this dialog at the command line. I'm not sure if there's an appropriate module - I looked at https://www.powershellgallery.com/ and couldn't find one. Any ideas on how to extend the above command, or another solution entirely?
As per my comment. Your use case could be as simple as this:
$CurrentDefaultPrinter = (
Get-CimInstance -Class Win32_Printer |
Where-Object {$PSItem.Default -eq $true}
).Name
$CurrentDefaultPrinter
Get-Printer |
Where-Object {$PSItem.Name -Match 'pdf'} |
Set-Printer -Name $PSItem.Name
Start-Process 'C:\path\to\ONENOTE.EXE' -FilePath 'C:\path\to\my_section.one' -Verb Print
Set-Printer -Name $CUrrentDefaultPrinter
Related
So, I am writing this script in PowerShell and I am required to delete a few files in APPDATA on Windows. I wrote this line of code and it doesn't remove the item silently. It asks for confirmation even after using $Confirm:false. How do I fix this issue?
My code:
Get-ChildItem -Path $env:APPDATA\"Microsoft\teams\blob_storage" | Remove-Item -Confirm:$false -Force
I get this unwanted confirmation box every time I run the script:
Here is your modified code. I hope it will work for you.
Get-ChildItem -Path $env:APPDATA\"Microsoft\teams\blob_storage" | Remove-Item -Recurse -Force
I want to kill the nodepad process if it exists. If I use this:
PS C:\> get-process -name notepad | Stop-Process -Force
I will get an error when the process does not exist.
get-process : Cannot find a process with the name "notepad". Verify the process name and call the cmdlet again.
At line:1 char:1
+ get-process -name notepad | Stop-Process -Force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (notepad:String) [Get-Process], ProcessCommandException
+ FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessCommand
I feel it should be silent, as it is not an error, the object should be null.
I know I could do:
PS C:\> get-process | where { $_.processname -eq 'notepad' } | Stop-Process -Force
but I prefer a simple way if it exists. Thanks.
PS: I need to kill the notepad because when I non-interactively install ClamAV, it create the notepad with a user manual. I could not find a way to tell ClamAV not to open the user manual.
Just add -ErrorAction SilentlyContinue. This one is simpler and does not prompt any erros if process does not exist.
Get-Process -Name notepad -ErrorAction SilentlyContinue | Stop-Process -Force
I suggest checking if the notepad process is the one you want first before just force-ending all notepad processes on the system:
Try {
(Get-WmiObject win32_process -Filter "name='notepad.exe'" |
Where commandline -like '*\path\to\manual.txt'
).Terminate()
}
# Handle "can't call method on null" error:
Catch [System.SystemException] { "Manual.txt process not found, skipping..." }
or ...
Stop-Process -Name "chrome" -Force -ErrorAction SilentlyContinue
And if you are using this with Gitlab beware that it has a bug with PowerShell runner, that you can work around by encapsulation inside parenthesis resulting in:
(Stop-Process -Name "chrome" -Force -ErrorAction SilentlyContinue)
source:
Gitlab powershell issue breaking on ErrorAction
Is there a way to bring a window in front from powershell?
I tried this to hide all windows (working) and bring me the powershell back (not working)
[void] [System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
$shell = New-Object -ComObject "Shell.Application"
$shell.MinimizeAll()
$a = Get-Process | Where-Object {$_.Name -like "powershell"}
[Microsoft.VisualBasic.Interaction]::AppActivate($a.ID)
Any suggestions?
The PowerShell Community Extensions has a cmdlet to assist with this. You use it like so:
Set-ForegroundWindow (Get-Process PowerShell).MainWindowHandle
or
Set-ForegroundWindow (Get-Process -id $pid).MainWindowHandle
To activate/show a window try this (assuming you're on PowerShell 2.0):
$sig = '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);'
Add-Type -MemberDefinition $sig -name NativeMethods -namespace Win32
Stop-Process -Name Notepad -ea 0;Notepad.exe
$hwnd = #(Get-Process Notepad)[0].MainWindowHandle
# Minimize window
[Win32.NativeMethods]::ShowWindowAsync($hwnd, 2)
# Restore window
[Win32.NativeMethods]::ShowWindowAsync($hwnd, 4)
Stop-Process -Name Notepad
This is cheating a bit since it's using WScript, but the following one-liner places the window in the foreground without requiring any external cmdlet installation.
In the example below, "notepad" is the process name associated with the window.
Credit goes to the Idera forum posting here by JSanders:
(New-Object -ComObject WScript.Shell).AppActivate((get-process notepad).MainWindowTitle)
Wscript one liner is working for me when I replace .MainWindowTitle to .Description at the end. So the line becomes:
(New-Object -ComObject WScript.Shell).AppActivate((get-process notepad).Description)
Yet to find a similar one liner for maximizing it...
I'm writing simple script to unarchive (rar) a project from Teamcenter to temp directory, then run specific program (Mentor), then archive again.
I've read a lot of examples about starting exe from PS, but they mostly relate to small exes like notepad, without dlls and other resources.
In Powershell Ise the script works perfectly. But when I call the script from teamcenter, Mentor is missing dlls.
Before I run Mentor, in the script, I do:
Get-ChildItem Env:
to check environment variables and all variables exist. I tried to set environments manually, like this:
$wf_classpath = Get-ChildItem Env:WF_CLASSPATH
[System.Environment]::SetEnvironmentVariable("WF_CLASSPATH", $wf_classpath.Value, "Process")
Does not work.
I tried to set homefolder:
$mentor = Start-Process $file.FullName -Wait -WorkingDirectory $workdir
Does not work.
Then I tried to call a batch file from the script with environments, does not work.
Try call cmd.exe /c ... does not work.
Full script here, works perfect only in Powershell Ise, if I call the script from other programs, exe does not start.
$shell = new-object -com shell.application
$invocation = $MyInvocation.MyCommand.Definition
$rootpath = $PSScriptRoot
$outpath = "$($PSScriptRoot)\out"
$pathtorar = "c:\Siemens\menutils\Rar.exe"
Remove-Item -Recurse -Force $outpath
New-Item $outpath -ItemType directory
$archive = get-childitem $rootpath | where { $_.extension -eq ".rar" } | Select-Object -First 1
$arglist = "x $($archive.FullName) $($outpath)"
Start-Process -FilePath $pathtorar -ArgumentList $arglist -Wait
Remove-Item -Recurse -Force $archive.FullName
$file = get-childitem $outpath -Recurse | where { $_.extension -eq ".prj" } | Select-Object -First 1
Write-Host "$(get-date -Format yyyy-MM-dd-hh-ss)
Start process: $($file.FullName)"
$mentor = Start-Process $file.FullName -Wait
$arglist = "a -m0 -r -ep1 $($archive.FullName) $($outpath)"
Start-Process -FilePath $pathtorar -ArgumentList $arglist -Wait
Remove-Item -Recurse -Force $outpath
Read-Host -Prompt "Press Enter to exit"
What's the difference between running the script from Powershell Ise and other programs?
How should I set environment variables to run the script from other scripts/programs?
Its probably that your Current directory is not correct and WorkingDirectory in my experience is buggy. The dll's will be obtained from the current directory if they are not at the regular system paths.
Use this function before Start-Process
[IO.Directory]::SetCurrentDirectory($Dir)
I'm trying to call a .PS1 using a batch file to produce a csv file with just the User Name and Other Telephone number details. I have the script to produce the csv file.
Get-ADUser -Filter * -Properties otherTelephone |
select name, #{L='otherTelephone'; E={$_.otherTelephone[0]}} | sort-object otherTelephone | select-object -last 1000 |
Export-Csv C:\Test.csv -NoTypeInformation
and I have the batch file to elevate the PowerShell
powershell -noprofile -command "&{ start-process powershell -ArgumentList '-noprofile -file C:\Test.ps1' -verb RunAs}"
The problem is when I try to import the system modules by adding
powershell.exe -ImportSystemModules
to the front of the powershell script, the CSV only returns the header information e.g. name and otherTelephone. The script works if I import the modules manually i.e right click import system modules, but not when I try to load modules before running the script.
Basically I need to run the PS script as admin, import the system modules and have the code output my data.
Any help as to where I am going wrong is appreciated.
powershell.exe -ImportSystemModules Get-ADUser -Filter * -Properties otherTelephone |
select name, #{L='otherTelephone'; E={$_.otherTelephone[0]}} | sort-object otherTelephone | select-object -last 10 |
Export-Csv C:\Test.csv -NoTypeInformation
If you need to load the modules inside your script use the following code:
Get-Module -ListAvailable | Where-Object {$_.Path -like "$PSHOME*"} | Import-Module
The -ImportSystemModules switch is a flag for powershell.exe. If you call powershell.exe -ImportSystemModules inside of your script it will start another powershell instance and load the modules inside of it.
You could also add the -ImportSystemModules to your powershell call inside the batch file. That should work too
Regards