【运维】PowerShell编程 目录文件相关方法的封装与案例详解

简介: 本文实现一个目录管理类,归纳了 Powershell 中常用的文件路径方法。这些方法可以迅速方便的用于 Powershell 编写大型运维脚本中。以简单使用为目的封装常用目录文件操作。完成源代码在作者的github上可以找到。

PowerShell 目录文件管理


目录文件相关方法的封装与案例详解

李俊才 的个人博客https://blog.csdn.net/qq_28550263?type=blog

已入驻阿里云

邮箱 :291148484@163.com
本文地址
- https://developer.aliyun.com/article/
- https://blog.csdn.net/qq_28550263/article/details/124378032

本文通过以一个 Path 类,归纳了 Powershell 中常用的文件路径方法。这些方法可以迅速方便的用于 Powershell 编写大型运维脚本中。


目 录


1. 获取绝对路径

2. 文件名

3. 获取盘符

4. 当前系统临时目录

5. 上级路径

6. 文件或者目录是否实际存在

7. 获取相对路径

8. 获取目录的当前子项目

9. 递归获取目录的所有子孙项目

10. 在指定目录下筛选文件

11. 在指定目录下筛选目录

12. 获取文件或者目录的修改时间

13. 判断指定路径是否实际是一个文件夹

14. 判断指定路径是否实际是一个文件

15. 判断文件时间是否早于某个值

16. 判断目录是否为空

17. 判断某个路径值是否为绝对路径

18. 获取目录的属性描述符

19. 判 断是否包含某个属性描述符

20. 计算文件或目录的大小

21. 连结多个路径

22. 拆分路径

23. 创建目录

24. Path 环境变量相关方法

25. 删除路径对应的项目

附录1: Path类代码

附录2: 脚本位置


1. 获取绝对路径

static [string]abspath([string]$path){
    <#
    Return absolute path
    Params
    ======
    - $path [string] Path of file.
    #>
    return Resolve-Path -Path $path; 
}

如图:

2. 文件名

static [string]basename([string]$path){
    <#
    Returns the file name from the absolute path value represented by a string.
    Params
    ======
    - $path [string] The absolute path of the file.
    - $extension [bool] Whether to remove the extension.
    #>
    return  [System.IO.Path]::GetFileName($path)
}
static [string]basename([string]$path,[bool]$extension=$True){
    if($extension){
        return  [System.IO.Path]::GetFileName($path)
    }
    else{
        return [System.IO.Path]::GetFileNameWithoutExtension($path)
    }
}

如图:

3. 获取盘符

static [string]rootname([string]$path){
    <# Return root directory information #>
    return [System.IO.Path]::GetPathRoot($path)
}

【例如】:

4. 当前系统临时目录

static [string]get_temp_path(){
    <# Returns the path of the current system temporary directory. #>
    return [System.IO.Path]::GetTempPath()
}

【例如】:

5. 上级路径

5.1 获取文件所在目录名(上级目录名)

static [string]get_dirname([string]$path){
    <#
    Returns the name of the folder where the file is located.
    Params
    ======
    - $path [string] Represents the absolute path of a file or folder.
    #>
    return [Path]::basename([System.IO.Path]::GetDirectoryName($path))
}
static [string]get_dirname([string]$path, [bool]$absolute=$True){
    if($absolute){
        return [System.IO.Path]::GetDirectoryName($path)
    }
    else{
        return [Path]::basename([System.IO.Path]::GetDirectoryName($path))
    }
}

【例如】:

备注:

这里图片调用的是之前的版本的方法名,现在已经改名为 get_dirname ,只要替换方法名效果一样,只是没有重新截图了。

5.2 获取文件所在目录名(上级绝对路径)

static [string]get_dirpath([string]$path){
    <#
    Returns the absolute path of the parent folder.
    Params
    ======
    - $path [string] Represents the absolute path of a file or folder.
    #>
    return [System.IO.Path]::GetDirectoryName($path)
}

6. 判断文件或者目录是否实际存在

static [bool] exists([string]$path){
    <#
    Determine whether the specified file or directory exists.
    Params
    ======
    - $path [string] The path value represented by a string.
    Returns
    =======
    - $True  exist.
    - $False non-existent.
    #>
    return Test-Path -Path $path
}

例如:

7. 获取相对路径

static [string]relpath([string]$relativeTo, [string]$path){
    <#
    Returns the relative path from one path to another.
    Params
    ======
    - $relativeTo [string] The source path relative to the result. This path is always treated as a directory.
    - $path [string] Target path.
    Returns
    =======
    [string] Relative path, or path if the paths do not share the same root.
    Exceptions
    ==========
    - [ArgumentNullException] The value of $relativeTo or $path is null。
    - [ArgumentException] $relativeTo or $path is actually null.
    #>
    return [System.IO.Path]::GetRelativePath($relativeTo, $path)
}

【例如】:

8. 获取目录的当前子项目

