Clear CrowdStrike SensorGroupingTags with Powershell - powershell

Quick explanation is that I need to reassign CrowdStrike tags locally on the hosts. I built a powershell script that stops right when the machine asks for a maintenance token. I have to run the CrowdStrike commands in command prompt, they do not work in powershell. It works until you need to enter the maintenance token, but shouldn't the variable entered earlier work? So the script is like this:
$maintenanceToken = Read-Host -Prompt "Enter Maintenance token"
$location = Read-Host -Prompt "What location are we at today"
$cs_version = cmd.exe /c CsSensorSettings --version
if($cs_version -Like "*6.4*") {
Write-Host "Clearing Tags"
$csClear = cmd.exe /c "CsSensorSettings clear --grouping-tags"
$maintenanceToken
### It works until right here, it just
stop Token is never entered ###
... more code ...}
I have tried doing Invoke-Command $maintenaceToken and cmd.exe $maintenanceToken. Everything I find doesn't seem to work. I am wondering if it us stuck in Command Prompt and if it is how do I get around it.

Related

Check if powershell running in REPL (Read-eval-print-loop) mode or via "Run With Powershell"

In other words, is there a way to test in a powershell whether we're running having been right-clicked upon and choosing "Run With Powershell" or by opening a powershell interpreter and running something like & myscript.ps1
I have a script which outputs dialog to the user and I've set it up to pause on completion for the user to read what was printed before it disappears (if running via Run With Powershell). However if the script is being run from a REPL interpreter there is no need to pause, as the output will persist in the shell after the script completes
Your answer might be in the $MyInvocation automatic variable. When I right click on a script and choose Run with PowerShell, an if statement is added to the command to check execution policy. You might be able to find a difference between the invocation methods in your environment.
Write-Output "My Invocation Testing"
if ($MyInvocation.Line -like "if((Get-ExecutionPolicy ) -ne 'AllSigned')*") {
Write-Host -NoNewLine 'Press any key to continue...';
[void]$Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
}

Pass argument into Powershell

I have a powershell script that completes some tasks in Active Directory and MS Exchange. I need to pass in the Active Directory username from our call logging system. Having the Call log system pass the argument is simple.
The problem i am facing is having powershell read the argument into a variable.
I will provide a proof of concept example.
Here is a sample command passing the argument into powershell.
C:\Users\UserName\Desktop\Test.ps1 -ADusername "Hello World"
Here is the sample script:
Param([string]$adusername)
$adusername
pause
I am Expecting the following output:
Hello World
Press Enter to continue...:
This is the actual output:
Press Enter to continue...:
Just wrapping my head around this core concept will help me immensely. I was unable to find any examples or tutorials that worked when applied to my scenario. I apologize if this is a duplicate post, couldnt find anything on this site as well.
EDIT: per request, this is my full script: http://pastebin.com/ktjpLQek
I think you will have much better luck if you avoid trying to use params and call the script exactly that way.
It is possible, but paramaters work better if you either inline the scriptfile like:
. .\scriptFile.ps1
function "Hello World"
Staying closer to what you are doing however, you should be using $args and calling PowerShell (the exe directly)
If you call your scriptfile like: (I used the runbox)
powershell c:\Path\Folder\Script.ps1 "Hello World!"
and then replace your Param([string]$adusername) with:
$adUserName = $args[0]
write-host $adUserName
Additionally, this should work for you (to dissect):
Param([string]$ad)
Write-Host $args[0]
Write-Host $ad
Read-Host
pause
Call the script with the path,
powershell c:\Path\Folder\Script.ps1 "Hello World!" $ad = "JSmith"
If this does not work, you should ensure that your execution policy is set correctly. Get-ExecutionPolicy will tell you the current level. For testing you can set it very low with Set-ExecutionPolicy unrestricted
Add the following to the top of your script.
Param(
[Parameter(Mandatory=$true)]
[string]$Euser
)
Write-Host "Deactivating $EUser"
Calling example after cd to the script directory
.\ScriptName.ps1 -Euser "FOO" # Tab auto completion works
The following in a new script works for me.
Param([string]$servers)
"You chose $servers"
PS C:\scripts> .\Untitled1.ps1 "this test"
You chose this test
PS C:\scripts>

How to run exe with/without elevated privileges from PowerShell

