How to calculate the StartTime / UntilTime parameter using Get-Printer in Powershell?
Now im kinda depressed i cant figure out how the hell 18:40 is represented as the value 1000 and 3:00 as the value 60.
I tried to find the answer via google but the technical references are only giving me information like
-StartTime UInt32 — Specifies the starting time of printer availability.
So my question is how do i calculate the value represented by the parameter StartTime and UntilTime? If needed i can add more values. Just cant figure it out.
4 Answers 4
I believe both values are calculated in minutes since 12:00 AM GMT. That would put you in GMT+2. Does that work out properly?
Just to clarify on this — there are multiple tricks on this question:
1) Johnathan is right — it is a trick question. The trick, though, comes from the fact that a user can submit a job at ANY time to the printer, regardless of the availability of the printer. The job will just hold in queue until StartTime is reached — at which time, it will print.
2) As mentioned before, the printer is paused. Nothing prints, although users can send jobs at any time.
3) StartTime and UntilTime are computed using UTC, regardless of the time zone and they are in minutes. So, if you set your StartTime to 0100 UTC, it will show as «60». This trick uses «1000» to fool you into thinking it is «10 o’clock». It is actually 4:40pm UTC. «60» is going to be 1:00am UTC. «600» is going to be 10:00am UTC.
4) Since the question does not indicate the Time Zone, the times aren’t going to matter, because the clock times given in the question aren’t going to be the same, say, for me in UTC-7, for someone in UTC+2. So. ANOTHER trick.
PowerShell: системное администрирование и программирование
Всё о PowerShell в Windows и на Linux. Системное администрирование Windows
Тонкая настройка вывода с Format-Table
Командлет Format-Table для вывода данных в виде таблицы
Командлет Format-Table форматирует выходные данные команды в виде таблицы с выбранными свойствами объекта в каждом столбце. Тип объекта определяет макет по умолчанию и свойства, которые отображаются в каждом столбце. Вы можете использовать параметр -Property, чтобы выбрать свойства, которые вы хотите отобразить.
По умолчанию многие командлеты выводят данные оформленные в виде таблицы. В этом случае перенаправление вывода в Format-Table ничего не меняет.
Например, этот командлет выведет содержимое текущей папки:
И следующие набор команд также выведет содержимое текущей папки, при этом данные будут идентичными, в том числе по оформлению:
Но Format-Table не является бесполезным командлетом, поскольку с помощью его опций можно:
1. Изменять набор выводимых данных
2. Изменять внешний вид выводимых данных
Подробности смотрите в статьях:
- Как в PowerShell менять набор выводимых по умолчанию данных
- В PowerShell таблица не помещается на экран — как исправить (РЕШЕНО)
Опции Format-Table
-AutoSize
Указывает, что командлет регулирует размер столбца и количество столбцов в зависимости от ширины данных. По умолчанию размер и количество столбцов определяются используемым шаблоном (так называемый «вид», view). Таблица, выведенная с использованием параметра -AutoSize может быть более компактной за счёт уменьшения пространства между столбцами.
-DisplayError False|True
Указывает, что командлет отображает ошибки в командной строке. Этот параметр можно использовать в качестве вспомогательного средства отладки, когда вы форматируете выражения в команде Format-Table и вам необходимо устранить неполадки с выражениями.
-Force
Указывает, что командлет предписывает командлету отображать всю информацию об ошибках. Используйте с параметром -DisplayError или -ShowError. По умолчанию, когда объект ошибки записывается в потоки ошибок или отображения, отображается только некоторая информация об ошибках.
Задаёт отсортированный вывод в отдельных таблицах на основе значения свойства. Например, вы можете использовать -GroupBy для перечисления служб в отдельных таблицах в зависимости от их статуса.
Введите выражение или свойство. Параметр -GroupBy предполагает, что объекты отсортированы. Используйте командлет Sort-Object перед использованием Format-Table для группировки объектов.
Значение параметра -GroupBy может быть новым вычисляемым свойством. Чтобы создать вычисляемое свойство, используйте хеш-таблицу. Допустимые ключи следующие:
- Name (или Label) — `<строка>`
- Expression — `<строка>` или `<блок скрипта>`
- FormatString — `<строка>`
-HideTableHeaders
Пропускает заголовки столбцов из таблицы.
-InputObject
Указывает объекты для форматирования. Введите переменную, содержащую объекты, или введите команду или выражение для получения объектов.
Чтобы понять принцип работы этого параметра, посмотрите на следующую команду:
и на идентичную предыдущей эту команду:
-Property <Object[]>
Задаёт свойства объекта, отображаемые на дисплее, и порядок их появления. Введите одно или несколько имён свойств, разделённых запятыми, или используйте хеш-таблицу для отображения вычисляемого свойства. Подстановочные знаки разрешены.
Если вы опустите этот параметр, свойства, отображаемые на дисплее, будут зависеть от свойств первого объекта. Например, если у первого объекта есть PropertyA и PropertyB, а у последующих объектов есть PropertyA , PropertyB и PropertyC , то будут отображаться только заголовки PropertyA и PropertyB.
Параметр -Property является необязательным. Вы не можете использовать параметры -Property и -View в одной и той же команде.
Значение параметра -Property может быть новым вычисляемым свойством. Чтобы создать вычисляемое свойство, используйте хеш-таблицу. Допустимые следующие ключи:
- Name (или Label) = `<строка>`
- Expression = `<строка>` или `<скриптовый блок>`
- FormatString = `<строка>`
- Width = `<int32>`
- Alignment = значением может быть Left, Center или Right
-RepeatHeader
Повторяет отображение заголовка таблицы после каждого заполнения экрана. Повторяющийся заголовок полезен, когда вывод направляется на программу, разделяющую вывод на страницы, такие как «less» или «more», или пейджинг с помощью программы чтения с экрана.
-ShowError
Этот параметр отправляет ошибки через конвейер. Этот параметр можно использовать в качестве средства отладки, когда вы форматируете выражения в команде Format-Table и вам необходимо устранить неполадки с выражениями.
Отображает текст, превышающий ширину столбца, на следующей строке. По умолчанию текст, превышающий ширину столбца, обрезается.
Примеры использования Format-Table
Пример 1: Подстройка размера таблицы под выводимые данные.
В этом примере в виде таблицы отображаются сведения о хост программе для PowerShell.
Get-Host | Format-Table -AutoSize
Командлет Get-Host получает объекты System.Management.Automation.Internal.Host.InternalHost, представляющие хост. Объекты передаются по конвейеру в Format-Table и отображаются в таблице. Параметр -AutoSize регулирует ширину столбцов, чтобы свести к минимуму усечение.
Пример 2: Форматирование процессов по BasePriority
В этом примере процессы отображаются в группах с одинаковым свойством BasePriority.
Командлет Get-Process получает объекты, представляющие каждый процесс на компьютере, и отправляет их по конвейеру в Sort-Object. Объекты сортируются в порядке их свойства BasePriority.
Отсортированные объекты отправляются по конвейеру в Format-Table. Параметр -GroupBy упорядочивает данные процесса в группы на основе значения их свойства BasePriority. Параметр -Wrap гарантирует, что данные не будут усечены.
Пример 3: Форматирование процессов по дате запуска
В этом примере отображается информация о процессах, запущенных на компьютере. Объекты сортируются, и Format-Table использует представление для группировки объектов по дате их запуска.
Командлет Get-Process получает объекты System.Diagnostics.Process, представляющие процессы, запущенные на компьютере. Объекты отправляются по конвейеру в Sort-Object и сортируются на основе свойства StartTime.
Отсортированные объекты отправляются по конвейеру в Format-Table. Параметр -View указывает представление StartTime, определённое в файле PowerShell DotNetTypes.format.ps1xml для объектов System.Diagnostics.Process. Представление StartTime преобразует время начала каждого процесса в короткую дату, а затем группирует процессы по дате начала.
Файл DotNetTypes.format.ps1xml содержит представление Priority для процессов. Вы можете создавать свои собственные файлы format.ps1xml с настроенными представлениями.
Пример 4: Использование свойств для вывода таблицы
В этом примере параметр -Property используется для отображения всех служб компьютера в таблице с двумя столбцами, в которой показаны свойства Name и DependentServices.
Get-Service получает все службы на компьютере и отправляет объекты System.ServiceProcess.ServiceController по конвейеру. Format-Table использует параметр -Property, чтобы указать, что в таблице нужно отображать только свойства Name и DependentServices.
Name и DependentServices — это два свойства типа объекта. Чтобы просмотреть все свойства, выполните команду:
Пример 5: Форматирование вывода о процессе и расчёт времени его выполнения
В этом примере отображается таблица с именем процесса и общим временем выполнения для запущенных процессов программы Блокнот на локальном компьютере. Общее время выполнения рассчитывается путём вычитания времени запуска каждого процесса из текущего времени.
Командлет Get-Process получает все процессы блокнота локального компьютера и отправляет объекты по конвейеру. Format-Table отображает таблицу с двумя столбцами: «ProcessName» (свойство Get-Process), и «Время работы» (вычисляемое свойство).
Свойство «Время работы» задаётся хэш-таблицей с двумя ключами: Label и Expression. Ключ Label задаёт имя свойства. Expression задаёт вычисление. Выражение получает свойство StartTime каждого объекта процесса и вычитает его из результата команды Get-Date, которая получает текущую дату и время.
При желании, заголовок первого столбца также можно русифицировать:
Пример 6: Форматирование вывода информации о процессе
В этом примере командлет Get-CimInstance используется для получения времени выполнения всех процессов блокнота на локальном компьютере. Командлет Get-CimInstance можно использовать с параметром -ComputerName для получения информации с удалённых компьютеров.
Get-CimInstance получает экземпляры класса WMI Win32_Process, который описывает все процессы локального компьютера с именем notepad.exe. Объекты процесса хранятся в переменной $Processes.
Объекты процесса в переменной $Processes отправляются по конвейеру в Format-Table, которая отображает свойство ProcessName и новое вычисляемое свойство Total Running Time.
Команда присваивает имя нового вычисляемого свойства Total Running Time ключу Label. Блок сценария ключа Expression вычисляет, как долго выполняется процесс, вычитая дату создания процесса из текущей даты. Командлет Get-Date получает текущую дату. Дата создания вычитается из текущей даты. Результатом является значение Total Running Time.
Пример 6: Устранение ошибок формата
В следующих примерах показаны результаты добавления к выражению параметров -DisplayError или -ShowError.
Adding time started and time stopped to my script
![]()
I have a simple script that copies all files and folders from Server A to Server B. I would like to know how long the entire script took to run.
Any idea how I can figure out how long it took to copy all?
![]()
This seeemed to work great!
I used while troubleshooting Exchange Online throttling. Useful. Just don't forget to close it when you are done.
Ready, Set, Wait! PowerShell Timers.
Okay, we’ve all been there. Yeah, you know, the time you need to automate something around some kind of process or task that is less than cooperative or predictable. Sometimes it finishes, but sometimes it gets hung up, and your script gets stuck in a loop… forever and ever and ever.