static [string[]] get_items([string]$path){
    <#
    Get all subprojects in the specified directory. 
    Params
    ======
    - $path [string] The path value represented by a string.
    - $sift [string] Optional, used to indicate the filtered content.
        * When the parameter value is' file', only the absolute path of 
        the files in it will be returned.
        * When the parameter value is' folder', the absolute path of the 
        directory (folder) in it is returned.
    Notes
    =====
        This method only gets the current level of subdirectories, while 
        the folders containing subdirectories will not be traversed.
        If you need to recursively obtain all descendants directories, 
        you should consider using `get_descendants()` method instead.
    #>
    $item_obj = Get-ChildItem $path |  Sort-Object
    $ary = [ArrayList]::new()
    foreach ($item in $item_obj){
        $ary.Add($item.ToString())
    }
    return $ary
}
static [string[]] get_items([string]$path, [string]$sift){
    if($sift -eq 'file'){
        $files = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $False} | Sort-Object;
        $ary = [ArrayList]::new()
        foreach ($item in $files){
            $ary.Add($item.ToString())
        }
        return $ary
    }elseif ($sift -eq 'folder') {
        $folders = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $True} | Sort-Object;
        $ary = [ArrayList]::new()
        foreach ($item in $folders){
            $ary.Add($item.ToString())
        }
        return $ary
    }else{
        $item_obj = Get-ChildItem $path |  Sort-Object
        $ary = [ArrayList]::new()
        foreach ($item in $item_obj){
            $ary.Add($item.ToString())
        }
        return $ary
    }
}

【例如】:

其中:

  • 由于该目录中没有直接子项目为文件,因此当指定第二个参数为file时,结果为空;
  • 指定第二个参数为folder和不指定第二个参数的效果完全一致。

9. 递归获取目录的所有子孙项目

static [string[]] get_descendants([string]$path){
    <#
    Get all items in the specified directory, and recursively traverse all descendant folders.
    Params
    ======
    - $path [string] The path value represented by a string.
    - $sift [string] Optional, used to indicate the filtered content.
        * When the parameter value is' file', only the absolute path of the files in it will be returned.
        * When the parameter value is' folder', the absolute path of the directory (folder) in it is returned.
    #>
    $ary = [ArrayList]::new();
    $item_obj = Get-ChildItem $path |  Sort-Object; # current directory
    foreach ($item in $item_obj){
        if([Path]::is_dirname($item)){
            $sub_ary = [Path]::get_descendants($item);
            $ary.AddRange($sub_ary);
        }
        else{
            $ary.Add($item);
        }
    }
    return $ary
}
static [string[]] get_descendants([string]$path, [string]$sift){
    $files = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $False} | Sort-Object;
    $folders = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $True} | Sort-Object;
    $ary = [ArrayList]::new()
    # only file
    if($sift -eq 'file'){
        if($null -ne $files){
            foreach ($file in $files){
                $ary.Add($file)
            }
        }
        foreach ($item in $folders){
            $ary.AddRange([Path]::get_descendants($item,'file'))
        }
    }
    # only dir
    elseif ($sift -eq 'folder') {
        if($null -ne $folders){
            foreach ($item in $folders){
                $ary.Add($item);
                $ary.AddRange([Path]::get_descendants($item,'folder'))
            }
        }
    }
    # all
    else{
        $item_obj = Get-ChildItem $path |  Sort-Object; # current directory
        foreach ($item in $item_obj){
            if([Path]::is_dirname($item)){
                $sub_ary = [Path]::get_descendants($item);
                $ary.AddRange($sub_ary);
            }
            else{
                $ary.Add($item);
            }
        }
    }
    return $ary
}

【例如】:

方法 get_descendants 与方法 get_items 的区别在于, get_descendants的查找范围不限于其自身,还包括其所有的子孙目录。

10. 在指定目录下筛选文件

static [string[]]filter_files([string]$path, [string]$sub_string){
    <#
    Filter the files containing the specified string from the specified directory.
    Params
    ======
    - $path [string] 
    - $sub_string [string] 
    - $recursion [bool] Recursively search all descendant directories, defaulf $False
    #>
    $ary = [ArrayList]::new();
    foreach ($item in [Path]::get_items($path,'file')) {
        if([Path]::basename($item).Contains($sub_string)){
            $ary.Add($item)
        }
    }
    return $ary
}
static [string[]]filter_files([string]$path, [string]$sub_string, [bool]$recursion){
    $ary = [ArrayList]::new();
    if($recursion){
        $all = [Path]::get_descendants($path,'file')
    }else{
        $all = [Path]::get_items($path,'file')
    }
    foreach ($item in $all) {
        if([Path]::basename($item).Contains($sub_string)){
            $ary.Add($item)
        }
    }
    return $ary
}

【例如】:

11. 在指定目录下筛选目录

static [string[]]filter_dirs([string]$path, [string]$sub_string){
    $ary = [ArrayList]::new();
    foreach ($item in [Path]::get_items($path,'folder')) {
        if([Path]::basename($item).Contains($sub_string)){
            $ary.Add($item)
        }
    }
    return $ary
}
static [string[]]filter_dirs([string]$path, [string]$sub_string, [bool]$recursion){
    $ary = [ArrayList]::new();
    if($recursion){
        $all = [Path]::get_descendants($path,'folder')
    }else{
        $all = [Path]::get_items($path,'folder')
    }
    foreach ($item in $all) {
        if([Path]::basename($item).Contains($sub_string)){
            $ary.Add($item)
        }
    }
    return $ary
}

【例如】:

12. 获取文件或者目录的修改时间

static [System.DateTime]get_modify_time([string]$path){
    <#
    Returns the last modification time of a file or directory.
    Params
    ======
    - $path [string] The path value represented by a string.
    #>
    return [System.IO.DirectoryInfo]::new($path).LastWriteTime
}

