I have an Apache service 'SERV[XYZ]' in my Windows services and I would like to be able to start it from a PowerShell script.
In the script, I added variable holding service name:
$serv = "SERV[XYZ]";
stop-service $serv;
start-service $serv;
but this does not start the service. PowerShell executes without error.
The *-Service cmdlets do wildcard matches on the service name. See for instance the documentation of Start-Service:
Parameters
-DisplayName<String[]>
Specifies the display names of the services to be started. Wildcards are permitted.
The pattern [XYZ] means "match any of the characters X, Y, or Z" (like in regular expressions), so your statements try to stop/start services named SERVX, SERVY and/or SERVZ. To match a literal string [XYZ] you need to prevent the square brackets from being treated as special characters, e.g. like this:
$serv = 'SERV[[]XYZ[]]'
Stop-Service $serv
Start-Service $serv
If you have only one service whose name starts with SERV you could also use a pattern like SERV*, or perhaps SERV?XYZ? where the ? (wildcard matching a single character) mask the square brackets.
Another option would be to use Get-Service without a name and filter the results via Where-Object:
$serv = 'SERV[XYZ]'
Get-Service | Where-Object { $_.Name -eq $serv } | Stop-Service
Get-Service | Where-Object { $_.Name -eq $serv } | Start-Service
Related
I have continuous automated application deployment building on Azure DevOps server 2019(ex TFS). Part of deploy is checking the Oracle DB status, before running scripts, the script below works for a year, and ones (probably after latest Azure DevOps server update 2019.1) it stops working with an error:
SQL> SP2-0734: unknown command beginning " select..." - rest of line ignored.
SQL> SP2-0734: unknown command beginning " select..." - rest of line ignored.
$chekdbsql = 'select status from v$instance;'
$i = 1
$chkdb = ""
while ($chkdb.Contains("OPEN") -ne 'True') {
Clear-Variable -Name chkdb
$chkdb = ($chekdbsql | cmd /c "sqlplus -s user/password#localhost/ora as sysdba")
if ($chkdb.Contains("OPEN") -eq 'True'){
break
}
echo "Trying to connect to database. Attempt $i"
sleep 10
$i++ }
write-host "Connected! Database's status is 'open'." -ForegroundColor green
If I tried to execute command locally on the machine where the application is built - it's work well.
The space before select makes me think it's a character encoding issue. See e.g. this, this
beginning " select..."
I'm not familiar enough with powershell to know what the problem is. I can think of a workaround, but it's a bit of a hack.
$chekdbsql = "`nselect status from v`$instance;"
This makes sure that whatever garbage characters are getting inserted at the beginning of the string will be on their own line in SQL*Plus. So if you get a SP2-0734, your select command will still run after that. Since it's now a double-quoted string, I escaped the $.
In my email today I received an email about getting unused drive letters. This was their solution:
Get-ChildItem function:[d-z]: -Name | Where-Object {-not (Test-Path -Path $_)}
PowerShell Magazine BrainTeaser had this for a solution, same thing.
ls function:[d-z]: -n|?{!(test-path $_)}|random
I have no idea how function:[d-z]: works. I know that for each character between 'd' to 'z' is used but I don't know why the syntax works.
Testing Get-ChildItem function:[d-a]: -Name gives you an error saying Get-ChildItem : Cannot retrieve the dynamic parameters for the cmdlet. The specified wildcard pattern is not valid:[d-a]:
So is that a dynamic parameter? How come is does not show up with Get-Help gci -full?
function: is a PSDrive which exposes the set of functions defined in the current session. PowerShell creates a function for each single letter drive, named as the letter followed by a colon.
So, function:[d-z]: lists the functions from "d:" through "z:"
function:[d-a]: doesn't work because , d-a isn't a range of letters.
I wrote a command line
sc query PlugPlay | FIND "SERVICE_NAME" | FIND "STATE"
to list only the service name and its status but it's not giving any output.
Please correct me how to list the service name and its STATE (running or stopped) only.
You can do this with Windows' built-in findstr command. If you give it multiple words to find, separated by spaces, it will print lines that match any word (i.e. findstr "a b" is equivalent to grep -E 'a|b').
sc query plugplay | findstr "SERVICE_NAME STATE"
Running two pipes like that is not an "or" operation, it is an "and" operation. It will only output lines that include both SERVICE_NAME and STATE (which will be none, so no output is correct). If you run just the first find it gives
C:\>sc query PlugPlay | FIND "SERVICE_NAME"
SERVICE_NAME: PlugPlay
C:\>
and thus the STATE information is already removed.
The windows find command is too simple and limited to do what you want, but it can be achieved using the unix grep command. From cygwin for instance:
$ sc query PlugPlay | grep -E 'SERVICE_NAME|STATE'
SERVICE_NAME: PlugPlay
STATE : 4 RUNNING
$
I have an admin server, NodeManager, and 1 managed server, all on the same machine.
I am trying to enter something similar to this to the arguments field in the Server Start tab:
-Dmy.property=%USERPROFILE%\someDir\someJar.jar
But when the managed server is started it throws this exception:
Error opening zip file or JAR manifest missing : %USERPROFILE%\someDir\someJar.jar
It appears that the environment variable is not being translated into it's value. It is just passed on to the managed server as plain-text.
I tried surrounding the path with double quotes (") but the console validates the input and does not allow this: "Arguments may not contain '"'"
Even editing the config.xml file manually cannot work, as the admin server fails to startup after this:
<Critical> <WebLogicServer> <BEA-000362> <Server failed. Reason: [Management:141266]Parsing failure in config.xml: java.lang
.IllegalArgumentException: Arguments may not contain '"'.>
I also tried using %20 to no avail, it is just passed as %20.
I thought that perhaps this had something to do with the spaces in the value of %USERPROFILE% (which is "C:\documents and settings.."), but the same thing happens with other env. variables which point to other directories with no spaces.
My question:
Is there any supported way of :
using double quotes? what if i have to reference a folder with spaces in it's name?
reference an environment variable? What if i have to rely on it's value for distributed servers where i do not know in advance the variable's value?
Edit based on comments:
Approach 1:
Open setDomainEnv.cmd and search for export SERVER_NAME in Linux or for set SERVER_NAME in Windows. Skip to next to next line (i.e skip current and the next line)
On the current line, insert:
customServerList="server1,server2" #this serverList should be taken as input
isCurrServerCustom=$(echo ${customServerList} | tr ',' '\n' | grep ${SERVER_NAME} | wc -l)
if [ $isCurrServerCustom -gt 0 ]; then
# add customJavaArg
JAVA_OPTIONS="-Dmy.property=${USERPROFILE}/someDir/someJar.jar"
fi
Save the setDomainEnv.sh file and re-start servers
Note that I have only given logic for Linux , for Windows similar logic can be used but with batch scripting syntax.
Approach 2:
Assuming domain is already installed and user provides the list of servers to which the JVM argument -Dmy.property need to be added. Jython script (use wlst.sh to execute). WLST Reference.
Usage: wlst.sh script_name props_file_location
import os
from java.io import File
from java.io import FileInputStream
# extract properties from properties file.
print 'Loading input properties...'
propsFile = sys.argv[1]
propInputStream = FileInputStream(propsFile)
configProps = Properties()
configProps.load(propInputStream)
domainDir = configProps.get("domainDir")
# serverList in properties file should be comma seperated
serverList = configProps.get("serverList")
# The current machine's logical name as mentioned while creating the domain has to be given. Basically the machine name on which NM for current host is configured on.
# This param may not be required as an input if the machine name is configured as same as the hostname , in which case , socket module can be imported and socket.getHostName can be used.
currMachineName = configProps.get("machineName")
jarDir = os.environ("USERPROFILE")
argToAdd = '-Dmy.property=' + jarDir + File.separator + 'someDir' + File.separator + 'someJar.jar'
readDomain(domainDir)
for srvr in serverList.split(",") :
cd('/Server/' + srvr)
listenAddr = get('ListenAddress')
if listenAddr != currMachineName :
# Only change current host's servers
continue
cd('/Server/' + srvr + '/ServerStart/' + srvr)
argsOld = get('Arguments')
if argsOld is not None :
set('Arguments', argsOld + ' ' + argToAdd)
else:
set('Arguments', argToAdd)
updateDomain()
closeDomain()
# now restart all affected servers (i.e serverList)
# one way is to connect to adminserver and shutdown them and then start again
Script has to be run from all hosts where the managed servers are going to be deployed in order to have the host specific value of "USERPROFILE" in the JVM argument.
BTW, to answer your question in a line : looks like the JVM arguments have to be supplied with the literal text eventually. But looks like WLS doesn't translate the environment variables if provided as JVM arguments. It gives an impression that it is translating when its done from startWebLogic.cmd (ex: using %DOMAIN_HOME% etc.) but its the shell/cmd executor that translates and then starts the JVM.
I'm trying to use a variable as a command's parameter but can't quite figure it out. Let's say MyCommand will accept two parameters: option1 and option2 and they accept boolean values. How would I use $newVar to substitute option 1 or 2? For example:
$newVar = "option1"
MyCommand -$newVar:$true
I keep getting something along the lines of 'A positional parameter cannot be found that accepts argument '-System.String option1'.
More Specifically:
Here, the CSV file is an output of a different policy. The loop goes through each property in the file and sets that value in my policy asdf; so -$_.name:$_.value should substitute as -AllowBluetooth:true.
Import-Csv $file | foreach-object {
$_.psobject.properties | where-object {
# for testing I'm limiting this to 'AllowBluetooth' option
if($_.name -eq "AllowBluetooth"){
Set-ActiveSyncMailboxPolicy -Identity "asdf" -$_.name:$_.value
}}
}
Typically to use a variable to populate cmdlet parameters, you'd use a hash table variable, and splat it, using #
$newVar = #{option1 = $true}
mycommand #newVar
Added example:
$AS_policy1 = #{
Identity = "asdf"
AllowBluetooth = $true
}
Set-ActiveSyncMailboxPolicy #AS_policy1
See if this works for you:
iex "MyCommand -$($newVar):$true"
I had the same Problem and just found out how to resolve it. Solution is to use invoke-Expression: invoke-Expression $mycmd
This uses the $mycmd-string, replaces variables and executes it as cmdlet with given parameters
Nowadays, If you don't mind evaluating strings as commands, you may use Invoke-Expression:
$mycmd = "MyCommand -$($newVar):$true"
Invoke-Expression $mycmd
I would try with:
$mycmd = "MyCommand -$($newVar):$true"
& $mycmd
result
Can't work because the ampersand operator just execute single commands without prameters, or script blocks.