I would like an easy way to run a process with different privileges from the same user without asking or knowing his/her password. A dialog is okay if necessary. I would prefer not to launch a PowerShell sub-process to accomplish this.
Scenario 1:
PowerShell script is running in admin-mode. I want to launch a script or an .exe without admin privileges but on the same user.
Scenario 2:
PowerShell script is running in normal mode. I want to launch a script or an .exe with admin privileges on the same user.
Let's split this into three parts.
First determine if current session is running with admin privileges:
$CurrentID = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$CurrentPrincipal = new-object System.Security.Principal.WindowsPrincipal($CurrentID)
$adminRole = [System.Security.Principal.WindowsBuiltInRole]::Administrator
# Check to see if session is currently with admin privileges
if ($CurrentPrincipal.IsInRole($adminRole)) {
write-host "Yes we are running elevated."
}else{
write-host "No this is a normal user session."
}
Now, if we are running with or without elevation, you can start a new process with elevated privileges like this:
$newProc = new-object System.Diagnostics.ProcessStartInfo "PowerShell"
# Specify what to run
$newProc.Arguments = "powershell.exe"
# If you set this, process will be elevated
$newProc.Verb = "runas"
[System.Diagnostics.Process]::Start($newProc)
And lastly, if we have elevated privileges, but would like to start a new process without...
I have no idea. Will have to try to find the answer to this, but as it is not a common scenario, I had no luck so far.
EDIT: I have now seen a couple of “solutions” for this scenario. There is no native way to do this in .NET/PowerShell. Some are quite complicated (Calls to some 12 COM objects). This vista-7-uac-how-to-lower-process-privileges is a good reference.
The one that seems most elegant to me, is exploiting a “bug” in explorer.exe.
Just launch you .exe using explorer.exe and the resulting process runs without privilege elevation again.
$newProc = new-object System.Diagnostics.ProcessStartInfo "PowerShell"
# Specify what to run, you need the full path after explorer.exe
$newProc.Arguments = "explorer.exe C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
[System.Diagnostics.Process]::Start($newProc)
EDIT #2: Another way I have just found to start a new non-elevated process from an already elevated environment is to use the runas.exe with the 0x20000 (Basic User) trust level:
C:\> runas /showtrustlevels
The following trust levels are available on your system:
0x20000 (Basic User)
C:\> runas /trustlevel:0x20000 devenv
I use this as first command in all scripts that requires elevated mode, it transfer the script to another elevated process if I forgot to start up as Admin. You have to confirm so it's not suitable for automated tasks
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 }

Manually running a .ps1 in an administrator (elevated) shell

I have a seemingly straightforward question: How can I manually run a .ps1 script on Server 2012 R2 and have it open in an administrator elevated shell? I am right clicking and clicking "Run with Powershell" on the .ps1 file.
My environment:
Two Server 2012 R2 machines in the same domain in the same OU. Both are full GUI installs. Both have UAC set to "default".
The discrepancy:
One of the servers will run any and all .ps1 files in an administrator elevated shell. The other server will run any and all .ps1 files in a non-administrator, standard shell. I have no idea what the differences are between the two servers. Neither are running any custom Powershell profiles.
The following registry keys are all identical between the two servers:
HKEY_CLASSES_ROOT\Microsoft.PowerShellCmdletDefinitionXML.1
HKEY_CLASSES_ROOT\Microsoft.PowerShellConsole.1
HKEY_CLASSES_ROOT\Microsoft.PowerShellData.1
HKEY_CLASSES_ROOT\Microsoft.PowerShellModule.1
HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1
HKEY_CLASSES_ROOT\Microsoft.PowerShellSessionConfiguration.1
HKEY_CLASSES_ROOT\Microsoft.PowerShellXMLData.1
What am I missing?
A quick foray with Google ended me up with a posting on Ben Armstrong's blog where he posted code that auto-elevated a script if it was needed. Here's the code he posted that seems perfect for your needs:
# Get the ID and security principal of the current user account
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
# Get the security principal for the Administrator role
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
# Check to see if we are currently running "as Administrator"
if ($myWindowsPrincipal.IsInRole($adminRole))
{
# We are running "as Administrator" - so change the title and background color to indicate this
$Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)"
$Host.UI.RawUI.BackgroundColor = "DarkBlue"
clear-host
}
else
{
# We are not running "as Administrator" - so relaunch as administrator
# Create a new process object that starts PowerShell
$newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell";
# Specify the current script path and name as a parameter
$newProcess.Arguments = $myInvocation.MyCommand.Definition;
# Indicate that the process should be elevated
$newProcess.Verb = "runas";
# Start the new process
[System.Diagnostics.Process]::Start($newProcess);
# Exit from the current, unelevated, process
exit
}
# Run your code that needs to be elevated here
Write-Host -NoNewLine "Press any key to continue..."
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