【例如】:

13. 判断指定路径是否实际是一个文件夹

static [bool]is_dirname([string]$path){
    <#
    Specifies whether the path represents a folder.
    Params
    ======
    - $path [string] The path value represented by a string.
    Returns
    =======
        - $True  If the specified path represents a folder
        - $False Versa
    Notes
    =====
        In most cases, you can also use the command: 
        `Test-Path -Path $path -PathType leaf `, 
        However, using the `Test-Path` command can't deal with 
        the case that the file name contains "[" as the powershell 
        compiler will throw back an error in this case.
    #>
    return [Path]::has_attributes($path,"Directory")
}

【例如】:

14. 判断指定路径是否实际是一个文件

static [bool]is_filename([string]$path){
    <#
    Returns whether the specified path value represents a file.
    Params
    ======
    - $path The path value represented by a string.
    Notes
    =====
        In most cases, you can also use the command: 
        `Test-Path -Path $path -PathType leaf `, 
        However, using the `Test-Path` command can't deal with 
        the case that the file name contains "[" as the powershell 
        compiler will throw back an error in this case.
    #>
    return -not [Path]::has_attributes($path,"Directory")
}

【例如】:

15. 判断文件是否比指定日期新

static [bool]is_newer_than($path, $time){
    <#
    Test whether the time of a file is before the specified date.
    Params
    ======
    - $path [string] The path value represented by a string.
    - $time A point-in-time string, such as "July 13, 2009"
    Returns
    =======
    - $True  If the modification time of the specified file is newer than this point in time;
    - $False Versa。
    #>
    return Test-Path -Path $path -NewerThan $time
}

该方法仅适用于文件系统驱动器。

【例如】:

16. 判断目录是否为空

static [bool]is_empty([string]$path){
    <#
    The folder is not empty, or the specified path is a file.
    Params
    ======
    - $path [string] The path value represented by a string.
    Retuens
    =======
    - $True  Folder is empty.
    - $False The folder is not empty, or the specified path is a file.
    #>
    if([Path]::is_dirname($path)){
        if((Get-ChildItem $path).count -eq 0){
            return $True
        }
        else{
            return $False
        }
    }
    else{
        write-host -ForegroundColor Yellow "Warning: The actual parameter of the variable `$path is a file name while a folder name is expected. "
        return $False
    }
}

【例如】:

17. 判断某个路径值是否为绝对路径

static [bool]is_abs([string]$path){
    <# 
    Determine whether the path value represents an absolute path.
    Params
    ======
    - $path [string] The path value represented by a string.
    Retuens
    =======
    - $True  Is an absolute path.
    - $False Versa.
    #>
    return Split-Path -Path $path -IsAbsolute
}

【例如】:

18. 获取目录的属性描述符

static [string[]]get_attributes([string]$path){
    <#
    Gets the operator of attribute description of the directory.
    #>
    return [System.IO.File]::GetAttributes($path).ToString().Split(", ")
}

【例如】:

【又如】:

19. 判断是否包含某个属性描述符

static [bool]has_attributes([string]$path, [string]$attributes){
    <#
    Returns whether the file or directory contains an attribute descriptor.
    Params
    ======
    - $path [string] The path value represented by a string.
    - $attributes [string] Represents an attribute descriptor of a directory. 
    Retuens
    =======
    - $True  Includes.
    - $False Not includes.
    #>
    return [Path]::get_attributes($path).Contains($attributes)
}

【其中】:

$attributes 的值可以是:

描述
Archive 此文件标记为包含在增量备份操作中。 每当修改文件时,Windows 会设置该属性,并且在增量备份期间处理文件时,备份软件应进行清理该属性。
Compressed 此文件是压缩文件。
Device 留待将来使用。
Directory 此文件是一个目录。 Directory 在 Windows、Linux 和 macOS 上受支持。
Encrypted 此文件或目录已加密。 对于文件来说,表示文件中的所有数据都是加密的。 对于目录来说,表示新创建的文件和目录在默认情况下是加密的。
Hidden 文件是隐藏的,因此没有包括在普通的目录列表中。 Hidden 在 Windows、Linux 和 macOS 上受支持。
IntegrityStream 文件或目录包括完整性支持数据。 在此值适用于文件时,文件中的所有数据流具有完整性支持。 此值将应用于一个目录时,所有新文件和子目录在该目录中和默认情况下应包括完整性支持。
Normal 该文件是没有特殊属性的标准文件。 仅当其单独使用时,此特性才有效。 Normal 在 Windows、Linux 和 macOS 上受支持。
NoScrubData 文件或目录从完整性扫描数据中排除。 此值将应用于一个目录时,所有新文件和子目录在该目录中和默认情况下应不包括数据完整性。
NotContentIndexed 将不会通过操作系统的内容索引服务来索引此文件。
Offline 此文件处于脱机状态, 文件数据不能立即供使用。
ReadOnly 文件为只读文件。 ReadOnly 在 Windows、Linux 和 macOS 上受支持。 在 Linux 和 macOS 上,更改 ReadOnly 标记是权限操作。
ReparsePoint 文件包含一个重新分析点,它是一个与文件或目录关联的用户定义的数据块。 ReparsePoint 在 Windows、Linux 和 macOS 上受支持。
SparseFile 此文件是稀疏文件。 稀疏文件一般是数据通常为零的大文件。
System 此文件是系统文件。 即,该文件是操作系统的一部分或者由操作系统以独占方式使用。
Temporary 文件是临时文件。 临时文件包含当执行应用程序时需要的,但当应用程序完成后不需要的数据。 文件系统尝试将所有数据保存在内存中,而不是将数据刷新回大容量存储,以便可以快速访问。 当临时文件不再需要时,应用程序应立即删除它。

