Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PowerShell 7 support #1052

Open
ronan-lg opened this issue Jan 4, 2024 · 1 comment
Open

Add PowerShell 7 support #1052

ronan-lg opened this issue Jan 4, 2024 · 1 comment

Comments

@ronan-lg
Copy link

ronan-lg commented Jan 4, 2024

Is your feature request related to a problem? Please describe

As Get-ItemProperty output is different → parsing fails

  • Number of lines
  • Number of digits

Windows PowerShell 5.1

> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.22621.2506
PSEdition                      Desktop
> Get-ItemProperty -Path C:\Windows
0|
1|
2|    Répertoire : C:\
3|
4|
5|Mode                 LastWriteTime         Length Name
6|----                 -------------         ------ ----
7|d-----        29/12/2023   6:01 PM                Windows
  < 6  >

PowerShell 7

> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.3.10
PSEdition                      Core
> Get-ItemProperty -Path C:\Windows
0|
1|    Directory: C:\
2|
3|Mode                 LastWriteTime         Length Name
4|----                 -------------         ------ ----
5|d----          29/12/2023  6:01 PM                Windows
  < 5 >

In addition the output is colored:

b'd----          29/12/2023  6:01 PM                \x1b[44;1mWindows\x1b[0m'

Describe the solution you'd like

facts/windows_files.pyclass File(FactBase):process method

  • from
      def process(self, output):
          if len(output) < 7:
              return None
    
          # Note: The first 7 lines are header lines
          return parse_win_ls_output(output[7], self.type)
  • to
      def process(self, output):
          if len(output) < 5:
              return None
    
          # Note: The first lines are header lines
          return parse_win_ls_output(output[-2], self.type)

facts/util/win_files.pyWIN_LS_REGEX definition, relax the filetype and mode pattern

  • from
            # filetype and mode
            r"^([darhsl\-]{6})\s+"
  • to
            # filetype and mode
            r"^([darhsl\-]{5,6})\s+"

facts/util/win_files.pyparse_win_ls_output function, remove ansi sequences

  • from
      if output:
          matches = re.match(WIN_LS_REGEX, output)
  • to
      if output:
    
          # Patch to remove ansi sequences from PowerShell 7
          # @see https://stackoverflow.com/questions/14693701/how-can-i-remove-the-ansi-escape-sequences-from-a-string-in-python
          ansi_escape = re.compile(r"(\x9B|\x1B\[)[0-?]*[ -/]*[@-~]", flags=re.IGNORECASE)
          output = ansi_escape.sub('', output)
    
          matches = re.match(WIN_LS_REGEX, output)
@vojta001
Copy link

vojta001 commented Feb 4, 2024

I think a much more future-proof, clean and safe (with respect to various kinds of injections when running commands on untrusted hosts) way is to use a proper serialization (JSON/XML) for transport. It is even much easier to handle the results on pyinfra's side while simply switching from Get-ItemProperty -Path C:\Windows to Get-ItemProperty -Path C:\Windows | ConvertTo-Json and possibly requesting only a subset of fields for efficiency.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants