Powershell remove-item with a timer? - windows

I have a script where my users get to install programs in on their computers.
the logic is -> copy from network path the installation file to the local hard drive of the computer,
run the installation file with different creds
I want to then delete the file but this code isnt good
copy-item "$path1" -Destination C:\ProgramData\ #copy from network path to local
$progyname = [System.IO.Path]::GetFileName($path1) #holding the programname.exe
Start-Process powershell -Credential $creds -workingdirectory c:\programdata\ -ArgumentList "-Command &{Start-Process $progyname -Verb RunAs}"
Remove-Item -path c:\programdata\$progyname -Force
Problem is the script will delete the item too soon, i actually want to wait for the installation to be completed and then delete the file.
what could work here?

Use the passthru parameter for start-process, save the returned ID to a variable and wait until the process is closed and youre good to delete

You can try this:
copy-item "$path1" -Destination C:\ProgramData\ #copy from network path to local
$progyname = [System.IO.Path]::GetFileName($path1) #holding the programname.exe
Start-Process powershell -Credential $creds -workingdirectory c:\programdata\ -ArgumentList "-Command &{Start-Process $progyname -Verb RunAs}"
$pro = $progynane.basename
If (!(Get-Process $pro -ErrorAction SilentlyContinue)){Remove-Item -path c:\programdata\$progyname -Force}
Or if you like you can -Wait parameter at end of Start-Process as #Lee_Dailey pointed.

Related

How to run a exe file with /regServer to create aplicationID in Dcom config in component services using powershell?

I have one WFO.exe file which I want to register .
I am able to run below command on remote desktop using powershell and a specific APPID is generated in Dcom config under component services:
c:\WFO.exe /RegServer
c:\WFO.exe /Service
But when I try to run this command through Packer powershell APPId is not getting created.
I tried multiple commands, but nothing is working
Start-Process -Wait -FilePath c:\WFO.exe -ArgumentList "/RegServer" -passthru
Start-Process -Wait -FilePath c:\WFO.exe -ArgumentList "/Service" -passthru
Invoke-Command -ScriptBlock {
Start-Process -Wait -FilePath "c:\WFO.exe" -ArgumentList "/s /RegServer" -PassThru
}
Invoke-Command -ScriptBlock {
Start-Process -Wait -FilePath "c:\WFO.exe" -ArgumentList "/s /Service" -PassThru
}
Do I need to import anything to work it through Packer Powershell?

Execute PS from bat for Intune Win32

I am so confused and actually also not so familiar with PS and bat after my troubles with them.
I want to set the Lockscreen in Windows 10 with Intune through an IntuneWin file (WIN32 application).
I have a folder with the image, which I want to set, a copy.bat which should copy the image in the directory and also execute the PS file for setting the login image and a del.bat for deleting the image.
copy.bat
md %AllUsersProfile%\sz
copy /Y Wallpaper.jpg %AllUsersProfile%\sz
powershell -ExecutionPolicy Bypass -File Set-Lockscreen.ps1 -verb RunAs
del.bat
del /Y %AllUsersProfile%\sz\Wallpaper.jpg
Set-Lockscreen.ps1
$RegKeyPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\PersonalizationLS"
$LockScreenPath = "LockScreenImagePath"
$LockScreenStatus = "LockScreenImageStatus"
$LockScreenUrl = "LockScreenImageUrl"
$StatusValue = "1"
$path = "C:\ProgramData\Elinvar"
$LockScreenImageValue = "C:\ProgramData\sz\Wallpaper.jpg"
sIf ((Test-Path -Path $path) -eq $false)
{
New-Item -Path $path -ItemType directory
}
if (!(Test-Path $RegKeyPath))
{
Write-Host "Creating registry path $($RegKeyPath)."
New-Item -Path $RegKeyPath -Force | Out-Null
}
New-ItemProperty -Path $RegKeyPath -Name $LockScreenStatus -Value $StatusValue -PropertyType DWORD -Force | Out-Null
New-ItemProperty -Path $RegKeyPath -Name $LockScreenPath -Value $LockScreenImageValue -PropertyType STRING -Force | Out-Null
New-ItemProperty -Path $RegKeyPath -Name $LockScreenUrl -Value $LockScreenImageValue -PropertyType STRING -Force | Out-Null
RUNDLL32.EXE USER32.DLL, UpdatePerUserSystemParameters 1, True
I pack all these files with Microsoft Win32 Content Prep Tool and upload this in Intune as Win32 file.
Upload works, assigning to a group works, installation is successful. All good so far, I thought.
If I check the directory, the image is in %AllUsersProfile%\sz.
But when I check the reg, the entry is not set.
When I run the copy.bat file manually, It doesn't work. Only when I run it as administrator.
When I run the last line in cmd as administrator, so
powershell -ExecutionPolicy Bypass -File Set-Lockscreen.ps1 -verb RunAs
It works as well.
I think Intune is not running the script as administrator.
In Intune there is no configuration to say, run this command as administrator.
Maybe with a syntax? Does anyone know this?
Something like
copy.bat RunAs
I also export the reg file and import this with
reg import PersonalizationLS.reg
It didn't work.
I think there must be a way to execute the installation command in intune to run the script as admin.
It needs just for the last line the administrator privilege , md and copy work without administrator privileges. (same also for important reg file).