【例如】:

可以知道,该文件是一个具有 Hidden的文件(隐藏文件)。

20. 计算文件或目录的大小

static [int64]$counter;
static [int64]get_size([string]$path){
    <#
    Returns the file size, or an error if the file does not exist.
    Params
    ======
    - $path [string] The path value represented by a string.
    #>
    [Path]::counter = -1;
    return [Path]::get_size($path,[Path]::counter)
}
static [int64]get_size([string]$path,[string]$ParentId){
    $count_size = 0;
    $file_infos = Get-ChildItem $path;
    # If it is a file, directly return the file size.
    if($file_infos.Attribute -eq 'Archive'){
        write-host $path+" is a file."
        $count_size = $count_size + $file_infos.Length;
    }
    # If it is a directory, the total size is calculated recursively.
    else{
        $count = $file_infos.Count;
        for ($i = 0; $i -lt $file_infos.Count; $i++) {
            $child = $file_infos[$i];
            [Path]::counter = [Path]::counter+1; # Each one is assigned an ID separately.
            $ID = [Path]::counter;
            # If it is a file, the size is accumulated.
            if([Path]::is_filename($child)){
                $count_size =  $count_size + $child.Length;
            }
            # If it is a directory, continue to recursively accumulate the size.
            else{
                $count_size =  $count_size + [Path]::get_size($child,$ID)
            }
            # 进度条显示
            $percent = $i / $count;  # 以子条目计算百分比
            if($ParentId -eq -1){
                Write-Progress -ID $ID -Activity ("Total counts "+$count.ToString()+"bytes of path: "+$child.ToString()) -Status "$percent% completed." -PercentComplete $percent;
            }else{
                Write-Progress -ID $ID -ParentId $ParentId -Activity ("Total counts "+$count.ToString()+"bytes of path: "+$child.ToString()) -Status "$percent% completed." -PercentComplete $percent;
            }
        }
    }
    return $count_size
}

【例如】:

21. 连结路径

static [string]join($path, $childpath){
    <# 
    Connect the directory and file name into a path.
    Params
    ======
    - $path [string] The path value represented by a string.
    - $childpath [string] childpath path value represented by a string.
    #>
    return Join-Path -Path $path -ChildPath $childpath
}

【例如】:

22. 拆分路径

static [string[]]split([string]$path){
    <#
    Divide the path into two parts: dirname and basename.
    Params
    ======
    - path [string] The path value represented by a string.
    Returns
    =======
    - $dirname   The absolute path of the folder.
    - $basename  Subfile or subdirectory name
    #>
    $dirname = Split-Path -Path $path -Leaf;
    $basename = Split-Path -Path $path;
    return $dirname,$basename
}

【例如】:

23. 创建目录

static [void]make($path){
    <#
    Create a series of folders according to the given path.
    Params
    ======
    - path [string] The path value represented by a string.
    #>
    New-Item -Path ([Path]::dirname($path, $True)) -Name ([Path]::basename($path)) -ItemType "directory" 
}

【例如】:

其中

  • 如果目录完全存在,则会提示错误 "An item with the specified name XXX already exists",例如两次重复创建:
  • 如果所创建的目录的祖先文件夹都不存在,则会逐个创建祖先文件夹。

24. Path 环境变量相关方法

static [string[]]get_enviroment(){
    return [Environment]::GetEnvironmentVariable('Path', 'Machine')
}
static [void]set_enviroment($path){
    [Environment]::SetEnvironmentVariable('Path', $path,'Machine')
}
static [void]set_enviroment($path,$env_var_target){
    if($env_var_target -eq 'Machine'){
        [Environment]::SetEnvironmentVariable('Path', $path,'Machine')
    }
    elseif($env_var_target -eq 'User'){
        [Environment]::SetEnvironmentVariable('Path', $path,'User')
    }
    else{
        write-host -ForegroundColor Red "ValueError: The value of variable  `"`$env_var_target`" can only be one of 'Machine' or 'User'." 
    }   
}

【例如】:


         

25. 删除路径对应的项目

static [void] delete([string]$path){
    <#
    Delete the file or directory corresponding to the specified path.
    Params
    ======
    - path [string] The path value represented by a string.
    #>
    Remove-Item $path;
}

【例如】:


         

附录: Path类代码

