Powershell - manage error when registry key not exist - powershell

I hope you're well.
Desciption
I requiere your help regarding the following code I use and who can generate an error when registry key do not exist.
In this example:
If the key Ins_ProductVersion exist in both registry path, the code show information expected.
However, if this key do not exist, I got an error exception + the text: - Product Version: Not found!
My goal , is to only get my message and not the error exception
I was thinking that -ErrorAction SilentlyContinue will manage this situation, but not in my case it not seems
foreach ($path in 'HKLM:HKEY_LOCAL_MACHINE\SOFTWARE\xxx\xxxx\xxxx\environment\', 'HKLM:HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\xxx\xxxx\xxxx\environment\') {
$hotfix = Get-ItemPropertyValue -Path $path -Name 'Ins_ProductVersion' -ErrorAction SilentlyContinue
# assuming you want to exit the loop at the first successfull 'hit'
if ($hotfix) { break }
}
if ($hotfix) {
write-host "- Product Version: $hotfix"
}
else {
write-host "- Product Version: Not found!"
}
Thanks for your helps and futur advices.
Regards,
Florian
-------------- new code version ---------------
Not working for now
Original key is : Version
Change this key like : Version1
Output can be found here :
code used
foreach ($path in 'HKLM:\SOFTWARE\Dropbox\Client', 'HKLM:\SOFTWARE\WOW6432Node\Dropbox\Client') {
$hotfix = Get-ItemPropertyValue -Path $path -Name 'Version' -ErrorAction SilentlyContinue
# assuming you want to exit the loop at the first successfull 'hit'
if ($hotfix) { break }
}
if ($hotfix) {
write-host "- Product version: $hotfix"
}
else {
Write-Host "- Product version : Not found"
}
========== SOLUTION ==========
Thanks for your help
foreach ($path in 'HKLM:\SOFTWARE\Dropbox\Client', 'HKLM:\SOFTWARE\WOW6432Node\Dropbox\Client') {
try {
$hotfix = Get-ItemPropertyValue -Path $path -Name 'Version' -ErrorAction Stop
# assuming you want to exit the loop at the first successfull 'hit'
if ($hotfix) { break }
}
catch {
Write-Warning $_.Exception.Message
}
}
if ($hotfix) {
write-host "- Product version: $hotfix"
}
else {
Write-Host "- Product version : Not found"
}

The reason you receive both an exception and your own message is because you have defined the registry paths wrong:
HKLM:HKEY_LOCAL_MACHINE\SOFTWARE\xxx\xxxx\xxxx\environment should be either
HKLM:\SOFTWARE\xxx\xxxx\xxxx\environment OR
Registry::HKEY_LOCAL_MACHINE\SOFTWARE\xxx\xxxx\xxxx\environment
In your code, you have now added the registry hive twice, where you only need the short OR long version here.
This works:
foreach ($path in 'HKLM:\SOFTWARE\xxx\xxxx\xxxx\environment\', 'HKLM:\SOFTWARE\WOW6432Node\xxx\xxxx\xxxx\environment\') {
$hotfix = Get-ItemPropertyValue -Path $path -Name 'Ins_ProductVersion' -ErrorAction SilentlyContinue
# assuming you want to exit the loop at the first successfull 'hit'
if ($hotfix) { break }
}
if ($hotfix) {
write-host "- Product Version: $hotfix"
}
else {
write-host "- Product Version: Not found!"
}
and so does this:
foreach ($path in 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\xxx\xxxx\xxxx\environment\', 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\xxx\xxxx\xxxx\environment\') {
$hotfix = Get-ItemPropertyValue -Path $path -Name 'Ins_ProductVersion' -ErrorAction SilentlyContinue
# assuming you want to exit the loop at the first successfull 'hit'
if ($hotfix) { break }
}
if ($hotfix) {
write-host "- Product Version: $hotfix"
}
else {
write-host "- Product Version: Not found!"
}
without the need to wrap it inside a try{..} catch{..}
Although I do not have any exception messages, and for me the -ErrorAction SilentlyContinue does exactly what is expected, you say you keep also receiving system Exception messages using the above..
In that case, you will need to add a try{..}catch{..} to figure out what exactly errors out like this:
foreach ($path in 'HKLM:\SOFTWARE\Dropbox\Client', 'HKLM:\SOFTWARE\WOW6432Node\Dropbox\Client') {
try {
$hotfix = Get-ItemPropertyValue -Path $path -Name 'Version' -ErrorAction Stop
# assuming you want to exit the loop at the first successfull 'hit'
if ($hotfix) { break }
}
catch {
Write-Warning $_.Exception.Message
}
}
if ($hotfix) {
write-host "- Product version: $hotfix"
}
else {
Write-Host "- Product version : Not found"
}
Now, exceptions will be written to the screen too like
WARNING: Cannot find path 'HKLM:\SOFTWARE\Dropbox\Client' because it does not exist.
WARNING: Cannot find path 'HKLM:\SOFTWARE\WOW6432Node\Dropbox\Client' because it does not exist.
- Product version : Not found
or
WARNING: Property Version does not exist at path HKEY_LOCAL_MACHINE\SOFTWARE\Dropbox\Client.
WARNING: Cannot find path 'HKLM:\SOFTWARE\WOW6432Node\Dropbox\Client' because it does not exist.
- Product version : Not found