Powershell Copying file from a mapped drive "Z:" to users local "C:"

Hello I want my powershell script to be able to copy a file from a mapped drive (Z:) and copy it to the user in the domains "C:/temp/" folder. Currently, my script looks like this.
$Computer = Read-Host -Prompt 'Enter the Computer Name you are accessing'
########## Install Software On PC ##########
New-Item -ItemType directory -Path "\\$Computer\c$\temp\openVPN"
Copy-Item "Z:\(15) IT\VPN\openvpn-install-2.4.8-I602-Win7.exe" "\\$Computer\c$\temp\" -Recurse
Copy-Item "Z:\(15) IT\VPN\office.opvn" "\\$Computer\c$\temp\" -Recurse
Write-Host "Installing openVPN on $Computer"
Invoke-Command -ComputerName $Computer -ScriptBlock {Start-Process "c:\temp\openVPN\openvpn-install-2.4.8-I602-Win7.exe" -ArgumentList "/q" -Wait}
Invoke-Command -ComputerName $Computer -ScriptBlock {Start-Process "c:\temp\openVPN\openvpn-install-2.4.8-I602-Win7.exe" -ArgumentList "/q" -Wait}
However, I receive the error
Copy-Item : Cannot find drive. A drive with the name 'Z' does not exist.
Would appreciate any help!
For some reason, your session is not seeing the Z drive.
Disconnect the Z drive if you can. Then map the drive in the same session using New-PSDrive PowerShell command, before accessing the Z drive.
New-PSDrive –Name "Z" –PSProvider FileSystem –Root "\\servername\path" –Persist
Also, try to run PowerShell in both standard mode and 'Run As Admin' mode.

Issues with Powershell Invoke-Command

I am trying to get an application to install on a remote server using powershell. Here is the script I am using:
$cred = Get-Credential
$s = New-PSSession -ComputerName $ServerName -Credential $cred
Invoke-Command -Session $s -ScriptBlock {Start-Process -FilePath "c:\windows\system32\msiexec.exe" -ArgumentList "/i \\computer\e$\installer.msi /qn" -Wait}
Remove-PSSession -ComputerName $ServerName
If I run the following on the remote computer directly, it executes beautifully:
Start-Process -FilePath "c:\windows\system32\msiexec.exe" -ArgumentList "/i \\computer\e$\installer.msi /qn" -Wait
But when I run it remotely as a part of the Invoke-Command, the PS Session is opened, the script runs, msiexec starts on the remote computer, then the PS Session closes but the application never installs and msiexec never closes.
Any help would be appreciated.
Thanks,
Zach
You'll need to copy the package locally first.
Once you start remoting you can no longer UNC.
The destination can be anywhere on the server/computer.
I use the temp but it's whatever you like.
Also I like to use $env:windir\temp, just in case.
Copy-item "\\servershare\File.msi" -conatiner -recurse `
\\$Computer\c$\windows\temp\
Invoke-Command -Computername $Computer -credential $cred -ScriptBlock {
Start-Process -FilePath `
"c:\windows\system32\msiexec.exe" `
-ArgumentList "/i `
\\computer\e$\installer.msi /qn" -Wait
}
I hope it helps.

How to run a PowerShell script from a batch file

