"Publishing" a powershell script so it isn't detected as a virus - windows

I have the following Powershell script:
# Check if the script is running as admin
$IsAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")
if (-not $IsAdmin) {
# Display an error message and exit
Write-Output "Dieses Programm muss als Administrator ausgeführt werden. Bitte Rechtsklicke diese datei und wähle 'Als Administrator' ausführen."
Start-Sleep -Seconds 50
break
}
$PortName = Read-Host -Prompt "Gib deine Druckeradresse ein"
Invoke-WebRequest -Uri "https://dl.konicaminolta.eu/de?tx_kmdownloadcentersite_downloadproxy%5bfileId%5d=7f86746b8a2082a5152d3dd65a48292d&tx_kmdownloadcentersite_downloadproxy%5bdocumentId%5d=135985&tx_kmdownloadcentersite_downloadproxy%5bsystem%5d=KonicaMinolta&tx_kmdownloadcentersite_downloadproxy%5blanguage%5d=DE&type=1558521685" -OutFile "C:\printer.zip"
Expand-Archive -Path "C:\printer.zip" -DestinationPath "C:\printerAksa"
pnputil.exe /add-driver "C:\printer\UPD4PCL6Win81P_2101MU\driver\x64\PCL6\KOBxxK__01.inf" /install
Add-PrinterDriver -Name “KONICA MINOLTA Universal V4 PCL”
Add-Printer -PortName $PortName -DriverName "KONICA MINOLTA Universal V4 PCL" -Name "Printer"
Remove-Item -Path "C:\printer.zip" -Force
Remove-Item -Path "C:\printer" -Recurse -Force`
It is meant to install the printers for our school because at the moment the school's solution is to install is manually, but many people aren't tech savvy enough to do that, even with a step-by-step guide.
So i created this script in which one only has to enter their own printer address provided by the school and the rest is done for them. The problem now is that you cant really just share PowerShell scripts, because you'd have to change a policy to execute it (at least to my knowledge). What I tried is converting it to an exe file using PS2EXE which worked but when others downloaded it, Windows blocked the download as it was identified as a virus.
So here is the Question: How do I bring my little program to others from the school without it getting flagged? Maybe there is even a completely different approach than mine to the problem altogether.
Thanks for your suggestions!

Related

Windows 10: after gaining remote access, remotely start Quick Assist as .\Administrator without UAC, or temporarily disable UAC

I'd like a script to be used in this situation:
gain remote access without admin privileges
remotely start Quick Assist as .\Administrator and not have a UAC dialogue.
Step 1 is usually made with Quick Assist, sometimes made with Teams screen sharing.
I'm aware that I can locate quickassist.exe in File Explorer then use Shift and the context menu to Run as a different user, however I'd like a scripted approach.
Experiment A
This works, but there's a Yes/No UAC dialogue:
$isElevated = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if ( -not $isElevated ) {
Start-Process powershell.exe -Credential Administrator -NoNewWindow -ArgumentList {
Start-Process quickassist.exe -Verb RunAs ;
} ;
}
Experiment B
I make multiple mistakes, don't know how to correct them. (I'm trying to learn PowerShell, gradually, but I'm easily confused whilst learning; slightly dyslexic.)
$isElevated = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if ( -not $isElevated ) {
Start-Process powershell.exe -Credential Administrator {
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "PromptOnSecureDesktop" -Value 0 -Force;
};
Write-Host "UAC (user account control) is weakened for a Quick Assist session …" -ForegroundColor Red;
Start-Process powershell.exe -Credential Administrator -NoNewWindow -ArgumentList {Start-Process quickassist.exe -Verb RunAs -Wait};
Write-Host "… Quick Assist session complete …" -ForegroundColor Red;
Start-Process powershell.exe -Credential Administrator {
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "PromptOnSecureDesktop" -Value 1 -Force;
};
Write-Host "… UAC is strengthened." -ForegroundColor Red;
}
the two intended changes to the registry do not occur
the third credential dialogue appears too soon – I want it to not appear until after the end of the Quick Assist session.
Also, conceptually, there's probably no need to run Quick Assist as Administrator whilst UAC is temporarily weakened.
References
https://stackoverflow.com/a/2258134/38108 (2010-02-13) I see use of -Credential with Invoke-Command but when I try to do something similar, for changes to the registry, I make a mess.
https://stackoverflow.com/a/47516161/38108 (2017-11-27) self-elevating PowerShell scripts.
https://superuser.com/a/1524960/84988 (2020-02-12) and https://serverfault.com/a/1003238/91969 (2020-02-15) are interesting – the same script in both answers – however I need something like -Credential Administrator in lieu of -ComputerName.
https://stackoverflow.com/a/60292423/38108 (2020-03-07) via https://stackoverflow.com/a/60263039/38108
PowerShell commands - PowerShell - SS64.com
https://github.com/okieselbach/Intune/blob/master/DisablePromptOnSecureDesktop.ps1 (2020-11-13) via Quick Assist the built-in Remote Control in Windows 10 – Modern IT – Cloud – Workplace
The short answer is don't. Get a real remote management tool or have someone hit the UAC yes prompt.
This is more of a windows thing than powershell, as windows explicitly denies elevating a process locally without going through UAC (and for good reason!). You used to be able to do things like this:
# Use Enter-PSSession to start a "remote" session
# This may still support elevation if you specify CredSSP and configure credential delegation):
New-PSSession MyPCName -Auth CredSSP -cred (get-credential)
# Create a scheduled task with RunAs/elevated permissions:
Register-ScheduledTask -Action $action -User .\Administrator -TaskName "Admin-Stuff" -RunLevel Highest
Which now give fat access denied messages when running locally. You also are not able to edit registry settings within HKLM: without elevation, so disabling uac temporarily is not an option.
You may be able to make use of this exploit that allows admin users to bypass uac, but I think you still have to Run-as-other-user your shell to use it.

Copying to network share does not work with powershell Copy-Item

I try to copy with powershell in Windows 10 a install folder to a network share (samba on linux)
powershell.exe -Version 5 -Command "Copy-Item -Force -Path 'install' -Recurse -Destination
'\\\\intranet.server.com\install'" -Container
It always fails, even if files can be written in the explorere and I have access, with a lot of these messages:
Copy-Item : The target file "\\intranet.server.com\install\a\b\c" is a directory, not a file.
Deleteing any existing folder works well with Remove-Item '\\intranet.server.com\install\*' -Force -Recurse
I dont know if it has to do with credentials, how can I debug this?
The problem lies in the SMB2 Redirector Cache of Windows:
We need to disable the annoying cache temporarily by doing:
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Start-Process PowerShell -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -Command `"cd '$pwd'; & '$PSCommandPath';`"";
exit;
}
$c = Get-SmbClientConfiguration
$dc=$c.DirectoryCacheLifetime
$fc=$c.FileInfoCacheLifetime
$fnc=$c.FileNotFoundCacheLifetime
Set-SmbClientConfiguration -Force -DirectoryCacheLifetime 0 -FileInfoCacheLifetime 0 -FileNotFoundCacheLifetime 0
// Normal kopieren hier !!!!
Set-SmbClientConfiguration -Force -DirectoryCacheLifetime $dc -FileInfoCacheLifetime $fc -FileNotFoundCacheLifetime $fnc
This is a pain in the ass, but solves the issues.