Usually best to use error handling properly rather than try to disable it:
$Paths = 'HKLM:HKEY_LOCAL_MACHINE\SOFTWARE\xxx\xxxx\xxxx\environment\', 'HKLM:HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\xxx\xxxx\xxxx\environment\'
$Paths | ForEach-Object {
Try {
$CurPath = $_
$hotfix = Get-ItemPropertyValue -Path $CurPath -Name 'Ins_ProductVersion' -ErrorAction Stop
}
Catch {
$RegError = "Error obtaining reg key: $_"
}
If ($hotfix) {
[pscustomobject]#{RegPath=$_;Hotfix=$hotfix}
}
Else {
[pscustomobject]#{RegPath=$_;Hotfix=$RegError}
}
}
Or:
$Paths | ForEach-Object {
Try {
$CurPath = $_
$hotfix = Get-ItemPropertyValue -Path $CurPath -Name 'Ins_ProductVersion' -ErrorAction Stop
[pscustomobject]#{RegPath=$_;Hotfix=$hotfix}
}
Catch {
$RegError = "Error obtaining reg key: $_"
[pscustomobject]#{RegPath=$_;Hotfix=$RegError}
}
}

Related

surpress output of get-azureaddomain

using below snippet :
#loop until we have found the newly added domain
$Stop=''
while (-not $Stop)
{
$stop = Get-AzureADDomain -Name $direct_routing_domain -ErrorAction Ignore | Out-Null
if (!$stop)
{
Write-Host "Domain is not provisioned yet - retrying in 60 seconds..." -ForegroundColor Yellow
Start-Sleep -Seconds 60
}
}
Write-Host "Domain is provisioned " -ForegroundColor Green
The output gives an error on stdout:
Get-AzureADDomain : Error occurred while executing GetDomain
Code: Request_ResourceNotFound
...
So here comes the question: how can I surpress this output ? I believe that | out-null should be enough. Or is this a bug in AzureAd 2.0.0 module ?
Out-Null does not ignore errors. Out-Null redirects stdout (known as stream #1) to null. You can try doing a try catch (catch provides easy exceptions handling)
try {}
catch {}
doc. https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_try_catch_finally?view=powershell-5.1
or redirect an error stream to void
Write-Error "ASD" 2>$null
doc. https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_redirection?view=powershell-5.1
You can use this:
$stop = $true
try {Get-AzureADDomain -Name $direct_routing_domain}
catch {
$stop = $false
}
OR
$stop = $true
$domain = Get-AzureADDomain | Where-Object {$_.Name -eq $direct_routing_domain}
if ($null -eq $domain) {
$stop = $false
}
You can use a try{}..catch{} on this, but remember to add -ErrorAction Stop (not 'Ignore') to the cmdlet to ensure also non-terminating exceptions are caught in the catch block:
# loop until we have found the newly added domain
$isProvisioned = $false
while (-not $isProvisioned) {
try {
$isProvisioned = [bool](Get-AzureADDomain -Name $direct_routing_domain -ErrorAction Stop)
}
catch { $isProvisioned = $false }
if (!$isProvisioned) {
Write-Host "Domain is not provisioned yet - retrying in 60 seconds..." -ForegroundColor Yellow
Start-Sleep -Seconds 60
}
}
Write-Host "Domain is provisioned " -ForegroundColor Green

Enviroment Paths without overwriting String

I would like to ask question about how I should proceed or how I should fix the code.
My problem is that I need my code to write into the Path three different paths for Logstash, Kibana and ElasticSearch, but I have no idea how to do it. It returns always the same error about missing ")" error
Here's the whole code ¨
[CmdletBinding(SupportsShouldProcess=$true)]
param(
[string]$NewLocation.GetType($ElasticSearch)
[string]$ElasticSearch = "C:\Elastic_Test_Server\elasticsearch\bin"
[string]$Kibana = "C:\Elastic_Test_Server\kibana\bin"
[string]$Logstash = "C:\Elastic_Test_Server\logstash\bin"
)
Begin
{
#Je potřeba spustit jako Administrátor
$regPath = "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
$hklm = [Microsoft.Win32.Registry]::LocalMachine
Function GetOldPath()
{
$regKey = $hklm.OpenSubKey($regPath, $FALSE)
$envpath = $regKey.GetValue("Path", "", [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames)
return $envPath
}
}
Process
{
# Win32API errory
$ERROR_SUCCESS = 0
$ERROR_DUP_NAME = 34
$ERROR_INVALID_DATA = 13
$NewLocation = $NewLocation.Trim();
If ($NewLocation -eq "" -or $NewLocation -eq $null)
{
Exit $ERROR_INVALID_DATA
}
[string]$oldPath = GetOldPath
Write-Verbose "Old Path: $oldPath"
# Zkontroluje zda cesta již existuje
$parts = $oldPath.split(";")
If ($parts -contains $NewLocation)
{
Write-Warning "The new location is already in the path"
Exit $ERROR_DUP_NAME
}
# Nová cesta
$newPath = $oldPath + ";" + $NewLocation
$newPath = $newPath -replace ";;",""
if ($pscmdlet.ShouldProcess("%Path%", "Add $NewLocation")){
# Přidá to přítomné session
$env:path += ";$NewLocation"
# Uloží do registru
$regKey = $hklm.OpenSubKey($regPath, $True)
$regKey.SetValue("Path", $newPath, [Microsoft.Win32.RegistryValueKind]::ExpandString)
Write-Output "The operation completed successfully."
}
Exit $ERROR_SUCCESS
}
Thank you for your help.
I really think you could simplify this a lot, unless I have misunderstood. Apologies, I am not currently on a Windows machine so can't test this.
function Add-ESPath {
# Create an array of the paths we wish to add.
$ElasticSearch = #(
"C:\Elastic_Test_Server\elasticsearch\bin",
"C:\Elastic_Test_Server\kibana\bin",
"C:\Elastic_Test_Server\logstash\bin"
)
# Collect the current PATH string and split it out in to an array
$CurrentPath = [System.Environment]::GetEnvironmentVariable("PATH")
$PathArray = $CurrentPath -split ";"
# Loop though the paths we wish to add.
foreach ($Item in $ElasticSearch) {
if ($PathArray -notcontains $Item) {
$PathArray += $Item
}
else {
Write-Output -Message "$Item is already a member of the path." # Use Write-Warning if you wish. I see it more as a notification here.
}
}
# Set the path.
$PathString = $PathArray -join ";"
Try {
[System.Environment]::SetEnvironmentVariable("PATH", $PathString)
exit 0
}
Catch {
Write-Warning -Message "There was an issue setting PATH on this machine. The path was:" # Use $env:COMPUTERNAME here perhaps instead of 'this machine'.
Write-Warning -Message $PathString
Write-Warning -Message $_.Exception.Message
exit 1
}
}
Add-ESPath
Perhaps you want to add some kind of log file rather than writing messages/warnings to the console. You can use Add-Content for this.
I long time ago i wrote some functions to add a path to system path + their is an check if the path is already inside the system path. And i also did an elevation check so when i use this function and i forgot to elevate my powershell that i get a warning. Its a different approach, I hope it will help you.
I only use the begin {} proccess{} statements for when i want to write a function that excepts pipeline inputs. So its if you want to write a function that will work as the following:
$paths = #("C:\Elastic_Test_Server\elasticsearch\bin", "C:\Elastic_Test_Server\kibana\bin")
$paths | my-append-these-to-system-path-function
Elevation check:
function G-AmIelevated($warningMessage){
if([bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).groups -match "S-1-5-32-544")){
return $true
}else{
write-host "not elevated $warningMessage" -ForegroundColor Red
return $false
}
}
append something to system path with check if its already inside system path:
function G-appendSystemEnvironmentPath($str){
if(test-path $str){
if(!((Get-Itemproperty -path 'hklm:\system\currentcontrolset\control\session manager\environment' -Name Path) -like "*$str*")){
write-host "`t $str exists...`n adding $str to environmentPath" -ForegroundColor Yellow
if(G-AmIelevated){
write-host `t old: (Get-Itemproperty -path 'hklm:\system\currentcontrolset\control\session manager\environment' -Name Path).Path
Set-ItemProperty -path 'hklm:\system\currentcontrolset\control\session manager\environment' `
-Name Path `
-Value "$((Get-Itemproperty -path 'hklm:\system\currentcontrolset\control\session manager\environment' -Name Path).Path);$str"
write-host `t new: (Get-Itemproperty -path 'hklm:\system\currentcontrolset\control\session manager\environment' -Name Path).Path
write-host `t restart the computer for the changes to take effect -ForegroundColor Red
write-host `t `$Env:Path is the merge of System Path and User Path This function set the system path
write-host `t $str appended to environmet variables. -ForegroundColor Green
}else{
write-host `t rerun ise in elevated mode -ForegroundColor Red
}
}else{
write-host "`t $str is in system environmenth path"
}
}else{
write-host `t $str does not exist
}
}
G-appendSystemEnvironmentPath -str "C:\Elastic_Test_Server\elasticsearch\bin"
G-appendSystemEnvironmentPath -str "C:\Elastic_Test_Server\kibana\bin"
G-appendSystemEnvironmentPath -str "C:\Elastic_Test_Server\logstash\bin"

Need To Install Alien Vault on Client, but Client Window Machines Run PowerShell 2.0. Need to convert to syntax that will work on that machine

Client doesn't want to upgrade, because they don't want anything to
break.
The code that I need to work on their machine is below. Right now
this script will not work because it's made to work for PowerShell 3.0 and above
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; (new-object Net.WebClient).DownloadString("https://api.agent.alienvault.cloud/osquery-api/us-east-1/bootstrap?flavor=powershell") | iex; install_agent -controlnodeid <Agent ID>
How can this be rewritten to accomplish the same thing?
Now if you know of a simpler way to work around this issue, that will help greatly.
new-module -name install_agent -scriptblock {
function AgentDoStart() {
$kServiceName = "osqueryd"
$osquerydService = Get-WmiObject -Class Win32_Service -Filter "Name='$kServiceName'"
if ($osquerydService) {
Start-Service $kServiceName
Write-Host "'$kServiceName' system service is started." -foregroundcolor Cyan
return 1
} else {
Write-Host "'$kServiceName' is not an installed system service." -foregroundcolor Yellow
return 0
}
}
function AgentDoStop() {
$kServiceName = "osqueryd"
$osquerydService = Get-WmiObject -Class Win32_Service -Filter "Name='$kServiceName'"
if ($osquerydService) {
Stop-Service $kServiceName
Start-Sleep -s 1
$proc = Get-Process osqueryd -ErrorAction SilentlyContinue
if ($proc) {
Write-Host "osqueryd still running, killing processes"
Stop-Process -Force -Name osqueryd
}
Write-Host "'$kServiceName' system service is stopped." -foregroundcolor Cyan
return 1
} else {
Write-Host "'$kServiceName' is not an installed system service." -foregroundcolor Yellow
return 0
}
}
Function Install-Project() {
param(
[string]$apikey="",
[string]$controlnodeid="",
[string]$hostid="",
[string]$assetid=""
)
Install-Project-Internal -apikey $apikey -controlnodeid $controlnodeid -hostid $hostid -assetid $assetid
Write-Host "See install.log for details" -ForegroundColor Cyan
}
Function Download-And-Install-Sysmon() {
#===================================================
#1. Download Sysmon
#===================================================
$source = "https://download.sysinternals.com/files/Sysmon.zip"
Write-Host "Downloading Sysmon from $source" -ForegroundColor Cyan
$file = "$($env:TEMP)\Sysmon.zip"
Invoke-WebRequest $source -OutFile $file
#===================================================
#2. Clean & Prepare Sysmon installation target
#===================================================
$targetondisk = "$($env:USERPROFILE)\Documents\Sysmon\"
Write-Host "Preparing Sysmon target path $($targetondisk)" -ForegroundColor Cyan
Remove-Item $targetondisk -Recurse -ErrorAction Ignore
# Suppress output, but not errors:
[void](New-Item -ItemType Directory -Force -Path $targetondisk)
If (-Not (Test-Path -Path $targetondisk)) {
Write-Error "Skipping Sysmon... Destination path $($targetondisk) does not exist."
} Else {
#===================================================
#3. Unzip Sysmon
#===================================================
Unblock-File -Path $file
Write-Host "Uncompressing the Zip file to $($targetondisk)" -ForegroundColor Cyan
$FoundExtractionAssembly = 0
try {
# Load preferred extraction method's assembly (.NET 4.5 or later)
# Write-Host "Using preferred extraction method..."
Add-Type -As System.IO.Compression.FileSystem -ErrorAction Stop
$FoundExtractionAssembly = 1
}
catch [System.Exception] {
# Write-Host "Preferred extraction method not found. Attempting fall-back method..."
}
If ($FoundExtractionAssembly) {
[IO.Compression.ZipFile]::ExtractToDirectory($file, $targetondisk)
} Else {
# Fall-back method, may fail in sessions lacking access to interactive shell
$continue_flag = 1
try {
$shell_app = New-Object -COMObject "Shell.Application"
} catch {
Write-Error "Could not create Shell.Application object"
$continue_flag = 0
}
if ($continue_flag) {
$zip_file = $shell_app.namespace($file)
$destination = $shell_app.namespace($targetondisk)
if ($destination -ne $null) {
$destination.Copyhere($zip_file.items(), 0x10)
}
}
}
}
#===================================================
#3. Download Sysmon Config File
#===================================================
$source = "https://www.alienvault.com/documentation/resources/downloads/sysmon_config_schema4_0.xml"
Write-Host "Downloading Sysmon config file from $source" -ForegroundColor Cyan
$destination = [System.IO.Path]::GetTempFileName()
Invoke-WebRequest $source -OutFile $destination
#===================================================
#3. Install Sysmon
#===================================================
Write-Host "Installing Sysmon from $source" -ForegroundColor Cyan
If ( (get-childitem $destination).length -eq 0 ) {
$command = "& '$targetondisk\sysmon' -accepteula -h md5 -n -l -i"
Write-Host "Not using an additional Sysmon configuration file" -ForegroundColor Cyan
}
Else {
$command = "& '$targetondisk\sysmon' -accepteula -h md5 -n -l -i '$destination'"
Write-Host "Sysmon configuration file to use $destination" -ForegroundColor Cyan
}
Write-Host "Installing Sysmon with command $command" -ForegroundColor Cyan
iex $command
}
Function Install-Project-Internal() {
param(
[string]$apikey="",
[string]$controlnodeid="",
[string]$hostid="",
[string]$assetid=""
)
If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Write-Error "You do not have Administrator rights to run this script!`nPlease re-run this script as an Administrator!"
Return
}
If ($PSVersionTable.PSVersion.Major -lt 3) {
Write-Error "This script must be run using Powershell version 3 or higher. You have version $PSVersionTable.PSVersion.Major installed"
Return
}
$kServiceName = "osqueryd"
$BASE = "$($env:SYSTEMDRIVE)\Program Files\osquery"
$OLDBASE = "$($env:SYSTEMDRIVE)\ProgramData\osquery"
$secretfile = $(Join-Path $BASE "secret")
$flagfile = $(Join-Path $BASE "osquery.flags")
if ([string]::IsNullOrEmpty($hostid)) {
$hostid = $assetid
}
if ([string]::IsNullOrEmpty($apikey)) {
$apikey = $controlnodeid
}
if ([string]::IsNullOrEmpty($apikey)) {
if ([System.IO.File]::Exists("$secretfile")) {
$apikey = [IO.File]::ReadAllText("$secretfile").Trim()
}
}
if ([string]::IsNullOrEmpty($apikey)) {
# check old location in ProgramData
$oldsecretfile = $(Join-Path $OLDBASE "secret")
if ([System.IO.File]::Exists("$oldsecretfile")) {
$apikey = [IO.File]::ReadAllText("$oldsecretfile").Trim()
}
}
if ([string]::IsNullOrEmpty($apikey)) {
Write-Warning "You must supply either the -apikey or -controlnodeid parameters to identify your agent account"
return
}
# use TLS 1.2
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Download-And-Install-Sysmon
#===================================================
#4. Download and install osquery
#===================================================
try {
AgentDoStop
} catch {
Write-Error "Did not stop osqueryd service. Hopefully, this is fine."
}
Write-Host "Downloading installer"
$webclient = New-Object System.Net.WebClient
$webclient.DownloadFile("https://prod-usm-saas-agent-config.s3.amazonaws.com/repo/windows/alienvault-agent-20.01.0203.0301.msi", "$env:TEMP\alienvault-agent.msi")
Write-Host "Installing"
try {
Start-Process C:\Windows\System32\msiexec.exe -ArgumentList "/i $env:TEMP\alienvault-agent.msi ALLUSERS=1 /qn /l*v .\install.log" -wait
echo "INSTALLATION SUCCESSFULLY COMPLETED" >> .\install.log
} catch {
echo "INSTALLATION ERROR (ERRORLEVEL=%ERRORLEVEL%)" >> .\install.log
Write-Error "INSTALLATION ERROR (ERRORLEVEL=%ERRORLEVEL%)"
Return
}
# If the install directory doesn't exist, bail
if (![System.IO.Directory]::Exists("$BASE")) {
echo "Installation directory does not exist: $BASE" >> .\install.log
Write-Error "Installation directory does not exist: $BASE"
Return
}
# $osquerydService = Get-WmiObject -Class Win32_Service -Filter "Name='osqueryd'"
# if ($osquerydService) {
# Write-Host "Service exists, uninstalling"
# try {
# Stop-Service $kServiceName
# AgentDoStop
#
# Write-Host "Found '$kServiceName', stopping the system service..."
# Start-Sleep -s 5
# Write-Host "System service should be stopped."
# $osquerydService.Delete()
# Write-Host "System service '$kServiceName' uninstalled." -foregroundcolor Cyan
# } catch {
# Write-Error "Did not uninstall osqueryd service. Hopefully, it's not already installed."
# }
# }
Write-Host "Writing secret"
[IO.File]::WriteAllLines("$secretfile", $apikey)
# if hostid is not specified, try to extract from flag file
if ([string]::IsNullOrEmpty($hostid)) {
if ([System.IO.File]::Exists($flagfile)) {
$match = (Select-String -Path $flagfile -Pattern "specified_identifier=(.*)")
if ($match.Matches.Groups.success) {
$hostid = $match.Matches.Groups[1].Value.Trim()
Write-Host "Detected and re-using previously selected host id from ${flagfile}: $hostid"
} else {
Write-Host "Existing host id not found in ${flagfile}"
}
}
}
# if still not found, check old ProgramData location
if ([string]::IsNullOrEmpty($hostid)) {
$oldflagfile = $(Join-Path $OLDBASE "osquery.flags")
if ([System.IO.File]::Exists($oldflagfile)) {
$match = (Select-String -Path $oldflagfile -Pattern "specified_identifier=(.*)")
if ($match.Matches.Groups.success) {
$hostid = $match.Matches.Groups[1].Value.Trim()
Write-Host "Detected and re-using previously selected host id from ${oldflagfile}: $hostid"
} else {
Write-Host "Existing host id not found in ${oldflagfile}"
}
}
}
echo "Creating flag file"
copy $BASE\osquery.flags.example $flagfile
Write-Host "Setting host identifier"
# if still no hostid, use generated default
if ([string]::IsNullOrEmpty($hostid)) {
$hostid="00000000-8019-46ae-b324-685a63cb327a"
}
$output = "--tls_hostname=api.agent.alienvault.cloud/osquery-api/us-east-1", "--host_identifier=specified", "--specified_identifier=$hostid"
[IO.File]::AppendAllLines([string]$flagfile, [string[]]$output)
# add customer certs if present
$custpem = "$($env:SYSTEMROOT)\System32\drivers\etc\osquery_customer_certs.pem"
if ([System.IO.File]::Exists($custpem)) {
Write-Host "Adding customer certs"
type "$custpem" >> "$BASE\certs\certs.pem"
}
# start service
if (-NOT (AgentDoStop)) {
return
}
AgentDoStart
Write-Host "Deleting installer"
del $env:TEMP\alienvault-agent.msi
if (($BASE -ne $OLDBASE) -And [System.IO.Directory]::Exists($OLDBASE)) {
Write-Host "renaming old ProgramData/osquery directory"
move "$OLDBASE" "$($OLDBASE).renamed"
}
}
set-alias install_agent -value Install-Project
export-modulemember -alias 'install_agent' -function 'Install-Project'
}
If you remove this from "Function Install-Project-Internal"
If ($PSVersionTable.PSVersion.Major -lt 3) {
Write-Error "This script must be run using Powershell version 3 or higher. You have version $PSVersionTable.PSVersion.Major installed"
Return
}
Does it work? And if not, what is the error?