I am trying to run this script in PowerShell. I have saved the below script as ps.ps1 on my desktop.
$query = "SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2"
Register-WMIEvent -Query $query -Action { invoke-item "C:\Program Files\abc.exe"}
I have made a batch script to run this PowerShell script
#echo off
Powershell.exe set-executionpolicy remotesigned -File C:\Users\SE\Desktop\ps.ps1
pause
But I am getting this error:
You need the -ExecutionPolicy parameter:
Powershell.exe -executionpolicy remotesigned -File C:\Users\SE\Desktop\ps.ps1
Otherwise PowerShell considers the arguments a line to execute and while Set-ExecutionPolicy is a cmdlet, it has no -File parameter.
I explain both why you would want to call a PowerShell script from a batch file and how to do it in my blog post here.
This is basically what you are looking for:
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& 'C:\Users\SE\Desktop\ps.ps1'"
And if you need to run your PowerShell script as an admin, use this:
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& {Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""C:\Users\SE\Desktop\ps.ps1""' -Verb RunAs}"
Rather than hard-coding the entire path to the PowerShell script though, I recommend placing the batch file and PowerShell script file in the same directory, as my blog post describes.
If you want to run from the current directory without a fully qualified path, you can use:
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& './ps.ps1'"
If you run a batch file calling PowerShell as a administrator, you better run it like this, saving you all the trouble:
powershell.exe -ExecutionPolicy Bypass -Command "Path\xxx.ps1"
It is better to use Bypass...
Small sample test.cmd
<# :
#echo off
powershell /nologo /noprofile /command ^
"&{[ScriptBlock]::Create((cat """%~f0""") -join [Char[]]10).Invoke(#(&{$args}%*))}"
exit /b
#>
Write-Host Hello, $args[0] -fo Green
#You programm...
Posted it also here:
How to run powershell command in batch file
Following this thread:
https://community.idera.com/database-tools/powershell/powertips/b/tips/posts/converting-powershell-to-batch
you can convert any PowerShell script into a batch file easily using this PowerShell function:
function Convert-PowerShellToBatch
{
param
(
[Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
[string]
[Alias("FullName")]
$Path
)
process
{
$encoded = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes((Get-Content -Path $Path -Raw -Encoding UTF8)))
$newPath = [Io.Path]::ChangeExtension($Path, ".bat")
"#echo off`npowershell.exe -NoExit -encodedCommand $encoded" | Set-Content -Path $newPath -Encoding Ascii
}
}
To convert all PowerShell scripts inside a directory, simply run the following command:
Get-ChildItem -Path <DIR-PATH> -Filter *.ps1 |
Convert-PowerShellToBatch
Where is the path to the desired folder. For instance:
Get-ChildItem -Path "C:\path\to\powershell\scripts" -Filter *.ps1 |
Convert-PowerShellToBatch
To convert a single PowerShell script, simply run this:
Get-ChildItem -Path <FILE-PATH> |
Convert-PowerShellToBatch
Where is the path to the desired file.
The converted files are located in the source directory. i.e., <FILE-PATH> or <DIR-PATH>.
Putting it all together:
create a .ps1 file (PowerShell script) with the following code in it:
function Convert-PowerShellToBatch
{
param
(
[Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
[string]
[Alias("FullName")]
$Path
)
process
{
$encoded = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes((Get-Content -Path $Path -Raw -Encoding UTF8)))
$newPath = [Io.Path]::ChangeExtension($Path, ".bat")
"#echo off`npowershell.exe -NoExit -encodedCommand $encoded" | Set-Content -Path $newPath -Encoding Ascii
}
}
# change <DIR> to the path of the folder in which the desired powershell scripts are.
# the converted files will be created in the destination path location (in <DIR>).
Get-ChildItem -Path <DIR> -Filter *.ps1 |
Convert-PowerShellToBatch
And don't forget, if you wanna convert only one file instead of many, you can replace the following
Get-ChildItem -Path <DIR> -Filter *.ps1 |
Convert-PowerShellToBatch
with this:
Get-ChildItem -Path <FILE-PATH> |
Convert-PowerShellToBatch
as I explained before.
If you want to run a few scripts, you can use Set-executionpolicy -ExecutionPolicy Unrestricted and then reset with Set-executionpolicy -ExecutionPolicy Default.
Note that execution policy is only checked when you start its execution (or so it seems) and so you can run jobs in the background and reset the execution policy immediately.
# Check current setting
Get-ExecutionPolicy
# Disable policy
Set-ExecutionPolicy -ExecutionPolicy Unrestricted
# Choose [Y]es
Start-Job { cd c:\working\directory\with\script\ ; ./ping_batch.ps1 example.com | tee ping__example.com.txt }
Start-Job { cd c:\working\directory\with\script\ ; ./ping_batch.ps1 google.com | tee ping__google.com.txt }
# Can be run immediately
Set-ExecutionPolicy -ExecutionPolicy Default
# [Y]es
Another easy way to execute a ps script from batch is to simply incorporate it between the ECHO and the Redirection characters,(> and >>),
example:
#echo off
set WD=%~dp0
ECHO New-Item -Path . -Name "Test.txt" -ItemType "file" -Value "This is a text string." -Force > "%WD%PSHELLFILE.ps1"
ECHO add-content -path "./Test.txt" -value "`r`nThe End" >> "%WD%PSHELLFILE.ps1"
powershell.exe -ExecutionPolicy Bypass -File "%WD%PSHELLFILE.ps1"
del "%WD%PSHELLFILE.ps1"
Last line deletes the created temp file.
If your PowerShell login script is running after 5 minutes (as mine was) on a 2012 server, there is a GPO setting on a server - 'Configure Login script Delay' the default setting 'not configured' this will leave a 5-minute delay before running the login script.

Resources