Find if a program is installed on remote computer

I am trying to connect to remote computers with Active Directory and see if a single program is installed. I have tried a couple tutorials I found on the Internet, but with no success:
http://windowsitpro.com/powershell/what-applications-are-installed-computers-your-network
http://community.spiceworks.com/scripts/show/2170-get-a-list-of-installed-software-from-a-remote-computer-fast-as-lightning
I cannot get them to work properly, and they are not exactly what I am looking for.
An example of what I want to do: say I have 3 computers on my network:
123-abc
123-bcd
123-cde
and I want to see if the executable C:\Program Files (x86)\Mozilla Firefox\Firefox.exe exists. Can someone please explain how I can go about this in PowerShell?
The simplest way, provided you have domain admin privileges and administrative shares are enabled and accessible on the target computers, would be this:
$computers = '123-abc', '123-bcd', '123-cde'
$path = 'C$\Program Files (x86)\Mozilla Firefox\Firefox.exe'
$computers | % {
'{0}: {1}' -f $_, (Test-Path -LiteralPath "\\$_\$path")
}
There are a handful of ways to check for installed software. Some better suited than others. But if you're certain on the file path on each machine, the Test-Path CmdLet could be an easy approach.
Invoke-Command -ComputerName 123-abc -ScriptBlock {Test-Path 'C:\Program Files (x86)\Mozilla Firefox\Firefox.exe'}
You could probably throw that into a loop with a custom object so you can work with it as well.
For example, your code could look like this.
$pass = "password";
$secpass = ConvertTo-SecureString $pass -AsPlainText -Force;
$creds = New-Object System.Management.Automation.PSCredential("domain\login", $secpass);
Invoke-Command -ComputerName 123-abc, 123-bcd, 123-cde -Credential $creds -ScriptBlock {
Test-Path "C:\Program Files (x86)\Mozilla Firefox\Firefox.exe"
};
There are multiple ways of running powershell commands on remote computers.
Many commands support string[] parameter -ComputerName to which you can pass multiple computer names
You can use the Enter-PSSession cmdlet to enter a Telnet-like session on the remote machine
And finally, you can use the Invoke-Command cmdlet to run a script block against multiple remote hosts.