How I can pass multiple array in value in PowerShell function

Below function I want to pass multiple value in array. When I'm passing more than one value I am getting an error.
function CheckProcess([String[]]$sEnterComputerNameHere, [String[]]$sEnterProccessNameHere) {
#Write-Host " $sEnterComputerNameHere hello"
#($sEnterComputerNameHere) | ForEach-Object {
# Calling Aarray
#($sEnterProccessNameHere) | ForEach-Object {
if (Get-Process -ComputerName $sEnterComputerNameHere | where {$_.ProcessName -eq $sEnterProccessNameHere}) {
Write-Output "$_ is running"
} else {
Write-Output "$_ is not running"
}
}
}
}
$script:sEnterProccessNameHere = #("VPNUI") # Pass the process agreement here
$script:sEnterComputerNameHere = #("hostname") # Pass the process agreement here
CheckProcess $sEnterComputerNameHere $sEnterProccessNameHere
Give it a try with this one:
Function CheckProcess([String[]]$sEnterComputerNameHere,[String[]]$sEnterProccessNameHere)
{ #Write-host " $sEnterComputerNameHere"
#($sEnterComputerNameHere) | Foreach-Object {
$computer = $_
Write-Host $computer
#($sEnterProccessNameHere) | Foreach-Object {
$process = $_
Write-Host $process
try{
$x = get-process -computername $computer #Save all processes in a variable
If ($x.ProcessName -contains $process) #use contains instead of equals
{
Write-Output "$process is running"
}
else
{
Write-Output "$process is not running"
}
}
catch
{
Write-Host "Computer $computer not found" -ForegroundColor Yellow
}
}
}
}
$script:sEnterProccessNameHere = #("VPNUI","Notepad++","SMSS")
$script:sEnterComputerNameHere = #("remotecomputer1","remotecomputer2")
CheckProcess -sEnterComputerNameHere $sEnterComputerNameHere -sEnterProccessNameHere $sEnterProccessNameHere
In general, it would be great if you write the error you get in your question. That helps others to help you.
If I work with arrays and | Foreach, I always write the $_in a new variable. That helps if I have another | Foreach (like you had) to know for sure, with which object I'm working with..
EDIT: I changed the script, so it uses "-contains" instead of "-eq" and I added a try/catch block, so if the other computer is not found, it gives you a message.. It works on my network
EDIT2: Do you have access to the other computers? If you run get-process -computername "name of remote computer" do you get the processes?