This is a trick I have used at work a few times. Let me be forward and state, every time I have implemented this solution to “fix” a problem, it is generally due to me coding around something bug ridden, or sporadically unpredictable that is entirely outside of my control.
With that said this is also useful to record timings on jobs that run long but definitely do have a set end time.
You may also be thinking, “Rob, I already have a method to do this using Start-Sleep and an incrementing index!”. You know what, that is completely valid too, this is just a different way to solve the same problem!
Let’s write some awful code to demonstrate this!
Okay, feel free to watch this gif, it’s entirely too long, and it will never end. It is still running on my computer to this day (not really).
Say this is some task you need to wait for in your automation, you need a way to defensively code in that failsafe “enough is enough just stop running already!”.
Our Working Example
If you want to follow along at home, you can use the following whipped up code to simulate something a little better than while loop based on a condition of $true . This is what will be used for the rest of this write up.
This block of code will open up calculator (on Windows) and then enter a do loop checking any matching processes until it doesn’t find one 1 . This loop will run as long as any calculator is open, you can close it and end the loop, but this is to simulate a situation where you can’t.
Imagine in this situation you can’t stop the calculator, or maybe checking a locked file, or waiting for a VMware Guest OS customization to finish.
Okay let’s implement a workaround!
Time This
Where do you start? You have a do loop doing some stuff that could get nasty, so you’ll need to add some logic to your until . Currently your until is only checking if a calculator is open, but you can add some additional logic to it.
Create the StopWatch
You’ll need to instantiate a [System.Diagnostics.StopWatch] object.
“What the heckin’ cuss Rob, I am not a C# developer, what in tarnation are you saying!?”
Many of you probably have done this without realizing, and if you haven’t it’s easy. You just need to use New-Object to create a stopwatch! It’s as easy as 1, 2, $stopWatch = New-Object -TypeName System.Diagnostics.Stopwatch !
Boy howdy, that was easy, right? Did you see those nifty methods? You can use them to…
- Start the stopwatch
- Stop the stopwatch
- Restart the stopwatch (and start running from 0 again)
- Reset the stopwatch (and keep it stopped)
- Use the .Elapsed property to get the elapsed time as a [System.TimeSpan]
You can give it a try yourself!
Okay, you’re keeping time now, but a timer isn’t really useful by itself. You’ll need to evaluate how much time has passed in for your check when you add it to the until logic.
You could just do something like $stopWatch.Elapsed.Seconds -ge 60 if you want to wait until 60 seconds has passed. This works, but can get complex if you want to wait for a more defined time span. For example, if you want to wait 1 day, 5 hours, 34 minutes and 9 seconds this logic is going to get pretty annoying to maintain.
Create the TimeSpan
You can use a TimeSpan to do the time math, why even bother with comparative logic for time when you have PowerShell to handle that peasant work for you?
You can use New-TimeSpan to create a [System.TimeSpan] object. You can then use this time span to do comparative logic against your timers elapsed time!
Remember that the .Elapsed property returns a [System.TimeSpan] of your timer. You can even double check if you’d like by running ($stopWatch.Elapsed).GetType()

Now create a time span with New-TimeSpan . For this, you can create it with 1 minute and 30 seconds.

Time Math
If you were playing around with your stopwatch, make sure you stop and reset it before continuing if you are following along.
You can very easily do comparisons between your time span, and your stopwatches elapsed time now as they are both of type [System.TimeSpan] . Even your current elapsed time at 0, you can still see the comparison.
Would you look at that?! Comparing time has never been easier!

Now that we know how to do that, let’s use all of this to solve our original problem!
Putting it all Together
Okay, now that we know how to create a timer and a time span, let’s use those to solve the long running calculator job.
You can even use the code from above with modified values! 2
You can see with not much modification you now have a timer condition built into your job.

Now when you run the code if you don’t close the calculator in 1 minute and 30 seconds, the script will stop running. You could have it throw an exception, or handle this in some other way, but now you have the flexibility to do so!
That Start-Sleep on line 2 may not be needed. I found my computer was so awesomely powerful and fast that when the first check for the calculator process ran it wasn’t fully open yet! If you’re running a Packard Bell from 1996 you might not need that Start-Sleep , otherwise just leave it. ↩