<#
@Auth: Jack Lee;
@Email: 291148484@163.com;
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#>
using namespace System;
using namespace System.Collections;
using namespace System.Collections.Generic;
class Path{
    static [string]abspath([string]$path){
        <#
        Return absolute path
        Params
        ======
        - $path [string] Path of file.
        #>
        return Resolve-Path -Path $path; 
    }
    static [string]basename([string]$path){
        <#
        Returns the file name from the absolute path value represented by a string.
        Params
        ======
        - $path [string] The absolute path of the file.
        - $extension [bool] Whether to remove the extension.
        #>
        return  [System.IO.Path]::GetFileName($path)
    }
    static [string]basename([string]$path,[bool]$extension=$True){
        if($extension){
            return  [System.IO.Path]::GetFileName($path)
        }
        else{
            return [System.IO.Path]::GetFileNameWithoutExtension($path)
        }
    }
    static [string]rootname([string]$path){
        <# Return root directory information #>
        return [System.IO.Path]::GetPathRoot($path)
    }
    static [string]get_temp_path(){
        <# Returns the path of the current system temporary directory. #>
        return [System.IO.Path]::GetTempPath()
    }
    static [string]get_dirpath([string]$path){
        <#
        Returns the absolute path of the parent folder.
        Params
        ======
        - $path [string] Represents the absolute path of a file.
        #>
      return [System.IO.Path]::GetDirectoryName($path)
  }
    static [string]get_dirname([string]$path){
        <#
        Returns the name of the folder where the file or subfolder is located.
        Params
        ======
        - $path [string] Represents the absolute path of a file.
        #>
        return [Path]::basename([System.IO.Path]::GetDirectoryName($path))
    }
    static [string]get_dirname([string]$path, [bool]$absolute=$True){
        if($absolute){
            return [System.IO.Path]::GetDirectoryName($path)
        }
        else{
            return [Path]::basename([System.IO.Path]::GetDirectoryName($path))
        }
    }
    static [bool] exists([string]$path){
        <#
        Determine whether the specified file or directory exists.
        Params
        ======
        - $path [string] The path value represented by a string.
        Returns
        =======
        - $True  exist.
        - $False non-existent.
        #>
        return Test-Path -Path $path
    }
    static [string]relpath([string]$relativeTo, [string]$path){
        <#
        Returns the relative path from one path to another.
        Params
        ======
        - $relativeTo [string] The source path relative to the result. This path is always treated as a directory.
        - $path [string] Target path.
        Returns
        =======
        [string] Relative path, or path if the paths do not share the same root.
        Exceptions
        ==========
        - [ArgumentNullException] The value of $relativeTo or $path is null。
        - [ArgumentException] $relativeTo or $path is actually null.
        #>
        return [System.IO.Path]::GetRelativePath($relativeTo, $path)
    }
    static [string[]] get_items([string]$path){
        <#
        Get all subprojects in the specified directory. 
        Params
        ======
        - $path [string] The path value represented by a string.
        - $sift [string] Optional, used to indicate the filtered content.
          * When the parameter value is' file', only the absolute path of 
            the files in it will be returned.
          * When the parameter value is' folder', the absolute path of the 
            directory (folder) in it is returned.
        Notes
        =====
          This method only gets the current level of subdirectories, while 
          the folders containing subdirectories will not be traversed.
          If you need to recursively obtain all descendants directories, 
          you should consider using `get_descendants()` method instead.
        #>
        $item_obj = Get-ChildItem $path |  Sort-Object
        $ary = [ArrayList]::new()
        foreach ($item in $item_obj){
            $ary.Add($item.ToString())
        }
        return $ary
    }
    static [string[]] get_items([string]$path, [string]$sift){
        if($sift -eq 'file'){
            $files = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $False} | Sort-Object;
            $ary = [ArrayList]::new()
            foreach ($item in $files){
                $ary.Add($item.ToString())
            }
            return $ary
        }elseif ($sift -eq 'folder') {
            $folders = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $True} | Sort-Object;
            $ary = [ArrayList]::new()
            foreach ($item in $folders){
                $ary.Add($item.ToString())
            }
            return $ary
        }else{
            $item_obj = Get-ChildItem $path |  Sort-Object
            $ary = [ArrayList]::new()
            foreach ($item in $item_obj){
                $ary.Add($item.ToString())
            }
            return $ary
        }
    }
    static [string[]] get_descendants([string]$path){
        <#
        Get all items in the specified directory, and recursively traverse all descendant folders.
        Params
        ======
        - $path [string] The path value represented by a string.
        - $sift [string] Optional, used to indicate the filtered content.
          * When the parameter value is' file', only the absolute path of the files in it will be returned.
          * When the parameter value is' folder', the absolute path of the directory (folder) in it is returned.
        #>
        $ary = [ArrayList]::new();
        $item_obj = Get-ChildItem $path |  Sort-Object; # current directory
        foreach ($item in $item_obj){
            if([Path]::is_dirname($item)){
                $sub_ary = [Path]::get_descendants($item);
                $ary.AddRange($sub_ary);
            }
            else{
                $ary.Add($item);
            }
        }
        return $ary
    }
    static [string[]] get_descendants([string]$path, [string]$sift){
        $files = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $False} | Sort-Object;
        $folders = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $True} | Sort-Object;
        $ary = [ArrayList]::new()
        # only file
        if($sift -eq 'file'){
            if($null -ne $files){
                foreach ($file in $files){
                    $ary.Add($file)
                }
            }
            foreach ($item in $folders){
                $ary.AddRange([Path]::get_descendants($item,'file'))
            }
        }
        # only dir
        elseif ($sift -eq 'folder') {
            if($null -ne $folders){
                foreach ($item in $folders){
                    $ary.Add($item);
                    $ary.AddRange([Path]::get_descendants($item,'folder'))
                }
            }
        }
        # all
        else{
            $item_obj = Get-ChildItem $path |  Sort-Object; # current directory
            foreach ($item in $item_obj){
                if([Path]::is_dirname($item)){
                    $sub_ary = [Path]::get_descendants($item);
                    $ary.AddRange($sub_ary);
                }
                else{
                    $ary.Add($item);
                }
            }
        }
        return $ary
    }
    static [string[]]filter_files([string]$path, [string]$sub_string){
        <#
        Filter the files containing the specified string from the specified directory.
        Params
        ======
        - $path [string] 
        - $sub_string [string] 
        - $recursion [bool] Recursively search all descendant directories, defaulf $False
        #>
        $ary = [ArrayList]::new();
        foreach ($item in [Path]::get_items($path,'file')) {
            if([Path]::basename($item).Contains($sub_string)){
                $ary.Add($item)
            }
        }
        return $ary
    }
    static [string[]]filter_files([string]$path, [string]$sub_string, [bool]$recursion){
        $ary = [ArrayList]::new();
        if($recursion){
            $all = [Path]::get_descendants($path,'file')
        }else{
            $all = [Path]::get_items($path,'file')
        }
        foreach ($item in $all) {
            if([Path]::basename($item).Contains($sub_string)){
                $ary.Add($item)
            }
        }
        return $ary
    }
    static [string[]]filter_dirs([string]$path, [string]$sub_string){
        $ary = [ArrayList]::new();
        foreach ($item in [Path]::get_items($path,'folder')) {
            if([Path]::basename($item).Contains($sub_string)){
                $ary.Add($item)
            }
        }
        return $ary
    }
    static [string[]]filter_dirs([string]$path, [string]$sub_string, [bool]$recursion){
        $ary = [ArrayList]::new();
        if($recursion){
            $all = [Path]::get_descendants($path,'folder')
        }else{
            $all = [Path]::get_items($path,'folder')
        }
        foreach ($item in $all) {
            if([Path]::basename($item).Contains($sub_string)){
                $ary.Add($item)
            }
        }
        return $ary
    }
    static [System.DateTime]get_modify_time([string]$path){
        <#
        Returns the last modification time of a file or directory.
        Params
        ======
        - $path [string] The path value represented by a string.
        #>
        return [System.IO.DirectoryInfo]::new($path).LastWriteTime
    }
    static [bool]is_dirname([string]$path){
        <#
        Specifies whether the path represents a folder.
        Params
        ======
        - $path [string] The path value represented by a string.
        Returns
        =======
         - $True  If the specified path represents a folder
         - $False Versa
        Notes
        =====
          In most cases, you can also use the command: 
          `Test-Path -Path $path -PathType leaf `, 
          However, using the `Test-Path` command can't deal with 
          the case that the file name contains "[" as the powershell 
          compiler will throw back an error in this case.
        #>
        return [Path]::has_attributes($path,"Directory")
    }
    static [bool]is_filename([string]$path){
        <#
        Returns whether the specified path value represents a file.
        Params
        ======
        - $path The path value represented by a string.
        Notes
        =====
          In most cases, you can also use the command: 
          `Test-Path -Path $path -PathType leaf `, 
          However, using the `Test-Path` command can't deal with 
          the case that the file name contains "[" as the powershell 
          compiler will throw back an error in this case.
        #>
        return -not [Path]::has_attributes($path,"Directory")
    }
    static [bool]is_newer_than($path, $time){
        <#
        Test whether the time of a file is before the specified date.
        Params
        ======
        - $path [string] The path value represented by a string.
        - $time A point-in-time string, such as "July 13, 2009"
        Returns
        =======
        - $True  If the modification time of the specified file is newer than this point in time;
        - $False Versa。
        #>
        return Test-Path -Path $path -NewerThan $time
    }
    static [bool]is_empty([string]$path){
        <#
        The folder is not empty, or the specified path is a file.
        Params
        ======
        - $path [string] The path value represented by a string.
        Retuens
        =======
        - $True  Folder is empty.
        - $False The folder is not empty, or the specified path is a file.
        #>
        if([Path]::is_dirname($path)){
            if((Get-ChildItem $path).count -eq 0){
                return $True
            }
            else{
                return $False
            }
        }
        else{
            write-host -ForegroundColor Yellow "Warning: The actual parameter of the variable `$path is a file name while a folder name is expected. "
            return $False
        }
    }
    static [bool]is_abs([string]$path){
        <# 
        Determine whether the path value represents an absolute path.
        Params
        ======
        - $path [string] The path value represented by a string.
        Retuens
        =======
        - $True  Is an absolute path.
        - $False Versa.
        #>
        return Split-Path -Path $path -IsAbsolute
    }
    static [string[]]get_attributes([string]$path){
        <#
        Gets the operator of attribute description of the directory.
        #>
        return [System.IO.File]::GetAttributes($path).ToString().Split(", ")
    }
    static [bool]has_attributes([string]$path, [string]$attributes){
        <#
        Returns whether the file or directory contains an attribute descriptor.
        Params
        ======
        - $path [string] The path value represented by a string.
        - $attributes [string] Represents an attribute descriptor of a directory. The value of $attributes could be:
            * Archive 此文件标记为包含在增量备份操作中。 每当修改文件时,Windows 会设置该属性,并且在增量备份期间处理文件时,备份软件应进行清理该属性。
            * Compressed 此文件是压缩文件。
            * Device 留待将来使用。
            * Directory 此文件是一个目录。 Directory 在 Windows、Linux 和 macOS 上受支持。
            * Encrypted 此文件或目录已加密。 对于文件来说,表示文件中的所有数据都是加密的。 对于目录来说,表示新创建的文件和目录在默认情况下是加密的。
            * Hidden 文件是隐藏的,因此没有包括在普通的目录列表中。 Hidden 在 Windows、Linux 和 macOS 上受支持。
            * IntegrityStream 文件或目录包括完整性支持数据。 在此值适用于文件时,文件中的所有数据流具有完整性支持。 此值将应用于一个目录时,所有新文件和子目录在该目录中和默认情况下应包括完整性支持。
            * Normal 该文件是没有特殊属性的标准文件。 仅当其单独使用时,此特性才有效。 Normal 在 Windows、Linux 和 macOS 上受支持。
            * NoScrubData 文件或目录从完整性扫描数据中排除。 此值将应用于一个目录时,所有新文件和子目录在该目录中和默认情况下应不包括数据完整性。
            * NotContentIndexed 将不会通过操作系统的内容索引服务来索引此文件。
            * Offline 此文件处于脱机状态, 文件数据不能立即供使用。
            * ReadOnly 文件为只读文件。 ReadOnly 在 Windows、Linux 和 macOS 上受支持。 在 Linux 和 macOS 上,更改 ReadOnly 标记是权限操作。
            * ReparsePoint 文件包含一个重新分析点,它是一个与文件或目录关联的用户定义的数据块。 ReparsePoint 在 Windows、Linux 和 macOS 上受支持。
            * SparseFile 此文件是稀疏文件。 稀疏文件一般是数据通常为零的大文件。
            * System 此文件是系统文件。 即,该文件是操作系统的一部分或者由操作系统以独占方式使用。
            * Temporary 文件是临时文件。 临时文件包含当执行应用程序时需要的,但当应用程序完成后不需要的数据。 文件系统尝试将所有数据保存在内存中,而不是将数据刷新回大容量存储,以便可以快速访问。 当临时文件不再需要时,应用程序应立即删除它。
        Retuens
        =======
        - $True  Includes.
        - $False Not includes.
        #>
        return [Path]::get_attributes($path).Contains($attributes)
    }
    static [int64]$counter;
    static [int64]get_size([string]$path){
        <#
        Returns the file size, or an error if the file does not exist.
        Params
        ======
        - $path [string] The path value represented by a string.
        #>
        [Path]::counter = -1;
        return [Path]::get_size($path,[Path]::counter)
    }
    static [int64]get_size([string]$path,[string]$ParentId){
        $count_size = 0;
        $file_infos = Get-ChildItem $path;
        # If it is a file, directly return the file size.
        if($file_infos.Attribute -eq 'Archive'){
            write-host $path+" is a file."
            $count_size = $count_size + $file_infos.Length;
        }
        # If it is a directory, the total size is calculated recursively.
        else{
            $count = $file_infos.Count;
            for ($i = 0; $i -lt $file_infos.Count; $i++) {
                $child = $file_infos[$i];
                [Path]::counter = [Path]::counter+1; # Each one is assigned an ID separately.
                $ID = [Path]::counter;
                # If it is a file, the size is accumulated.
                if([Path]::is_filename($child)){
                    $count_size =  $count_size + $child.Length;
                }
                # If it is a directory, continue to recursively accumulate the size.
                else{
                    $count_size =  $count_size + [Path]::get_size($child,$ID)
                }
                # Progress bar display
                $percent = $i / $count;  # Calculate the percentage by subentry.
                if($ParentId -eq -1){
                    Write-Progress -ID $ID -Activity ("Total counts "+$count.ToString()+"bytes of path: "+$child.ToString()) -Status "$percent% completed." -PercentComplete $percent;
                }else{
                    Write-Progress -ID $ID -ParentId $ParentId -Activity ("Total counts "+$count.ToString()+"bytes of path: "+$child.ToString()) -Status "$percent% completed." -PercentComplete $percent;
                }
            }
        }
        return $count_size
    }
    static [string]join($path, $childpath){
        <# 
        Connect the directory and file name into a path.
        Params
        ======
        - $path [string] The path value represented by a string.
        - $childpath [string] childpath path value represented by a string.
        #>
        return Join-Path -Path $path -ChildPath $childpath
    }
    static [string[]]split([string]$path){
        <#
        Divide the path into two parts: dirname and basename.
        Params
        ======
        - path [string] The path value represented by a string.
        Returns
        =======
        - $dirname   The absolute path of the folder.
        - $basename  Subfile or subdirectory name
        #>
        $dirname = Split-Path -Path $path -Leaf;
        $basename = Split-Path -Path $path;
        return $dirname,$basename
    }
    static [string[]]get_enviroment(){
        return [Environment]::GetEnvironmentVariable('Path', 'Machine')
    }
    static [void]set_enviroment($path){
        [Environment]::SetEnvironmentVariable('Path', $path,'Machine')
    }
    static [void]set_enviroment($path,$env_var_target){
        if($env_var_target -eq 'Machine'){
            [Environment]::SetEnvironmentVariable('Path', $path,'Machine')
        }
        elseif($env_var_target -eq 'User'){
            [Environment]::SetEnvironmentVariable('Path', $path,'User')
        }
        else{
            write-host -ForegroundColor Red "ValueError: The value of variable  `"`$env_var_target`" can only be one of 'Machine' or 'User'." 
        }   
    }
    static [void]delete([string]$path){
        <#
        Delete the file or directory corresponding to the specified path.
        Params
        ======
        - path [string] The path value represented by a string.
        #>
        Remove-Item $path;
    }
    static [void]make($path){
        <#
        Create a series of folders according to the given path.
        Params
        ======
        - path [string] The path value represented by a string.
        #>
        New-Item -Path ([Path]::dirname($path, $True)) -Name ([Path]::basename($path)) -ItemType "directory" 
    }
}