Creating Registry Keys with Powershell

I am trying to check if a key-structure exists in the registry using powershell. If the structure does not exist, I need to create it and then I need to create the keys in the ending folder. If I run the snippets individually to create the keys, they create just fine. But running the block itself (ensuring manually within the registry that the keys don't exist) it won't create the folder structure. Not sure what the issue is. Any help would be appreciate. The code is as follows:
$Registry_Paths = "hkcu:\Software\Microsoft\Office\14.0", "hkcu:\Software\Microsoft\Office\14.0\Groove", "hkcu:\Software\Microsoft\Office\14.0\Groove\Development"
foreach($Registry_Path in $Registry_Paths)
{
$Test_Path_Result = Test-Path -Path $Registry_Path
if($Test_Path_Result -eq $false)
{
$Registry_Key_Log += "Warning: No registry key path found at " + $Registry_Path +"`n"
$Registry_Key_Log += "Creating key now for " + $Registry_Path + "`n" + "`n"
if($Registry_Path -eq "hkcu:\Software\Microsoft\Office\14.0")
{
try{
New-Item -Path "HKCU:\Software\Microsoft\Office\14.0" -ItemType Key
}
catch
{
$Error_Log += "Warning: There was an error when attempting to create a new registry key, or key property for $Registry_Path"
$Error_Log += $_.exception.message
}
}
if($Registry_Path -eq "hcku:\Software\Microsoft\Office\14.0\Groove")
{
try{
New-Item -Path "HKCU:\Software\Microsoft\Office\14.0\Groove" -ItemType Key
}
catch
{
$Error_Log += "Warning: There was an error when attempting to create a new registry key, or key property for $Registry_Path"
$Error_Log += $_.exception.message
}
}
if($Registry_Path -eq "hcku:\Software\Microsoft\Office\14.0\Groove\Development")
{
try{
New-Item -Path "HKCU:\Software\Microsoft\Office\14.0\Groove\Development" -ItemType Key
New-ItemProperty -Path "hkcu:\Software\Microsoft\Office\14.0\Groove\Development" -Value 00000001 -PropertyType dword -Name "EnableReleaseBuildDebugOutput"
New-ItemProperty -Path "hkcu:\Software\Microsoft\Office\14.0\Groove\Development" -Value 1 -Name "TraceIdentityMessaging"
New-ItemProperty -Path "hkcu:\Software\Microsoft\Office\14.0\Groove\Development" -Value 00000001 -PropertyType dword -Name "TraceTelespaceFetch"
New-ItemProperty -Path "hkcu:\Software\Microsoft\Office\14.0\Groove\Development" -Value 1 -Name "TraceConnectSequence"
}
catch
{
$Error_Log += "Warning: There was an error when attempting to create a new registry key, or key property for $Registry_Path"
$Error_Log += $_.exception.message
}
}
}
}
Here is how I'd do it.
$Key = "HKEY_CURRENT_USER\TEST"
If ( -Not ( Test-Path "Registry::$Key")){New-Item -Path "Registry::$Key" -ItemType RegistryKey -Force}
Set-ItemProperty -path "Registry::$Key" -Name "Less" -Type "String" -Value "Less"
function New-RegKey
{
# Create subkey in specified registry hive/key.
param (
[string]$Key
)
# Check if key exists or not:
if ($reg.GetSubKeyNames() -notcontains $Key)
{
Try
{
# The key DOES NOT exist, so create it:
$Script:reg = $reg.CreateSubKey($Key)
Write-Host "Registry key ""$($Script:reg.Name)"" has been successfully created." -foregroundColor Green
}
Catch
{
Write-Host "ERROR:$((($ERROR[0].Exception).InnerException).Message)." -ForegroundColor Yellow
}
}
else
{
Write-Host "Registry key ""$Key"" already exists. Do not need to create." -ForegroundColor White
# Open the subkey in writable mode and update the $reg in script scope:
Try
{
$Script:reg = $reg.OpenSubKey($Key, $Writable)
}
Catch
{
Write-Host "ERROR:$((($ERROR[0].Exception).InnerException).Message)."
-ForegroundColor Yellow
}
}
}
function Set-RegValue
{
param (
[string]$RegName,
[string]$RegValue,
[string]$RegValueType
)
# Create or update the specified registry value (valueName and valueValue):
# First check to see if the value name exists or not in the current key:
if ($reg.GetValueNames() -notcontains $RegName) {
# Registry value does not exist, so create one and assign value:
Try
{
$reg.SetValue($RegName, $RegValue, $RegValueType)
Write-Host "Registry value name ""$RegName"" does not exist, so create it and assign value ""$RegValue"" with type: ""$RegValueType""."
}
Catch
{
Write-Host "ERROR: $((($ERROR[0].Exception).InnerException).Message)." -ForegroundColor Yellow
}
}
else
{
Try
{
Write-Host "Registry value name ""$RegName"" already exists, so update its value ""$RegValue"" with type: ""$RegValueType""."
$reg.SetValue($RegName, $RegValue, $RegValueType)
}
Catch
{
Write-Host "ERROR:$((($ERROR[0].Exception).InnerException).Message)." -ForegroundColor Yellow
}
}
}
I got it working. Turns out I had a typo (hkcu != hcku):
if($Registry_Path -eq "hkcu:\Software\Microsoft\Office\14.0")
if($Registry_Path -eq "hcku:\Software\Microsoft\Office\14.0\Groove")
Note the "HKCU" and "HCKU" above.