Вопрос: Как установить переменную окружения из команды powershell?


Я хочу иметь переменную окружения, которая содержит день недели в cmd.exe.

Когда я запускаю эту команду, я получаю результат, который я хочу.

C:\Users\tisc>powershell (get-date).dayofweek
Friday

Здесь я пытаюсь сохранить результат в переменной среды.

C:\Users\tisc>set dow = powershell (get-date).dayofweek

Но когда я пытаюсь его получить, я не получаю строку, как мне хотелось.

C:\Users\tisc>set dow
DoW=0
dow = powershell (get-date).dayofweek

Моя цель - использовать переменную в пакетном файле для некоторых сценариев резервного копирования.


27
2018-01-13 09:56


Источник




Ответы:


вы можете использовать что-то вроде:

$env:DOW = "foo"

45
2018-06-08 01:28



Я не понимаю, почему это было отмечено негативно, знаете ли вы, что лучше устанавливать переменные среды? - Ion Todirel
+1 Это отлично работает для меня в сценарии, который мне нужен. PowerShell -Command $env:Note = 'Elevate'; (New-Object -com 'Shell.Application').ShellExecute('cmd.exe', '/k %*', '', 'runas') - David Ruhmann
@IonTodirel Поскольку это только сохраняется в пространстве процесса. - JohnD
наконец, я теперь понимаю, как установить RAILS_ENV в powershell - wired00


Я считаю, что установка переменной окружения изнутри powershell с [Environment]::SetEnvironmentVariable как предложил Дэн, бессмысленно, потому что вы потеряли бы содержимое переменной после прекращения полномочий, если бы вы выбрали временный контекст «процесса» или не имели бы его в среде вашего пакетного файла все же если вы выбрали постоянный «машинный» или «пользовательский» контекст, то есть, если весь ваш сценарий не написан в PowerShell, где проблема не возникла в первую очередь:

C:\Users\myuser>echo %DOW%
%DOW%

C:\Users\myuser>powershell
Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. Alle Rechte vorbehalten.

PS C:\Users\myuser> $dow = (get-date).dayofweek
PS C:\Users\myuser> [Environment]::SetEnvironmentVariable("DOW", $dow, "User")
PS C:\Users\myuser> [Environment]::SetEnvironmentVariable("DOW", $dow, "Process")
PS C:\Users\myuser> exit

C:\Users\myuser>echo %DOW%
%DOW%

C:\Users\myuser>

Вы можете использовать for команду в качестве обходного пути для синтаксического анализа вывода команды powershell и перевода его в переменную

  for /F "usebackq tokens=1" %%i in (`powershell ^(get-date^).dayofweek`) do set DOW=%%i

Обратите внимание на символы каретки ^ используется, чтобы избежать специальных символов в скобках в вашем вызове powershell.

Если вы тестируете его из командной строки, а не из контекста пакетного файла, вам нужно будет заменить %% перед ссылками на переменные %:

C:\Users\myuser>for /F "usebackq tokens=1" %i in (`powershell ^(get-date^).dayofw
eek`) do set DOW=%i

C:\Users\myuser>set DOW=Friday

C:\Users\myuser>

13
2018-01-13 10:15



Нет, это неверно. Мой пример ниже устанавливает «нормальные» переменные среды, доступные из любого пакетного файла и т. Д. - Dan
@ Dan Я считаю, что вы ошибаетесь, я пробовал настройку [Environment]::SetEnvironmentVariable("DOW", $dow, "user") из сеанса работы powershell, но он не присутствовал в моей родительской сессии cmd после завершения PowerShell - the-wabbit
Форматирование ввернулось, но вы не определили $ dow. Запуск моего примера в сценарии Powershell хранит нормальную переменную окружения, как ожидалось. - Dan
@ Да, у меня есть. И, очевидно, переменная среды сохраняется для процесса powershell но он изолирован от родительского CMD-процесса и к нему нельзя получить доступ. Просто проверьте это и посмотрите. - the-wabbit
@ Dan BTW: Я не против downvoting, но следует отметить, что продемонстрированный подход четко делает то, что задал вопрошающий, поэтому, даже если бы был более элегантный подход, это все равно было бы правильным решением проблемы. - the-wabbit


Вы должны запускать обе команды в PowerShell, поскольку Powershell более чем способен манипулировать переменными среды.

т.е .:

$dow = (get-date).dayofweek
[Environment]::SetEnvironmentVariable("DOW", $dow, "Machine")

или

[Environment]::SetEnvironmentVariable("DOW", $dow, "User")

Кстати, ваш скрипт не работает, потому что все, что вы получаете, это код возврата Powershell, а не данные, которые он производит. Возможно, есть способ заставить его работать, но в конечном счете бессмысленно по сравнению с использованием собственно сценария Powershell.

Для полноты, вот хорошая статья от MS по Powershell и Environmental Variables:

http://technet.microsoft.com/en-us/library/ff730964.aspx

Обновить: Просмотрев это решение с помощью @ syneticon-dj в чате, кажется, что проблема, с которой вы сталкиваетесь, с помощью этого метода заключается в том, что необходимо перезагрузить командную строку, прежде чем она будет отражать изменения внешних переменных, которые произошли извне.

Вы не предоставили подробных сведений о том, что вы делаете, но если это единственная причина, по которой вы запускаете Powershell, то мое фактическое предложение будет касаться того, как вы делаете.

Либо выполняйте весь процесс с помощью PowerShell, либо считаете, что используете запланированные задачи? Вы можете планировать задания в зависимости от дня недели.


11
2018-01-13 10:03



Командный файл будет запускаться каждый день и запускаться из запланированных задач. Я думаю о том, чтобы работать в powershell вместо этого. Но им еще больше новичка в powershell, чем cmd. И прямо сейчас у меня возникают трудности с простой командой. Но я могу задать новый вопрос об этом, может быть, это очень просто для вас :) EDIT: Я понял это. Это было как запустить программу с некоторыми параметрами. - Tim
Я тоже не очень хорош в PowerShell, но хорошо учиться. Для начала это почти лучше, но так же, как и Microsoft (и другие производители). - Dan
Кроме того, обратите внимание, что приведенное выше предложение @ Dan устанавливает переменные окружения на постоянной основе (в контексте Machine или User). Если вы оставите третий параметр, вы можете установить его только для текущего процесса, что иногда более желательно. - Per Lundberg


Если бы это был я, а родительский скрипт имеет чтобы быть сценарием оболочки, я просто навязчивый вызов PowerShell в сценарии .CMD, например:

set DOW=
for /f %%D in ('%SystemRoot%\System32\WindowsPowerShell\V1.0\powershell.exe -NoLogo -NoProfile -Command Write-Host -Object ^(Get-Date^).DayOfWeek;') do set DOW=%%D

Возможно, вам потребуется проверить политику выполнения PowerShell (командлет Set-ExecutionPolicy).


3
2018-06-08 21:13





Или, если вы женаты, чтобы сделать это в старой оболочке, полностью пропустите Powershell.

Используйте переменную% date% и раскройте день с аббревиатуры, которую она дает (на это могут влиять региональные настройки формата даты)

C:\>echo %date%
Thu 09/05/2013

Возьмите первый ответ в ответ и расширьте его:

C:\>type dayofweek.cmd
@echo off
for /f %%A in ("%date%") do set DAYOFWEEK=%%A
if "%DAYOFWEEK%" == "Mon" set DAYOFWEEK=Monday
if "%DAYOFWEEK%" == "Tue" set DAYOFWEEK=Tuesday
if "%DAYOFWEEK%" == "Wed" set DAYOFWEEK=Wednesday
if "%DAYOFWEEK%" == "Thu" set DAYOFWEEK=Thursday
if "%DAYOFWEEK%" == "Fri" set DAYOFWEEK=Friday
if "%DAYOFWEEK%" == "Sat" set DAYOFWEEK=Saturday
if "%DAYOFWEEK%" == "Sun" set DAYOFWEEK=Sunday
echo.%DAYOFWEEK%
C:\>
C:\>dayofweek
Thursday

2
2017-09-05 15:04





Если вы хотите, чтобы ваш пакетный файл обращался к переменным среды, заданным командой powsershell, запускаемой из этого командного файла, вы можете использовать следующее обходное решение:

создайте файл powershell, создайте файл подкачки mysub.bat, содержащий строки «set variable = value», и выполните этот командный файл mysub.bat из основного командного файла сразу после команды powershell.

Используйте метод WriteAllLines, а не стандартные методы вывода powsershell, чтобы дополнительный файл пакета не был сгенерирован в формате кодировки UTF-8.

ПРИМЕР

main.bat:

REM main.bat first line
powershell -Command "[System.IO.File]::WriteAllLines(\".\mysub.bat\", \"set VARIABLE=VALUE\");"
.\mysub.bat
echo VARIABLE=%VARIABLE%
REM expected output: VARIABLE=VALUE

0
2018-01-05 17:21





Фактически, когда вы помещаете что-то вроде ниже в файл ps1 (скажем t.ps1) и вызываете его из сеанса CMD с помощью PowerShell -File t.ps1 ... это работает хорошо.

$DateAndTime = (get-date -UFormat "%Y%m%d_%H%M%S")[Environment]::SetEnvironmentVariable("DateAndTime", $DateAndTime, "Machine")

Но не для сеанса CMD, из которого был вызван сценарий t.ps1. В новой CMD-сессии мы получаем:

D:> echo% DateAndTime% ==> 20120208_123106

Я думаю, нам нужно выяснить, как сделать что-то вроде export T=date в сеансе CMD.


0
2018-02-08 11:55