Я хочу иметь переменную среды, которая содержит день недели в 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
Моя цель - использовать переменную в пакетном файле для некоторых сценариев резервного копирования.
Вы можете использовать что-то вроде:
$env:DOW = "foo"
Вы должны запустить обе команды в PowerShell, поскольку PowerShell более чем способен манипулировать переменными среды.
То есть:
$dow = (get-date).dayofweek
[Environment]::SetEnvironmentVariable("DOW", $dow, "Machine")
или
[Environment]::SetEnvironmentVariable("DOW", $dow, "User")
Кстати, ваш скрипт не работает, потому что все, что вы получаете, - это код возврата PowerShell, а не данные, которые он производит. Возможно, есть способ заставить его работать, но в конечном итоге это бессмысленно по сравнению с простым использованием надлежащего сценария PowerShell.
Для полноты, вот хорошая статья от Microsoft о PowerShell и переменных окружения:
Создание и изменение переменных среды
Обновить: Рассмотрев это решение с помощью @ syneticon-dj в чате, похоже, проблема, с которой вы сталкиваетесь при использовании этого метода, заключается в том, что командная строка должна быть перезагружена, прежде чем она отразит изменения в переменных среды, которые произошли извне.
Вы не предоставили много подробностей о том, что вы делаете, но если это единственная причина, по которой вы запускаете PowerShell, то мое реальное предложение - проверить, как вы это делаете.
Либо весь ваш процесс использует PowerShell, либо вы рассматривали возможность использования вместо этого запланированных задач? Вы можете планировать задачи в зависимости от дня недели.
Я считаю, что установка переменной среды из PowerShell с помощью [Environment]::SetEnvironmentVariable
как предлагает Дэн, бессмысленно, потому что вы либо потеряете содержимое переменной при завершении PowerShell, если выберете временный контекст «процесса», либо не будете иметь его в среде вашего пакетного файла все же если вы выбрали постоянный «машинный» или «пользовательский» контекст - то есть, если весь ваш скрипт не написан на 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>
Если бы это был я, а родительский скрипт имеет чтобы быть сценарием оболочки, я бы просто дерзко вызвал 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).
Или, если вы хотите делать это в старой оболочке, полностью пропустите 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
На самом деле, если поместить что-то подобное в файл .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.
Если вы хотите, чтобы ваш пакетный файл имел доступ к переменным среды, которые устанавливаются командой PowerShell, запущенной из этого пакетного файла, вы можете использовать следующий обходной путь:
Создайте сценарий PowerShell для создания вспомогательного пакетного файла, mysub.bat
, который содержит строки «установить переменную = значение», и выполнить этот командный файл mysub.bat из основного командного файла сразу после команды PowerShell.
Используйте метод WriteAllLines вместо методов вывода PowerShell по умолчанию, чтобы вспомогательный пакетный файл не создавался с форматом кодировки 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