Powershell PS Credentials

I'm getting confused while trying to automatically login to a share on my server through Powershell using PSCredentials.
Here is the code I'm currently using WITHOUT using PSCredentials...
#Login to server to copy installer files to desktop
Remove-PSDrive P
New-PSDrive -Name P -PSProvider FileSystem -Root \\192.168.1.85\Users2\Ross\Documents\Powershell -Credential Ross
#Copies installer files from server to the local desktop
Copy-Item -Path \\192.168.1.85\Users2\Ross\Documents\Powershell\ccsetup502.exe -Destination C:\Users\Ross\Desktop
#Executes copied installers
Start-Process C:\Users\Ross\Desktop\ccsetup502.exe -ArgumentList "/S" -Wait -Verb RunAs
#Deletes leftover installer files
Remove-Item C:\Users\Ross\Desktop\ccsetup502.exe
And here is the website I'm using to help, but whichever way I try and apply it to my own script, it never works?
http://geekswithblogs.net/Lance/archive/2007/02/16/106518.aspx
Thanks in advance!
Ross
Try this. It will prompt you for creds, but you could always create them and store them in a variable if you wish as well.
#Login to server to copy installer files to desktop
Remove-PSDrive P
New-PSDrive -Name P -PSProvider FileSystem -Root \\192.168.1.85\Users2\Ross\Documents\Powershell -Credential (Get-Credential)
#Copies installer files from server to the local desktop
Copy-Item -Path \\192.168.1.85\Users2\Ross\Documents\Powershell\ccsetup502.exe -Destination C:\Users\Ross\Desktop
#Executes copied installers
Start-Process C:\Users\Ross\Desktop\ccsetup502.exe -ArgumentList "/S" -Wait -Verb RunAs
#Deletes leftover installer files
Remove-Item C:\Users\Ross\Desktop\ccsetup502.exe
After some perseverance I managed to solve this...
Probably worth noting that I left the PSDrive removal in there for testing purposes, as you'll get an error if the script doesn't complete and you try to run it again after making changes.
#Ensure previous PSDrive 'p' is removed
Remove-PSDrive P
#Creates new PSDrive
New-PSDrive -Name P -PSProvider FileSystem -Root \\YOURSERVERNAMEHERE\YOURFILEPATHHERE
#Login to server
new-object -typename System.Management.Automation.PSCredential -argumentlist "YOURDOMAINORSERVERUSERNAMEHERE",$password
#Copies installer files from server to the local desktop
Copy-Item -Path \\YOURSERVERNAMEHERE\YOURFILEPATHHERE\ccsetup502.exe -Destination C:\YOURFILEPATHHERE
#Executes copied installers, runs the installer silently, waits until the installer has completed
Start-Process C:\YOURFILEPATHHERE\ccsetup502.exe -ArgumentList "/S" -Wait -Verb RunAs
#Deletes leftover installer files
Remove-Item C:\YOURFILEPATHHERE\ccsetup502.exe
Hopefully this helps someone else who is stuck in the future!
Thank you anyone else who contributed their efforts.