附录2: 脚本位置

方式一: Get-Location

你可以使用如下方式获取脚本所在目录的位置:

(Get-Location).Path

当你使用一个bat来调用一个包含这种方式作为BASE_DIR来使用时往往是正确的,但是如果你将这个样的bat添加到Windwos任务计划中,BASE_DIR将成为cmd.exe所在文件夹。

方式二: 使用$MyInvocation

你可以通过以下方式在ps1脚本中表示自己的脚本所在位置:

$MyInvocation.MyCommand.source

因此脚本所在文件夹的绝对路径所在位置可以表示为:

using module .\utils\jcpath.psm1
[Path]::get_dirpath($MyInvocation.MyCommand.source)
目录
相关文章
|
3月前
|
运维 监控 网络协议
【运维干货】一次因 VPN 协议不一致导致的 CPE 速率异常案例
本文分享了一次企业 CPE 主备切换后速率异常的排障案例,重点分析了因主备设备 VPN 协议配置不一致(TCP vs UDP)导致的速率问题,并总结了配置一致性检查、临时改动闭环及协议选择等方面的运维经验。
|
3月前
|
机器学习/深度学习 人工智能 运维
运维告警别乱飞了!AI智能报警案例解析
运维告警别乱飞了!AI智能报警案例解析
433 0
|
6月前
|
人工智能 运维 关系型数据库
数据库运维:mysql 数据库迁移方法-mysqldump
本文介绍了MySQL数据库迁移的方法与技巧,重点探讨了数据量大小对迁移方式的影响。对于10GB以下的小型数据库,推荐使用mysqldump进行逻辑导出和source导入;10GB以上可考虑mydumper与myloader工具;100GB以上则建议物理迁移。文中还提供了统计数据库及表空间大小的SQL语句,并讲解了如何使用mysqldump导出存储过程、函数和数据结构。通过结合实际应用场景选择合适的工具与方法,可实现高效的数据迁移。
1061 1
|
8月前
|
人工智能 运维 监控
阿里云携手神州灵云打造云内网络性能监测标杆 斩获中国信通院高质量数字化转型十大案例——金保信“云内网络可观测”方案树立云原生运维新范式
2025年,金保信社保卡有限公司联合阿里云与神州灵云申报的《云内网络性能可观测解决方案》入选高质量数字化转型典型案例。该方案基于阿里云飞天企业版,融合云原生引流技术和流量“染色”专利,解决云内运维难题,实现主动预警和精准观测,将故障排查时间从数小时缩短至15分钟,助力企业降本增效,形成可跨行业复制的数字化转型方法论。
421 6
|
10月前
|
运维 应用服务中间件 nginx
docker运维查看指定应用log文件位置和名称
通过本文的方法,您可以更高效地管理和查看Docker容器中的日志文件,确保应用运行状态可控和可监测。
1308 28
|
11月前
|
存储 弹性计算 运维
云端问道 7 期实践教学-使用操作系统智能助手 OS Copilot 轻松运维与编程
使用操作系统智能助手 OS Copilot 轻松运维与编程
229 14
|
运维
【运维基础知识】用dos批处理批量替换文件中的某个字符串(本地单元测试通过,部分功能有待优化,欢迎指正)
该脚本用于将C盘test目录下所有以t开头的txt文件中的字符串“123”批量替换为“abc”。通过创建批处理文件并运行,可实现自动化文本替换,适合初学者学习批处理脚本的基础操作与逻辑控制。
897 56
|
11月前
|
弹性计算 人工智能 运维
新手训练营——使用操作系统智能助手OS Copilot轻松运维与编程
本文摘自阿里云操作系统团队的林演(林生)关于操作系统智能助手创新产品的分享,围绕“OS Copilot的高效运维与编程”展开,主要包括以下几方面的内容: 1. 行业痛点击及背景 2. 产品与架构 3. 典型应用场景 4. 实验及反馈渠道
274 1
|
11月前
|
人工智能 弹性计算 运维
云端问道7期方案教学-使用操作系统智能助手OS Copilot轻松运维与编程
本文介绍了阿里云基础软件团队推出的操作系统智能助手 OS Copilot,旨在解决 Linux 开发与运维中的痛点。OS Copilot 基于大模型和操作系统领域知识构建,支持自然语言问答、命令辅助执行、系统运维优化及代码生成等功能,极大降低了学习成本和工作量。文章详细阐述了其产品架构、典型应用场景以及实验反馈渠道,帮助用户更高效地进行系统管理和编程。目前该产品处于公测阶段,免费提供给阿里云 ECS 实例和 Alinux 3 系统用户使用。
180 1
|
存储 JSON JavaScript

热门文章

最新文章