Create a process using Plink in PowerShell and sending commands to it

I need to be able to create a process on a remote device and send come commands to it using a PowerShell script. I need to do it this way because I get prompts when I use a command. I have been trying to figure out how to do this by using Google searches and the following link: http://tartarus.org/~simon/putty-snapshots/htmldoc/Chapter7.html#plink. From that link, I realized using a file with a list of commands in Plink won't work for the following reason (copied and pasted from that link):
Any non-interactive command you could usefully run on the server
command line, you can run in a batch file using Plink in this way.
It says "non-interactive command", which is what I'm using. I have also tried using a file with a list of commands anyway, but it didn't solve my problem because I basically need to give a command, wait, and then give another one when it prompts me. This is what I found in the PuTTY FAQ and basically what I would like to try:
Probably your best bet is to use Plink, the command-line connection
tool. If you can start Plink as a second Windows process, and arrange
for your primary process to be able to send data to the Plink process,
and receive data from it, through pipes, then you should be able to
make SSH connections from your program. This is what CVS for Windows does, for example.
EDIT: Based on the answer from user2460798, I have tried out the solution below. I'm hoping to use PuTTY and be able to send commands to it that way. My problem now is that I don't know how to send commands to the PuTTY session that gets opened. So basically this code opens up a PuTTY session and tries to write the "ls" command to it, but nothing happens. I have no idea where the "ls" text is going.
$procInfo = New-Object Diagnostics.ProcessStartInfo
$procInfo.RedirectStandardOutput=$true
$procInfo.RedirectStandardInput=$true
$procInfo.RedirectStandardError=$true
$procInfo.FileName="putty.exe"
$procInfo.Arguments="-ssh -pw <password> <username>#<device>"
$procInfo.UseShellExecute=$false
$p=[diagnostics.process]::start($procInfo)
sleep -Milliseconds 3000
$p.StandardInput.WriteLine("ls")
Not sure to understand your question, but here is the way I use plink
function plink
{
[CmdletBinding()]
PARAM
(
[Parameter(Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[string] $remoteHost,
[Parameter(Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[string] $login,
[Parameter(Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[string] $passwd,
[Parameter(Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[string] $command)
& c:\Tools\plink.exe -ssh $remoteHost -l $login -pw $passwd $command
return
}
$remoteHost = "192.168.1.1"
$login = "TheUserWhoCan"
$command1 = "/opt/compiere/apache-tomcat-6.0.32/bin/shutdown.sh "
$command2 = "cd /opt/compiere/apache-tomcat-6.0.32/bin && ./startWS.sh"
$command3 = "ps -edalf | grep java"
$passwd = Read-Host "Enter Password for $login"
write-host "Stopping tomcat" -ForegroundColor DarkGreen
plink -remoteHost $remoteHost -login compiere -command $command1 -passwd $passwd
Start-Sleep 10
write-host "Starting tomcat" -ForegroundColor DarkGreen
plink -remoteHost $remoteHost -login compiere -command $command2 -passwd $passwd
write-host "Looking for java processes"-ForegroundColor DarkGreen
plink -remoteHost $remoteHost -login compiere -command $command3 -passwd $passwd
It's not clear to me if you really want something that's non-interactive. The sentence 'It says "non-interactive command", which is what I'm using.' sounds like you want non-interactive. But " I basically need to give a command, wait, and then give another one when it prompts me" sounds interactive. Since it's not clear I'll answer for the interactive case.
The second quote from the FAQ ("Probably your...") can be achieved using the code given here: How to run interactive commands in another application window from powershell , but replacing cmd.exe with plink.exe and changing the command line arguments as needed for plink.
But sure to read the text that precedes the code. It mentions a couple of caveats.