Install .net remotely via powershell

I’m attempting to install the .net framework on a windows server 2008 r2 machine remotely via PowerShell. Reading about it seems that this cannot be achieved through an existing PowerShell session but credentials need to be explicitly passed in (any idea why this is?). However, I'm still getting permission errors.
For example, If I run:
$cred = Get-Credential -Credential 10.20.0.13\administrator
$Session=New-PsSession -ComputerName 10.20.0.13 -Credential $cred
Invoke-command -ScriptBlock {Start-Process -FilePath c:\installers\dotNetFx40_Full_x86_x64.exe -ArgumentList "/q /norestart /log c:\" -Wait} -Credential $cred -ComputerName 10.20.0.13
I can see on the remote machine that the installer runs (in task manager), the temporary folder is created on the root of c:\, the files extracted and then I get a 700kb log file. At the foot of that log file I get:
OS Version = 6.1.7601, Platform 2, Service Pack 1 OS Description =
Win2K8R2 - x64 Standard Edition Service Pack 1 CommandLine =
C:\b65da67b927bfb71c84adcecefc019\Setup.exe /q /norestart /log c:\
/x86 /x64 TimeZone = GMT Standard Time Initial LCID = 2057 Using
Simultaneous Download and Install mechanism Operation: Installing
Package Name = Microsoft .NET Framework 4 Setup Package Version =
4.0.30319 User Experience Data Collection Policy: Disabled Number of applicable items: 11 Exe
(C:\b65da67b927bfb71c84adcecefc019\SetupUtility.exe) succeeded. Exe
Log File: dd_SetupUtility.txt ServiceControl operation succeeded!
ServiceControl operation succeeded! Exe
(C:\b65da67b927bfb71c84adcecefc019\Windows6.1-KB958488-v6001-x64.msu)
failed with 0x5 - Access is denied. . Final Result: Installation
failed with error code: (0x00000005), "Access is denied. " (Elapsed
time: 0 00:01:12).
So access is denied. However, using the exact same credentials I can perform other tasks (add server roles in Powershell, add windows features via powershell etc) and I can RDP onto the box using the same username/password and run the installer there (which completes fine).
I’m missing something somewhere, but can’t seem to find out what it is. I can see its worked for someone else (http://social.technet.microsoft.com/Forums/windowsserver/ar-SA/3045eb24-7739-4695-ae94-5aa7052119fd/install-dotnet-framework-4-using-powershell?forum=winserverpowershell) so no idea why I’m getting this.
Any help much appreciated.
Thanks
You're creating a session but never using it?
I haven't tried this on a remote computer beforey, but try to run the process "as admin" by using -Verb RunAs, like this:
$cred = Get-Credential -Credential 10.20.0.13\administrator
$Session=New-PsSession -ComputerName 10.20.0.13 -Credential $cred
Invoke-command -ScriptBlock {Start-Process -FilePath c:\installers\dotNetFx40_Full_x86_x64.exe -ArgumentList "/q /norestart /log c:\" -Wait -Verb RunAs } -Session $Session
While installation of .NET framework 4.0, It installs some updates as well (.msu) files.
But when we are installaing .NET 4.0 remotely, It fails because of these updates. The reason behind that is, it's not allowable to install these updates remotely. Please find the KB article here. This article also mentioned the workaround for this.
you have servername in textfile or machine names in OU based. create .bat which has .exe to run C:\temp\xxx.exe /S /qn
$ou='OU=subou3,OU=subou2,OU=subou1,DC=domain,DC=com'
$filter = #("machinename1", "machinename2")
$compute= Get-ADComputer -Filter * -SearchBase $ou | where-object{$filter -contains $_.name}
$comp=$compute.name
foreach ($Computer in $Comp) {
Write-Host "Processing $Computer"
{
Write-Host " Installing application on $Comp"
psexec $Compter path\XXX.bat /S /qn
}
}

Resources